OpenCV, С++: расстояние между двумя точками

Для группового проекта мы пытаемся создать игру, где функции выполняются всякий раз, когда игрок формирует набор конкретных жестов руки перед камерой. Для обработки изображений мы используем Open-CV 2.3.

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

Мы хотим знать, есть ли какая-либо встроенная функция в Open-CV или стандартной библиотеке для С++, которая может обрабатывать низкоуровневые вычисления расстояния между двумя точками. У нас есть координаты для точек, которые находятся в пиксельных значениях (конечно).

Дополнительная информация: Предыдущий опыт научил нас тому, что OpenCV и другие библиотеки сильно оптимизированы. В качестве примера мы попытались изменить значения RGB канала изображения в реальном времени с камеры с помощью цикла for, проходящего через каждый пиксель. Это обеспечивает низкую частоту кадров. Вместо этого вместо этого мы решили использовать функцию сборки Open-CV, которая вместо этого предоставила нам высокую производительность с частотой кадров.

Ответ 1

Как вы правильно указали, есть функция OpenCV, которая выполняет некоторые из ваших работ:)

(Также проверьте другим способом)

Он называется величина(), и он вычисляет расстояние для вас. И если у вас есть вектор из более чем 4 векторов для вычисления расстояний, он будет использовать SSE (я думаю), чтобы сделать его быстрее.

Теперь проблема заключается в том, что он вычисляет только квадрат полномочий, и вам приходится делать это вручную. (проверьте документацию). Но если вы делаете их также с использованием функций OpenCV, это должно быть быстрым.

Mat pts1(nPts, 1, CV_8UC2), pts2(nPts, 1, CV_8UC2);
// populate them
Mat diffPts = pts1-pts2;
Mat ptsx, ptsy;
// split your points in x and y vectors. maybe separate them from start
Mat dist;
magnitude(ptsx, ptsy, dist); // voila!

Другой способ - использовать очень быстрый sqrt:

// 15 times faster than the classical float sqrt. 
// Reasonably accurate up to root(32500)
// Source: http://supp.iar.com/FilesPublic/SUPPORT/000419/AN-G-002.pdf

unsigned int root(unsigned int x){
    unsigned int a,b;
    b     = x;
    a = x = 0x3f;
    x     = b/x;
    a = x = (x+a)>>1;
    x     = b/x;
    a = x = (x+a)>>1;
    x     = b/x;
    x     = (x+a)>>1;
    return(x);  
}

Ответ 2

Вы должны попробовать это

cv::Point a(1, 3);
cv::Point b(5, 6);
double res = cv::norm(a-b);//Euclidian distance

Ответ 3

Это должно быть комментарий, но у меня недостаточно rep (50?) | - (поэтому я отправляю его как ответ.

То, что ребята пытаются рассказать вам в комментариях к вашим вопросам, состоит в том, что если это только около сравнения расстояний, то вы можете просто использовать d = (dx * dx + dy * dy) = (x1-x2) (x1-x2) + (y1-y2) (y1-y2) избегая при этом квадратного корня. Но вы не можете, конечно, пропустить квадратную высоту.

Ответ 4

Pythagoras - самый быстрый способ, и это действительно не так дорого, как вы думаете. Раньше это было из-за квадратного корня. Но современные процессоры обычно могут делать это за несколько циклов.

Если вам действительно нужна скорость, используйте OpenCL на графической карте для обработки изображений.