Евклидово расстояние дает странные результаты

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

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

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

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

person Roy James Schumacher    schedule 10.03.2012    source источник
comment
Евклидово расстояние (или, если на то пошло, любая функция расстояния) должно быть симметричным, поэтому ваши результаты действительно кажутся странными. Однако вам нужно опубликовать более подробную информацию, чтобы кто-нибудь мог помочь. Какой код вы используете для расчета расстояния?   -  person Michał Kosmulski    schedule 11.03.2012
comment
вам нужен весь код или только код евклидова расстояния?   -  person Roy James Schumacher    schedule 11.03.2012
comment
Начнем с кода расстояния - посмотрим, хватит ли его для решения вопроса.   -  person Michał Kosmulski    schedule 11.03.2012
comment
distance = (int) Math.sqrt ((rgb1.getR () - rgb2.getR ()) ^ 2 + (rgb1.getG () - rgb2.getG ()) ^ 2 + (rgb1.getB () - rgb2. getB ()) ^ 2);   -  person Roy James Schumacher    schedule 11.03.2012


Ответы (3)


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

person Michał Kosmulski    schedule 10.03.2012
comment
Большое спасибо, проблема была решена, и теперь она работает должным образом. - person Roy James Schumacher; 11.03.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);

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

person Óscar López    schedule 10.03.2012

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

person smessing    schedule 10.03.2012