2012-03-10 2 views
3

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

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

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

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

Евклидово расстояние (или, если на то пошло, любая функция расстояния), должно быть симметричным, так что действительно ваши результаты кажутся странными. Однако вам нужно отправить более подробную информацию для любого, кто сможет помочь. Какой код вы используете для расчета расстояния? –

+0

Вам нужен весь код или просто код эвклидовой дистанции? –

+0

Начнем с кода расстояния - мы увидим, достаточно ли для решения проблемы. –

ответ

7

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

+0

спасибо, много, это решило проблему, и она работает как ожидалось сейчас –

2

Для квадратизации числа на Java используйте Math.pow(x, 2) или даже проще, x * x. Выражение x^2 не квадратное x, вместо этого оно XORsx с 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

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