Distance euclidienne retourne des résultats étranges
-
11-12-2019 - |
Question
Je suis en train d'écrire un programme pour comparer deux images les unes contre les autres sur la base de la couleur et de la messagerie instantanée en fonction de la couleur et de la messagerie instantanée en fonction de la couleur et de la messagerie instantanée à l'aide de l'algorithme de distance euclidiene, cependant, lorsque je l'exécute et que je passe dans deux images, je reçois une distance puis que je passe dans les mêmes images mais l'autreEntrez, je reçois un ensemble de résultats complètement différent.
est-ce normal ou si les réponses sont-elles les mêmes?
La déclaration que j'utilise pour calculer la distance euclidienne est la suivante:
distance = (int) Math.sqrt( (rgb1.getR()-rgb2.getR())^2
+ (rgb1.getG()-rgb2.getG())^2
+ (rgb1.getB()-rgb2.getB())^2
);
La solution
Looking at the code you posted, it looks your RGB values are ints. However, the ^
operator is not the power operator, but XOR (exclusive-OR) - a bitwise operation. So in order to calculate the squares correctly, use regular multiplication - e.g., use a temporary variable int deltaR = rgb1.getR()-rgb2.getR();
and then in the formula write deltaR*deltaR
instead of the ^
operator. Your RGB values will probably be in 0 to 255 range, so there shouldn't be overflow issues. Alternatively, you could use Math.pow(rgb1.getR()-rgb2.getR(),2)
etc. in the formula.
Autres conseils
For squaring a number in Java, use Math.pow(x, 2)
or even simpler, x * x
. The expression x ^ 2
does not square x
, instead it XORs x
with 2
.
In your code:
int diffR = rgb1.getR() - rgb2.getR();
int diffG = rgb1.getG() - rgb2.getG();
int diffB = rgb1.getB() - rgb2.getB();
int distance = (int) Math.sqrt(diffR*diffR + diffG*diffG + diffB*diffB);
... Although I'm not quite sure of your algorithm, but that's a different issue.
As people have said, you can use Math.pow(x, 2)
for squaring. Just from personal experience, if you're going to call this function a lot it might be better to write out the multiplication yourself, i.e. Math.sqrt((deltaX * deltaX) + (deltaY * deltaY) + (deltaZ * deltaZ));
It may seem uglier but if you profile both forms of the code you'll see that the calls to Math.pow
are much slower than the simple multiplications. Obviously there's nothing to do about the Math.sqrt
call though.