图像失真的快速算法

时间:2011-12-06 09:26:06

标签: algorithm image-processing emgucv

我正在研究扭曲图像的工具,失真的目的是将图像投影到球形屏幕。所需的输出如下图所示。

我使用的代码如下 - 对于目标区域中的每个Point(x,y),我计算要检索的原始图像中的相应像素(sourceX,sourceY)。

但是这种方法很慢,在我的测试中,处理sunset.jpg(800 * 600)需要超过1500ms,如果我删除了数学/三角计算,单独调用cvGet2D和cvSet2D需要超过1200ms。

有更好的方法吗?我正在使用Emgu CV(OpenCV的.NET包装器库),但其他语言的示例也没问题。

private static void DistortSingleImage()
{
    System.Diagnostics.Stopwatch stopWatch = System.Diagnostics.Stopwatch.StartNew();
    using (Image<Bgr, Byte> origImage = new Image<Bgr, Byte>("sunset.jpg"))
    {
        int frameH = origImage.Height;
        using (Image<Bgr, Byte> distortImage = new Image<Bgr, Byte>(2 * frameH, 2 * frameH))
        {
            MCvScalar pixel;
            for (int x = 0; x < 2 * frameH; x++)
            {
                for (int y = 0; y < 2 * frameH; y++)
                {
                    if (x == frameH && y == frameH) continue; 
                    int x1 = x - frameH;
                    int y1 = y - frameH;
                    if (x1 * x1 + y1 * y1 < frameH * frameH) 
                    {
                        double radius = Math.Sqrt(x1 * x1 + y1 * y1);
                        double theta = Math.Acos(x1 / radius);
                        int sourceX = (int)(theta * (origImage.Width - 1) / Math.PI);
                        int sourceY = (int)radius;
                        pixel = CvInvoke.cvGet2D(origImage.Ptr, sourceY, sourceX);
                        CvInvoke.cvSet2D(distortImage, y, x, pixel);
                    }
                }
            }
            distortImage.Save("Distort.jpg");
        }
        Console.WriteLine(stopWatch.ElapsedMilliseconds);
    }
}

The desired distortion

1 个答案:

答案 0 :(得分:2)

从我个人的经验来看,我正在做一些立体视觉的东西,与openCV交谈的最好方法是通过自己的包装器,你可以把你的方法放在c ++中并用c#调用它,这会给你1个本机调用,更快的代码,并且因为在Emgu保留OpenCV数据的情况下,也可以使用emgu创建图像,本地处理它并再次在c#中享受处理过的图像。

get / set方法看起来像Gdi的GetPixel / SetPixel方法,根据文档,它们是“缓慢但安全的方式”。

仅保留Emgu,文档告诉您如果要迭代像素,则应该访问.Data属性:

安全(缓慢)

假设您正在处理图像。您可以通过调用获取第y行和第x列的像素 Bgr color = img [y,x]; 设置第y行和第x列的像素也很简单 img [y,x] = color;

快捷方式

图像像素值存储在Data属性(3D数组)中。如果需要迭代图像的像素值,请使用此属性。