EMGUCV fastest set pixel

限于喜欢 提交于 2019-12-11 15:06:53

问题


I Need fastest way to iterate an EmguCV bitmap matrix and set pixel. i found this after google but it takes about 3 sec for 700x500 image:

Documents says that access (get) data matrix is just o(1) but its not clearly declare about set data.



    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.


回答1:


The getter for Emgu.CV.Image<>'s Data property returns a reference to the three-dimension array that is used internally by the class. 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.

I suspect that the slowdown you are experiencing is related to calling unmanaged code, since the EmguCV code is largely unmanaged.

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. 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. May be quicker.




回答2:


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



回答3:


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.

  • 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. You can find tons of examples online.

I am very disappointed with EmguCV 3.0 pixel access.




回答4:


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


来源:https://stackoverflow.com/questions/15045295/emgucv-fastest-set-pixel

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!