在c#中查找图像中的颜色

时间:2010-09-25 19:38:55

标签: c# image image-processing aforge

我偶然发现了这个youtube视频http://www.youtube.com/watch?v=Ha5LficiSJM,它演示了使用AForge.NET框架进行颜色检测的人。我想复制作者所做的但我不知道如何进行图像处理。

似乎AForge.NET框架允许您从Bitmap格式的视频源下拉图像。我的问题是,有人能指出我的方向或提供一些指导如何询问Bitmap对象,以找到其中的特定颜色? (例如 - 如果图像中有“红色”或“紫色”持续X秒,我想提出一个事件'ColorDetected'或者左右......)

有没有人对从哪里开始有任何建议?

谢谢,

-R

编辑:我是否需要遍历整个Bitmap对象并询问每个像素的颜色?像这样:http://msdn.microsoft.com/en-us/library/system.drawing.bitmap.getpixel.aspx

2 个答案:

答案 0 :(得分:15)

好吧,你总是可以使用GDI +方法。

Bitmap b = new Bitmap( "some path" );
Color x = b.GetPixel( x, y );

然而,GetPixel实际上非常慢。首先尝试这种方式,但如果您需要扫描许多相对较大的图像,它可能不适合您。在这种情况下,使用LockBits获取指向连续内存块的指针。然后你可以快速遍历图像,但你必须知道如何操作指针,尽管它并不是非常复杂。

编辑:使用LockBits查看每个像素:

Bitmap b = new Bitmap( "some path" );
BitmapData data = b.LockBits( new Rectangle( 0, 0, b.Width, b.Height ),
ImageLockMode.ReadOnly, b.PixelFormat );  // make sure you check the pixel format as you will be looking directly at memory

unsafe
{         
    // example assumes 24bpp image.  You need to verify your pixel depth
    // loop by row for better data locality
    for( int y = 0; y < data.Height; ++y )
    {
        byte* pRow = (byte*)data.Scan0 + y * data.Stride;
        for( int x = 0; x < data.Width; ++x )
        {
            // windows stores images in BGR pixel order
            byte r = pRow[2];
            byte g = pRow[1];
            byte b = pRow[0];

            // next pixel in the row
            pRow += 3;
        }
    }
}

b.UnlockBits(data);

如果您的图像在最后填充,您可以使用BitmapData.Stride属性到达每个新行的开头(否则您将读取一些垃圾并且您的偏移将会变得棘手)。

答案 1 :(得分:5)

除了Ed Swangren对LockBits的回答之外,您还可以避免使用指针。如果您正在使用WPF(或有权访问),您可以执行以下操作:

var bitmap = new BitmapImage(uri);

//Pixel array
byte[] pixels = new byte[width * height * 4]; //account for stride if necessary

bitmap.CopyPixels(..size, pixels, fullStride, 0); 

现在,您可以使用pixels进行常规阵列扫描而不使用指针。这个片段已有几年历史了,我开发了自己的AmbiLight解决方案,因此它可以非常快。同样,这已经有几年了,所以像WriteableBitmap等新类可能会更好,避免使用数组副本。在我最初的解决方案中,我使用了指针,但是当我发现没有必要切换时。