如何将光流场(浮点)映射到像素数据(char)以进行图像变形?

时间:2011-06-16 07:31:50

标签: c++ c graphics image-processing opencv

我一直在玩OpenCV中的光流功能而且卡住了。我已经使用Farneback方法成功生成了X和Y光流场/地图,但我不知道如何将其应用于输入图像坐标以扭曲图像。生成的X和Y字段是32位浮点类型(0-1.0),但这如何转换为输入和输出图像的坐标?例如,1.0是什么?图像的宽度?两者之间的区别?

另外,我不确定应用transform / warp的循环是什么样的。我已经做了很多循环来改变颜色,但像素总是保持在同一个位置。移动像素对我来说是新的领域!

更新:我让这个工作,但结果图像很乱:

//make a float copy of 8 bit grayscale source image
IplImage *src_img = cvCreateImage(img_sz, IPL_DEPTH_32F, 1);
cvConvertScale(input_img,src_img,1/255.0); //convert 8 bit to float

//create destination image
IplImage *dst_img = cvCreateImage(img_sz, IPL_DEPTH_32F, 1);

for(y = 0; y < flow->height; y++){

    //grab flow maps for X and Y
    float* vx = (float*)(velx->imageData + velx->widthStep*y);
    float* vy = (float*)(vely->imageData + vely->widthStep*y);

    //coords for source and dest image
    const float *srcpx = (const float*)(src_img->imageData+(src_img->widthStep*y));
    float *dstpx = (float*)(dst_img->imageData+(dst_img->widthStep*y));

    for(x=0; x < flow->width; x++)
    {
        int newx = x+(vx[x]);
        int newy = (int)(vy[x])*flow->width;
        dstpx[newx+newy] = srcpx[x];
    }
}

我无法让它发挥作用。输出只是乱码:

cvRemap(src_img,dst_img,velx,vely,CV_INTER_CUBIC,cvScalarAll(0));

2 个答案:

答案 0 :(得分:5)

流向量是速度值。如果位置(x, y)处的图像1中的像素具有流向量(vx, vy),则估计其位于(x+vx, y+vy)位置(因此值实际上不在[0, 1]范围内 - 它们可能更大,也可能是负面的)。最简单的扭曲方法是使用这些值创建浮点图像(x方向为x+vx,类似于y),然后使用cv::remap

答案 1 :(得分:1)

使用OpenCV

https://github.com/opencv/opencv/blob/master/samples/python/opt_flow.py

def warp_flow(img, flow):
    h, w = flow.shape[:2]
    flow = -flow
    flow[:,:,0] += np.arange(w)
    flow[:,:,1] += np.arange(h)[:,np.newaxis]
    res = cv2.remap(img, flow, None, cv2.INTER_LINEAR)
    return res

Sample Result