Направление и сила смещения изображения с помощью OpenCV / OpenCV / Recog.ru - Распознавание образов для программистов


Направление и сила смещения изображения с помощью OpenCV

Когда камера движется на каком-либо объекте, то важно определить направление движения. В этом случае можно использовать следующую функцию в OpenCV.

phaseCorrelate
Функция используется для определения сдвигов между двумя изображениями (массивами). Теорию по данному вопросу можно взять здесь http://en.wikipedia.org/wiki/Phase_correlation. C++ синтаксис:
Point2d phaseCorrelate(
InputArray src1, 
InputArray src2, 
InputArray window=noArray(), 
double* response=0
)

Параметры:
src1 – первое изображение формата CV_32FC1 или CV_64FC1;
src2 – второе изображение формата CV_32FC1 или CV_64FC1;
window – окно изображения, в котором проводится анализ, для уменьшения краевых эффектов;
response — мощность сигнала в пределах 5x5 пика в интервале между 0 и 1 (опционально).
Функция возвращает обнаруженный фазовый сдвиг между двумя массивами. Направление сдвига будет определяться положением возвращаемой точки относительно центра изображения.
Эта функция выполняет следующие уравнения:
1. Сначала выполняет окно Хана (http://en.wikipedia.org/wiki/Hann_function) для каждого изображения, чтобы устранить последствия краев.
2. Вычисляется дискретное преобразование Фурье для входных массивов.

3. Вычисляется поперечный спектр мощности каждого массива в частотной области.

4. Обратное преобразование Фурье.

5. Вычисляется расположение пика и вычисляет 5x5 взвешенную тяжесть вокруг пика.

6. Если результат не равен нулю, то response вычисляется как сумма элементов вокруг пика. Это нормированная величина (максимум 1).

Пример (из samples в OpenCV):
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"

using namespace cv;

int main(int, char* [])
{
    // Создание видеопотока с камеры
    VideoCapture video(0);
    Mat frame, curr, prev, curr64f, prev64f, hann;
    int key = 0;

    do
    {
        video >> frame; // Очередной фрейм
        cvtColor(frame, curr, CV_RGB2GRAY); // Перевод в градации серого

        if(prev.empty())
        {
            prev = curr.clone(); // клонирование изображения
            createHanningWindow(hann, curr.size(), CV_64F); // Создание окна Ханна
        }

        prev.convertTo(prev64f, CV_64F); 
        curr.convertTo(curr64f, CV_64F);

        Point2d shift = phaseCorrelate(prev64f, curr64f, hann); // Фазовая корреляция
        double radius = cv::sqrt(shift.x*shift.x + shift.y*shift.y); // Вычисление радиуса отклонения

        if(radius > 5)
        {
            // вывод на экран окружности и направления смещения
            Point center(curr.cols >> 1, curr.rows >> 1);
            cv::circle(frame, center, (int)radius, cv::Scalar(0, 255, 0), 3, CV_AA);
            cv::line(frame, center, Point(center.x + (int)shift.x, center.y + (int)shift.y), cv::Scalar(0, 255, 0), 3, CV_AA);
        }

        imshow("phase shift", frame);
        key = waitKey(2);

        prev = curr.clone();
    } while((char)key != 27); // Esc to exit...

    return 0;
}

Для проверки необходимо подключить web-камеру и перемещать ее.
  • 0
  • 18 октября 2012, 16:19
  • vidikon

Комментарии (0)

RSS свернуть / развернуть

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.