EMGUCV最快设置像素

时间:2013-02-23 20:29:25

标签: c# emgucv

我需要以最快的方式迭代EmguCV位图矩阵并设置像素。我在google之后发现了这个,但700x500图像需要大约3秒钟:

文件说访问(获取)数据矩阵只是o(1)但它没有明确声明设置数据。



    for(int i = 0; i < img.Rows ; i++)

        for(int j = 0; j < img.Cols; j++){

            img.Data[x,y,0] = 255;

            img.Data[x,y,1] = 255;

            img.Data[x,y,2] = 255;

        }


提前致谢。

4 个答案:

答案 0 :(得分:3)

Emgu.CV.Image<>的{​​{1}}属性的getter返回对类内部使用的三维数组的引用。当您分配给该数组的元素时(正如您在上面的代码中所做的那样),您没有调用Data属性的setter,而是在操作数组本身。

我怀疑您遇到的速度减慢与调用非托管代码有关,因为EmguCV代码基本上不受管理。

试试这个并查看速度是否有任何变化:

Data

Byte[,,] data = img.Data; int rows = img.Rows; int cols = img.Cols; for (int y = 0; y < rows; ++i) { for (int x = 0; x < cols; ++x) { data[x, y, 0] = 255; data[x, y, 1] = 255; data[x, y, 2] = 255; } } 类还有一个方法Image,可以将每个像素设置为特定值。如果您要实现的目的是将图像清除为白色,请尝试调用SetValue(或者您正在使用的图像颜色类型),而不是手动执行。可能会更快。

答案 1 :(得分:1)

for (int y = 0; y < rows; y++)
{
    for (int x = 0; x < cols; x++)
    {
        b = (int)frameClone.Data[y, x, 0];
        g = (int)frameClone.Data[y, x, 1];
        r = (int)frameClone.Data[y, x, 2];
    }

    currIntensity = b + g + r;
}

答案 2 :(得分:1)

Emgu.Cv.Image转换为System.Drawing.Bitmap并使用安全或不安全的方法迭代位图要快得多。

  • 安全方法使用

    color.toargb = bmp.getpixel(X, Y).toargb / bmp.setpixel(X, Y).toargb 
    

    并且相当直接。

  • 不安全的方法非常快,依靠bmp.lockbits(bmp_data)interopservices.marshal将bmp数据复制到数组。你可以在网上找到大量的例子。

我对EmguCV 3.0像素访问感到非常失望。

答案 3 :(得分:0)

这是我用来替换颜色的方法,它将给定的不在给定(差异)范围内的任何颜色替换为所需的颜色。它非常快,使用不安全

/// <summary>
    /// Replaces a given color in a bitmap
    /// </summary>
    /// <param name="image"></param>
    /// <returns></returns>
    public static unsafe void ReplaceColor(Bitmap image,
        Color FindColor,
        int WithinDistance,
        Color ReplaceColor
        )
    {

        byte FindColorR = (byte)FindColor.R;
        byte FindColorG = (byte)FindColor.G;
        byte FindColorB = (byte)FindColor.B;

        byte ReplaceColorR = (byte)ReplaceColor.R;
        byte ReplaceColorG = (byte)ReplaceColor.G;
        byte ReplaceColorB = (byte)ReplaceColor.B;

        byte WithinDistanceByte = (byte)WithinDistance;


        BitmapData imageData = image.LockBits(new Rectangle(0, 0, image.Width, image.Height),
            ImageLockMode.ReadWrite,
            PixelFormat.Format24bppRgb);



        int bytesPerPixel = 3;
        byte* scan0 = (byte*)imageData.Scan0.ToPointer();
        int stride = imageData.Stride;
        PixelData NewData = new PixelData(image.Height,image.Size);
        for (int y = 0; y < imageData.Height; y++)
        {
            byte* row = scan0 + (y * stride);
            for (int x = 0; x < imageData.Width; x++)
            {
                int bIndex = x * bytesPerPixel;
                int gIndex = bIndex + 1;
                int rIndex = bIndex + 2;

                byte pixelR = row[rIndex];
                byte pixelG = row[gIndex];
                byte pixelB = row[bIndex];

                if( Math.Abs(FindColorR - pixelR) > WithinDistanceByte && 
                    Math.Abs(FindColorG - pixelG) > WithinDistanceByte &&
                    Math.Abs(FindColorB - pixelB) > WithinDistanceByte )
                {
                    row[rIndex] = ReplaceColorR;
                    row[gIndex] = ReplaceColorG;
                    row[bIndex] = ReplaceColorB;
                }
                else
                {
                    row[rIndex] = FindColorR;
                    row[gIndex] = FindColorG;
                    row[bIndex] = FindColorB;
                }
            }
        }
        image.UnlockBits(imageData);
    }