10

我正在尝试使用密集光流对图像进行复杂的扭曲。我正在尝试将第二张图像扭曲成与第一张图像大致相同的形状。

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 );

我从两个灰度帧计算流量。我现在正在尝试使用该cv::remap功能使用此流信息重新映射我的原始(即非灰度)图像。但是,我从中得到了一个非常严重扭曲的图像。我只是最终得到一个与我的原始图像有点相似的橙色和黑色图像。

如何使用cv::remap计算flow

4

1 回答 1

17

remap功能不能flow直接使用。必须使用一个单独map的计算方法,该计算方法是采用反向流(从frame2frame1),然后通过其在像素网格上的位置偏移每个流向量。(x, y)请参阅下面的详细信息。

回想一下反向光流公式:

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

remap函数使用指定的转换源图像map

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

比较上面的两个等式,我们可以确定map需要remap

mapx(x, y) = x + flowx(x, y)
mapy(x, y) = y + flowy(x, y)

例子:

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);
于 2013-07-04T06:00:54.740 回答