简体   繁体   English

EMGUCV最快设置像素

[英]EMGUCV fastest set pixel

I Need fastest way to iterate an EmguCV bitmap matrix and set pixel. 我需要最快的方法来迭代EmguCV位图矩阵并设置像素。 i found this after google but it takes about 3 sec for 700x500 image: 我在Google之后找到了这个,但700x500图片大约需要3秒:

Documents says that access (get) data matrix is just o(1) but its not clearly declare about set data. 文档说访问(获取)数据矩阵只是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;

        }

Thanks in advance. 提前致谢。

The getter for Emgu.CV.Image<> 's Data property returns a reference to the three-dimension array that is used internally by the class. Emgu.CV.Image<>Data属性的getter返回对该类内部使用的三维数组的引用。 When you assign to an element of that array (as you are doing in the code above) you are not calling the setter for the Data property, you are manipulating the array itself. 当您分配给该数组的元素时(就像在上面的代码中所做的那样),您没有在调用Data属性的setter,而是在操纵数组本身。

I suspect that the slowdown you are experiencing is related to calling unmanaged code, since the EmguCV code is largely unmanaged. 我怀疑您遇到的速度下降与调用非托管代码有关,因为EmguCV代码在很大程度上是非托管的。

Try this and see if there is any change in speed: 试试看,看看速度是否有变化:

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

Also the Image class has a method SetValue that sets every pixel to a specific value. Image类还具有SetValue方法,该方法将每个像素设置为特定值。 If what you are trying to achieve is to clear the image to white, try calling img.SetValue(new Rgb(255,255,255)) (or whichever color type you're using for the image) instead of doing it manually. 如果要实现的目的是将图像清除为白色,请尝试调用img.SetValue(new Rgb(255,255,255)) (或用于图像的任何一种颜色类型),而不要手动进行操作。 May be quicker. 可能更快。

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

It is much faster to convert your Emgu.Cv.Image to System.Drawing.Bitmap and iterate through the bitmap, either using safe or unsafe method. 将您的Emgu.Cv.Image转换为System.Drawing.Bitmap并使用安全或不安全的方法遍历位图要快得多。

  • The safe method uses 安全方法使用

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

    and it is fairly straight forward. 这是相当简单的。

  • The unsafe method is super fast, relies on bmp.lockbits(bmp_data) and interopservices.marshal to copy bmp data to array. 不安全的方法超级快,它依赖于bmp.lockbits(bmp_data)interopservices.marshal将bmp数据复制到数组。 You can find tons of examples online. 您可以在线找到大量示例。

I am very disappointed with EmguCV 3.0 pixel access. 我对EmguCV 3.0像素访问感到非常失望。

Here is a method I use to replace color, it replaces any color given that is not within a given (difference) to the desired one. 这是我用来替换颜色的一种方法,它替换给定颜色(与给定颜色不同)内的任何颜色。 Its very fast, uses unsafe 它非常快,使用不安全

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM