2012-06-14 29 views
7

Estoy desarrollando aplicaciones de procesamiento de profundidad (Xbox Kinect, Asus Xtion, etc.) usando OpenNI.C# pixel rendering rápido

Necesito una manera muy simple y rápida de dibujar en un formulario de Windows cuando los nuevos datos de profundidad están disponibles desde el sensor (30 o 60 fps dependiendo de la resolución).

Actualmente estoy invalidando un panel de doble amortiguación de un hilo separado cuando los datos están disponibles, y luego estableciendo los píxeles de un mapa de bits en el método de pintura del panel, produciendo un horrible 5fps predeciblemente.

System.Drawing.Graphics parece carecer de una forma rápida de establecer píxeles individuales, a menos que alguien pueda indicar lo contrario.

Literalmente solo necesito establecer colores de píxeles, por lo que me gustaría evitar el uso de API de renderizado de alta velocidad de terceros si es posible, e idealmente usar algo tan nativo como sea posible.

¿Alguien tiene alguna sugerencia?

+0

¿Cómo está configurando los píxeles actualmente? – leppie

+0

Creó un mapa de bits, usando image.SetPixel (x, y, color). Después de todo eso, llamar a graphics.drawImage (image, etc) –

+2

'SetPixel' es muy lento. Mira el enfoque 'Scanline'. – leppie

Respuesta

4

Si está utilizando mapas de bits, entonces debe usar LockBits y UnlockBits para acceder a los datos directamente en la memoria. En C#, puede obtener un rendimiento adicional mediante el uso de bloques de código y punteros inseguros.

ver este enlace para más información: http://web.archive.org/web/20150227183132/http://bobpowell.net/lockingbits.aspx

+0

Esta fue una mejora drástica. No pude lograr más de 10 fps al dibujar un mapa de bits en blanco de 640x480, por lo que la conclusión es que System.Drawing simplemente no es rápido. Esta solución, combinada con escalar la imagen y solo renderizar algunos de los píxeles para lograr el FPS requerido, fue la respuesta. –

4

image.SetPixel() es muy lento cuando está reemplazando muchos píxeles por fotograma y necesita muchos fotogramas por segundo.

Se habrá mucho más rápido cuando se utiliza un WriteableBitmap y llame CopyPixels

De esta manera usted puede llenar la matriz con datos de píxel utilizando múltiples hilos y simplemente blit la matriz de la imagen en una sola llamada.

EDITAR

Tenga en cuenta que WriteableBitmap es una clase de WPF. Si está obligado a WinForms puede necesitar crear su propia implementación. WPF/WinForms/GDI interop: converting a WriteableBitmap to a System.Drawing.Image?

+0

Gracias por su respuesta, pero el enlace de respuesta que ha proporcionado usa .SetPixel() en la conversión de WriteableBitmap a System.Drawing.Image. –

+0

Sí, y eso es horrible para la velocidad. Una alternativa sería escribir en una matriz y usar un codificador (PNG, BMP, ...) para convertirla en una imagen y mostrarla. El principal problema con SetPixel es que establece un solo píxel. –

0

Usted podría intentar mi LINQ image processing library para trabajar con su "buffer-mapas de bits". Utiliza una sintaxis muy accesible, pero es muy eficaz para los grandes mapas de bits. Está disponible en Nuget como un archivo único incluido en su proyecto.

Espero que ayude!