Евклидово расстояние, возвращающее странные результаты - PullRequest
3 голосов
/ 11 марта 2012

я пишу программу для сравнения двух изображений друг с другом по цвету и им, используя алгоритм евклидова расстояния, однако, когда я запускаю его и передаю два изображения, я получаю одно расстояние и затем, когда я передаю те же изображения, но другоенаоборот, я получаю совершенно другой набор результатов.

это нормально или ответы должны быть одинаковыми?

Утверждение, которое я использую для вычисления евклидова расстояния:

distance = (int) Math.sqrt(   (rgb1.getR()-rgb2.getR())^2
                            + (rgb1.getG()-rgb2.getG())^2
                            + (rgb1.getB()-rgb2.getB())^2
                          );

Ответы [ 3 ]

7 голосов
/ 11 марта 2012

Глядя на код, который вы разместили, выглядит, что ваши значения RGB являются целыми.Однако оператор ^ не является оператором мощности, а XOR (исключающее-ИЛИ) - побитовая операция.Поэтому, чтобы правильно рассчитать квадраты, используйте регулярное умножение - например, используйте временную переменную int deltaR = rgb1.getR()-rgb2.getR();, а затем в формуле напишите deltaR*deltaR вместо оператора ^.Ваши значения RGB, вероятно, будут в диапазоне от 0 до 255, поэтому не должно быть проблем переполнения.В качестве альтернативы, вы можете использовать Math.pow(rgb1.getR()-rgb2.getR(),2) и т. Д. В формуле.

2 голосов
/ 11 марта 2012

Для возведения в квадрат числа в Java используйте Math.pow(x, 2) или, что еще проще, x * x.Выражение x ^ 2 не является квадратным x, вместо этого оно XOR x с 2.

В вашем коде:

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);

..Хотя я не совсем уверен в вашем алгоритме, но это другая проблема.

0 голосов
/ 11 марта 2012

Как уже говорили, вы можете использовать Math.pow(x, 2) для возведения в квадрат. Исходя из личного опыта, если вы собираетесь многократно вызывать эту функцию, может быть лучше написать умножение самостоятельно, то есть Math.sqrt((deltaX * deltaX) + (deltaY * deltaY) + (deltaZ * deltaZ)); Это может показаться уродливым, но если вы профилируете обе формы кода, вы увидите, что вызовы Math.pow намного медленнее, чем простые умножения. Очевидно, что с вызовом Math.sqrt ничего не поделаешь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...