Деформирующее изображение OpenCV на основе calcOpticalFlowFarneback

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

cv::Mat flow;
cv::calcOpticalFlowFarneback( mGrayFrame1, mGrayFrame2, flow, 0.5, 3, 15, 3, 5, 1.2, 0 );

cv::Mat newFrame = cv::Mat::zeros( frame.rows, frame.cols, frame.type() );
cv:remap( frame, newFrame, flow, cv::Mat(), CV_INTER_LINEAR );

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

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

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

Если бывший кто есть какие-либо предложения о том, как я могу решить эту проблему? Если последнее, то в чем я ошибаюсь?

любая помощь очень ценится!

1 ответов


на remap функция не может работать с оптическим потоком. Функция remap преобразует исходное изображение с помощью указанной карты:

dst(x, y) = src(mapx(x, y), mapy(x, y))

оптический поток имеет другую формулу:

frame1(x, y) = frame2(x + flowx(x, y), y + flowy(x, y))

чтобы использовать remap функция сначала вам нужно создать карту из потока:

Mat flow; // backward flow
calcOpticalFlowFarneback(nextFrame, prevFrame, flow);

Mat map(flow.size(), CV_32FC2);
for (int y = 0; y < map.rows; ++y)
{
    for (int x = 0; x < map.cols; ++x)
    {
        Point2f f = flow.at<Point2f>(y, x);
        map.at<Point2f>(y, x) = Point2f(x + f.x, y + f.y);
    }
}

Mat newFrame;
remap(prevFrame, newFrame, map);