Pregunta

Me encontré con este video de youtube aquí http://www.youtube.com/watch?v = Ha5LficiSJM que demuestra que alguien está haciendo detección de color utilizando el marco AForge.NET. Me gustaría duplicar lo que el autor ha hecho, pero no estoy seguro de cómo hacer algo de procesamiento de imágenes.

Parece que el marco AForge.NET le permite arrastrar hacia abajo desde la fuente de vídeo de la imagen en un formato de mapa de bits. Mi pregunta es que me podría apuntar a nadie en la dirección o pueden servir de orientación sobre la forma de interrogar a un objeto de mapa de bits para encontrar colores específicos en ella? (Por ejemplo - si hay 'rojo' o 'púrpura' en la imagen de X segundos, me gustaría plantear un evento 'ColorDetected' o algo así ...)

¿Alguien tiene alguna sugerencia sobre dónde empezar?

Gracias,

-R.

EDIT: ¿Me necesidad de caminar todo el objeto de mapa de bits e interrogar a cada píxel para el color? De este modo: http://msdn.microsoft.com/ en-us / library / system.drawing.bitmap.getpixel.aspx

¿Fue útil?

Solución

Bueno, siempre se puede utilizar el método de GDI +.

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

Sin embargo, GetPixel es en realidad bastante lenta. Trate de esa manera en primer lugar, pero si usted necesita para escanear muchas imágenes relativamente grandes puede que no funcione para usted. En ese caso, utilice LockBits para obtener un puntero a un bloque de memoria contigua. A continuación, puede recorrer la imagen rápidamente, pero usted tiene que saber cómo manipular los punteros, aunque no es terriblemente complicado.

EDIT: Usando LockBits mirar a cada píxel:

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

Si las imágenes se rellenan al final puede utilizar la propiedad BitmapData.Stride llegar al inicio de cada nueva fila (de lo contrario va a leer un poco de chatarra y sus compensaciones será chiflado).

Otros consejos

Además de respuesta Ed Swangren's con LockBits puede evitar punteros todos juntos. Si está utilizando el WPF (o tiene acceso a) puede hacer algo como esto:

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

Y ahora sólo se puede hacer una matriz de búsqueda de virus con pixels sin punteros. Este fragmento es un par de años y de un proyecto en el que he desarrollado mi propia solución AmbiLight lo que puede ser bastante rápido. Una vez más, se trata de unos pocos años, así como nuevas clases WriteableBitmap etc., pueden ser mejor y evitar una matriz de copia. En mi inicialmente solución Solía ??punteros, pero cuando me di cuenta de que no era necesario que lo cambié.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top