c++ - 如何将光流场(float)映射到像素数据(char)以进行图像变形?

标签 c++ c graphics image-processing opencv

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

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

更新:我让它工作了,但生成的图像很乱:

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

最佳答案

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

关于c++ - 如何将光流场(float)映射到像素数据(char)以进行图像变形?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6368499/

相关文章:

c++ - 将 boost 的缓冲流转换为 istream

c++ - 数组c++中的随机数据丢失

c - 将 x 个字符附加到字符串

c - 如何将宏定义从 "make"命令行参数 (-D) 传递给 C 源代码?

java - 不使用 OPENGL 在 Android 中制作动画

c++ - 在 c++ .h 文件中定义和声明函数/方法

c++ - 无法使用OpenCv 3.4.5从具有C++ dll的IP摄像机(rtsp)抓取帧

c - 为什么这个程序可以工作?返回局部结构变量

c# - 如何获取和设置图像的属性项

c# - System.Drawing.Graphics.DrawRectangle 绘制比指定大 1px 的矩形