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

Ran*_*ter 8 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

Ed *_* S. 17

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

Bitmap b = new Bitmap( "some path" );
Color x = b.GetPixel( x, y );
Run Code Online (Sandbox Code Playgroud)

但是,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);
Run Code Online (Sandbox Code Playgroud)

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


Las*_*olt 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); 
Run Code Online (Sandbox Code Playgroud)

现在你可以在pixels没有指针的情况下进行常规阵列扫描.这个片段已有几年历史了,我开发了自己的AmbiLight解决方案,因此它可以非常快.同样,这是几年前的事情,所以像WriteableBitmap等等新类可能更好,避免阵列复制.在我最初的解决方案中,我使用了指针,但当我发现没有必要时我会切换.

  • 是的,我同意.从最简单的方法开始,并进行一些时序测试.如果它有效,那么很好,如果没有,转移到另一种方法. (2认同)