2012-06-22 19 views
7

Evitaría convertir cada cuadro tomado por la cámara de video con cvtColor(frame, image, CV_RGB2GRAY);
¿Hay alguna manera de establecer VideoCapture para obtener directamente en escala de grises?opencv VideoCapture.set escala de grises?

Ejemplo:

VideoCapture cap(0); 

cap.set(CV_CAP_PROP_FRAME_WIDTH,420); 
cap.set(CV_CAP_PROP_FRAME_HEIGHT,340); 
cap.set(CV_CAP_GREYSCALE,1); //< ??? 

Respuesta

3

Esto es imposible. Aquí está la lista de todos los códigos:

CV_CAP_PROP_POS_MSEC - position in milliseconds from the file beginning 
CV_CAP_PROP_POS_FRAMES - position in frames (only for video files) 
CV_CAP_PROP_POS_AVI_RATIO - position in relative units (0 - start of the file, 1 - end of the file) 
CV_CAP_PROP_FRAME_WIDTH - width of frames in the video stream (only for cameras) 
CV_CAP_PROP_FRAME_HEIGHT - height of frames in the video stream (only for cameras) 
CV_CAP_PROP_FPS - frame rate (only for cameras) 
CV_CAP_PROP_FOURCC - 4-character code of codec (only for cameras). 

O (si es posible, el uso de algunos servicios públicos) se puede configurar la cámara para mostrar sólo la imagen en escala de grises.

Para convertir una imagen coloreada a escala de grises debe llamar al cvtColor con el código CV_BGR2GRAY. Esto no debería tomar mucho tiempo.

+2

La conversión de color segura no es gran cosa en OpenCV a menos que esté en sistemas integrados donde la potencia de la CPU es crucial y un cvtColor en cada bucle podría hacer que los fps se vuelvan más duros. Como con la Raspberry Pi. – Void

+0

Esto no es completamente cierto, ver mi respuesta. –

6

Si su cámara es compatible con YUV420 entonces sólo podía tomar el canal Y: http://en.wikipedia.org/wiki/YUV

Cómo hacer que está bien explicado aquí: Access to each separate channel in OpenCV

Advertencia: el canal Y podría no ser la primera Mat obtienes split() así que deberías hacer un imshow() de todos ellos por separado y elegir el que se parece a la imagen gris "real". Los otros simplemente se quedarán sin contraste, así que será obvio. Para mí fue la segunda estera.

Por lo general, cualquier cámara debe ser capaz de hacer YUV420, ya que el envío de cuadros directamente en RGB es más lento, por lo que casi todas las cámaras utilizan YUV. :)

+0

En realidad, recuperar marcos en YUV y convertirlos en escala de grises tiene el mismo costo de CPU que usar la función spit() para trabajar solo en el canal Y. Tal vez vea una reducción en el uso de la CPU al 3% cuando se usa la función split en lugar de cvtColor (en una tarjeta ARM cortex A9 1.1 ghz) –

3

Esto no es posible si usa v4l (el método de captura de cv por defecto en el escritorio de Linux). El CV_CAP_PROP_FORMAT existe, pero simplemente se ignora. Tienes que convertir las imágenes a escala de grises de forma manual. Si su dispositivo lo admite, puede volver a implementar cap_v4l.cpp para conectar la interfaz v4l y establecer el formato en escala de grises.

En Android esto es posible con el siguiente código nativo (para el dispositivo 0 ª):

#include<opencv2/highgui/highgui.hpp> 
#include<opencv2/highgui/highgui_c.h> 

cv::VideoCapture camera(0); 
camera->open(0); 
cv::Mat dest(480,640,CV_8UC1); 
if(camera->grab()) 
    camera->retrieve(dest,CV_CAP_ANDROID_GREY_FRAME); 

Aquí, pasando CV_CAP_ANDROID_GREY_FRAME al parámetro channel de cv::VideoCapture::retrieve(cv::Mat,int) hace que la imagen (también conocido como yuv420sp) YUV NV21 a ser de color convertido a escala de grises Esto es solo un mapeo del canal Y a la imagen en escala de grises, que no implica ninguna conversión real o memcpy, por lo tanto muy rápido. Puede verificar este comportamiento en https://github.com/Itseez/opencv/blob/master/modules/videoio/src/cap_android.cpp#L407 y la "conversión de color" en https://github.com/Itseez/opencv/blob/master/modules/videoio/src/cap_android.cpp#L511. Estoy de acuerdo en que este comportamiento no está documentado en absoluto y es muy incómodo, pero me ahorró mucho tiempo de CPU.

Cuestiones relacionadas