Pregunta

En mi programa C/C++, estoy usando OpenCV para capturar imágenes desde mi cámara web.La Cámara (Logitech QuickCam mensajería instantánea) puede capturar en resoluciones 320x240, 640x480 y 1280x960.Pero, por alguna extraña razón, OpenCV me da imágenes de resolución. 320x240 solo.Llamadas para cambiar la resolución usando cvSetCaptureProperty() con otros valores de resolución simplemente no funcionan.¿Cómo capturo imágenes con otras resoluciones posibles con mi cámara web?

¿Fue útil?

Solución 2

No parece haber una solución.La resolución se puede aumentar a 640x480 usando este truco compartido por cinturón salvavidas77.Aquí se reproducen los detalles:

añadir highgui.h:

#define CV_CAP_PROP_DIALOG_DISPLAY 8
#define CV_CAP_PROP_DIALOG_FORMAT 9
#define CV_CAP_PROP_DIALOG_SOURCE 10
#define CV_CAP_PROP_DIALOG_COMPRESSION 11
#define CV_CAP_PROP_FRAME_WIDTH_HEIGHT 12

Agregar la función icvSetPropertyCAM_VFW a cvcap.cpp:

static int icvSetPropertyCAM_VFW( CvCaptureCAM_VFW* capture, int property_id, double value )
{
    int result = -1;
    CAPSTATUS capstat;
    CAPTUREPARMS capparam;
    BITMAPINFO btmp;

    switch( property_id )
    {
        case CV_CAP_PROP_DIALOG_DISPLAY:
            result = capDlgVideoDisplay(capture->capWnd);
            //SendMessage(capture->capWnd,WM_CAP_DLG_VIDEODISPLAY,0,0);
            break;

        case CV_CAP_PROP_DIALOG_FORMAT:
            result = capDlgVideoFormat(capture->capWnd);
            //SendMessage(capture->capWnd,WM_CAP_DLG_VIDEOFORMAT,0,0);
            break;

        case CV_CAP_PROP_DIALOG_SOURCE:
            result = capDlgVideoSource(capture->capWnd);
            //SendMessage(capture->capWnd,WM_CAP_DLG_VIDEOSOURCE,0,0);
            break;

        case CV_CAP_PROP_DIALOG_COMPRESSION:
            result = capDlgVideoCompression(capture->capWnd);
            break;

        case CV_CAP_PROP_FRAME_WIDTH_HEIGHT:
            capGetVideoFormat(capture->capWnd, &btmp, sizeof(BITMAPINFO));
            btmp.bmiHeader.biWidth = floor(value/1000);
            btmp.bmiHeader.biHeight = value-floor(value/1000)*1000;
            btmp.bmiHeader.biSizeImage = btmp.bmiHeader.biHeight *
            btmp.bmiHeader.biWidth * btmp.bmiHeader.biPlanes *
            btmp.bmiHeader.biBitCount / 8;
            capSetVideoFormat(capture->capWnd, &btmp, sizeof(BITMAPINFO));
            break;

        default:
            break;
    }

    return result;
}

y editar capturarCAM_VFW_vtable como sigue:

static CvCaptureVTable captureCAM_VFW_vtable =
{
6,
(CvCaptureCloseFunc)icvCloseCAM_VFW,
(CvCaptureGrabFrameFunc)icvGrabFrameCAM_VFW,
(CvCaptureRetrieveFrameFunc)icvRetrieveFrameCAM_VFW,
(CvCaptureGetPropertyFunc)icvGetPropertyCAM_VFW,
(CvCaptureSetPropertyFunc)icvSetPropertyCAM_VFW, // was NULL
(CvCaptureGetDescriptionFunc)0
};

Ahora reconstruido highgui.dll.

Otros consejos

Estoy usando openCV 1.1pre1 en Windows (esta versión de openCv en Windows usa la biblioteca de entrada de video de forma predeterminada).

Con estas instrucciones puedo configurar la resolución de la cámara.Tenga en cuenta que llamo al antiguo cvCreateCameraCapture en lugar de cvCaptureFromCam.

capture = cvCreateCameraCapture(cameraIndex);

cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH, 640 );

cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT, 480 );


videoFrame = cvQueryFrame(capture);

Lo he probado con cámaras web Logitech, Trust y Philips.

He realizado procesamiento de imágenes en Linux antes y me salté la funcionalidad de cámara integrada de OpenCV porque está (como has descubierto) incompleta.

Dependiendo de su sistema operativo, es posible que tenga más suerte si accede directamente al hardware a través de canales normales que a través de openCV.Si está utilizando Linux, video4linux o video4linux2 deberían brindarle un acceso relativamente trivial a cámaras web USB y puede usar libavc1394 para firewire.Dependiendo del dispositivo y la calidad del código de ejemplo que siga, debería poder hacer que el dispositivo funcione con los parámetros que desea en una o dos horas.

Editado para agregar:Estás solo si se trata de Windows.Imagino que no es mucho más difícil pero nunca lo he hecho.

Recomiendo encarecidamente utilizar Biblioteca de entrada de vídeo, admite cualquier dispositivo DirectShow (incluso varios dispositivos al mismo tiempo) y es más configurable.Pasarás cinco minutos haciéndolo funcionar con OpenCV.

Mira este boleto:https://code.ros.org/trac/opencv/ticket/376

"La solución es utilizar el nuevo contenedor basado en libv4l.

  1. instale libv4l-dev (así se llama en Ubuntu)

  2. Vuelva a ejecutar cmake y verá "V4L/V4L2:Usando libv4l"

  3. volver a ejecutar make.ahora se puede cambiar la resolución.Probado con isight incorporado en MBP."

Esto me solucionó el problema al usar Ubuntu y también podría funcionar para ti.

Código que finalmente puse a funcionar en Python una vez que Aaron Haun señaló que necesitaba definir los argumentos de la función set antes de usarlos.

#Camera_Get_Set.py
#By Forrest L. Erickson of VRX Company Inc. 8-31-12.
#Opens the camera and reads and reports the settings.
#Then tries to set for higher resolution.
#Workes with Logitech C525 for resolutions 960 by 720 and 1600 by 896


import cv2.cv as cv
import numpy

CV_CAP_PROP_POS_MSEC = 0
CV_CAP_PROP_POS_FRAMES = 1
CV_CAP_PROP_POS_AVI_RATIO = 2
CV_CAP_PROP_FRAME_WIDTH = 3
CV_CAP_PROP_FRAME_HEIGHT = 4
CV_CAP_PROP_FPS = 5
CV_CAP_PROP_POS_FOURCC = 6
CV_CAP_PROP_POS_FRAME_COUNT = 7
CV_CAP_PROP_BRIGHTNESS = 8
CV_CAP_PROP_CONTRAST = 9
CV_CAP_PROP_SATURATION = 10
CV_CAP_PROP_HUE = 11

CV_CAPTURE_PROPERTIES = tuple({
CV_CAP_PROP_POS_MSEC,
CV_CAP_PROP_POS_FRAMES,
CV_CAP_PROP_POS_AVI_RATIO,
CV_CAP_PROP_FRAME_WIDTH,
CV_CAP_PROP_FRAME_HEIGHT,
CV_CAP_PROP_FPS,
CV_CAP_PROP_POS_FOURCC,
CV_CAP_PROP_POS_FRAME_COUNT,
CV_CAP_PROP_BRIGHTNESS,
CV_CAP_PROP_CONTRAST,
CV_CAP_PROP_SATURATION,
CV_CAP_PROP_HUE})

CV_CAPTURE_PROPERTIES_NAMES = [
"CV_CAP_PROP_POS_MSEC",
"CV_CAP_PROP_POS_FRAMES",
"CV_CAP_PROP_POS_AVI_RATIO",
"CV_CAP_PROP_FRAME_WIDTH",
"CV_CAP_PROP_FRAME_HEIGHT",
"CV_CAP_PROP_FPS",
"CV_CAP_PROP_POS_FOURCC",
"CV_CAP_PROP_POS_FRAME_COUNT",
"CV_CAP_PROP_BRIGHTNESS",
"CV_CAP_PROP_CONTRAST",
"CV_CAP_PROP_SATURATION",
"CV_CAP_PROP_HUE"]


capture = cv.CaptureFromCAM(0)

print ("\nCamera properties before query of frame.")
for i in range(len(CV_CAPTURE_PROPERTIES_NAMES)):
#    camera_valeus =[CV_CAPTURE_PROPERTIES_NAMES, foo]
    foo = cv.GetCaptureProperty(capture, CV_CAPTURE_PROPERTIES[i])
    camera_values =[CV_CAPTURE_PROPERTIES_NAMES[i], foo]
#    print str(camera_values)
    print str(CV_CAPTURE_PROPERTIES_NAMES[i]) + ": " + str(foo)


print ("\nOpen a window for display of image")
cv.NamedWindow("Camera", 1)
while True:
    img = cv.QueryFrame(capture)
    cv.ShowImage("Camera", img)
    if cv.WaitKey(10) == 27:
        break
cv.DestroyWindow("Camera")


#cv.SetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 1024)
#cv.SetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 768)
cv.SetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 1600)
cv.SetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 896)


print ("\nCamera properties after query and display of frame.")
for i in range(len(CV_CAPTURE_PROPERTIES_NAMES)):
#    camera_valeus =[CV_CAPTURE_PROPERTIES_NAMES, foo]
    foo = cv.GetCaptureProperty(capture, CV_CAPTURE_PROPERTIES[i])
    camera_values =[CV_CAPTURE_PROPERTIES_NAMES[i], foo]
#    print str(camera_values)
    print str(CV_CAPTURE_PROPERTIES_NAMES[i]) + ": " + str(foo)


print ("/nOpen a window for display of image")
cv.NamedWindow("Camera", 1)
while True:
    img = cv.QueryFrame(capture)
    cv.ShowImage("Camera", img)
    if cv.WaitKey(10) == 27:
        break
cv.DestroyWindow("Camera")

Estoy usando Debian y Ubuntu, tuve el mismo problema, no pude cambiar la resolución de la entrada de video usando CV_CAP_PROP_FRAME_WIDTH y CV_CAP_PROP_FRAME_HEIGHT

Resultó que el motivo era que faltaba una biblioteca.lo instalé lib4l-dev a través de sináptico, reconstruido ¡OpenCV y el problema está SOLUCIONADO!

Estoy publicando esto para asegurarme de que nadie más pierda el tiempo en esta función setproperty.Pasé 2 días en esto y vi que nada parece funcionar.Así que desenterré el código (había instalado la biblioteca la primera vez).Esto es lo que realmente sucede: cvSetCaptureProperty, llama a setProperty dentro de la clase CvCapture y he aquí que setProperty no hace nada.Simplemente devuelve falso.En lugar de eso, continuaré usando otra biblioteca para alimentar a OpenCV con una captura de video/imágenes.Estoy usando OpenCV 2.2

cvSetCaptureProperty (captura, CV_CAP_PROP_FRAME_WIDTH, ANCHO);

cvSetCaptureProperty( captura, CV_CAP_PROP_FRAME_HEIGHT, ALTURA);

cvQueryFrame(capturar);

¡Eso no funcionará con OpenCV 2.2, pero si usa OpenCV 2.1 funcionará bien!

Si está en la plataforma Windows, pruebe DirectShow (IAMStreamConfig).

http://msdn.microsoft.com/en-us/library/dd319784%28v=vs.85%29.aspx

En Windows, intente utilizar la biblioteca VideoInput:http://robocraft.ru/blog/computervision/420.html

Encuentro que en Windows (desde Win98 hasta WinXP SP3), OpenCV suele utilizar la biblioteca VFW de Microsoft para acceder a la cámara.El problema con esto es que a menudo es muy lento (digamos un máximo de captura de fotogramas de 15 FPS) y tiene errores (de ahí que cvSetCaptureProperty a menudo no funcione).Afortunadamente, generalmente puedes cambiar la resolución en otro software (particularmente "AMCAP", que es un programa de demostración que está fácilmente disponible) y afectará la resolución que utilizará OpenCV.Por ejemplo, puede ejecutar AMCAP para establecer la resolución en 640x480, y luego OpenCV la usará de forma predeterminada a partir de ese momento.

Pero si puede utilizar una biblioteca de acceso a la cámara de Windows diferente, como la biblioteca "videoInput" http://muonics.net/school/spring05/videoInput/ que accede a la cámara mediante DirectShow muy eficiente (parte de DirectX).O si tiene una cámara de calidad profesional, a menudo vendrá con una API personalizada que le permitirá acceder a la cámara, y podrá usarla para un acceso rápido con la capacidad de cambiar la resolución y muchas otras cosas.

¡Solo una información que podría ser valiosa para las personas que tienen dificultades para cambiar la resolución de captura predeterminada (640 x 480)!Yo mismo experimenté un problema de este tipo con opencv 2.4.x y una cámara Logitech...¡Y encontré una solución!

El comportamiento que detecté es que el formato predeterminado se configura como parámetros iniciales cuando se inicia la captura de la cámara (cvCreateCameraCapture), y todas solicitan cambiar el alto o el ancho:

cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH, ... 

o

cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT, ...

¡No son posibles después!Efectivamente, al agregar el error de retorno de las funciones ioctl descubrí que el controlador V4l2 está devolviendo EBUSY ¡Por esas solicitudes!Por lo tanto, una solución debería ser cambiar el valor predeterminado directamente en highgui/cap_v4l.cpp:

*#define DEFAULT_V4L_WIDTH  1280    // Originally 640* 

*#define DEFAULT_V4L_HEIGHT 720     // Originally 480*

Después de eso, simplemente recompilé abiertocv ...¡Y llegué a 1280 x 720 sin ningún problema!Por supuesto, una mejor solución debería ser detener la adquisición, cambiar los parámetros y reiniciar la transmisión después, ¡pero no estoy lo suficientemente familiarizado con opencv para hacer eso!

Espero que ayude.

Michel BEGEY

Prueba esto:

capture = cvCreateCameraCapture(-1);
//set resolution
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, frameWidth);
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, frameHeight);
cvQueryFrame(capture);

cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH, any_supported_size );

cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT, any_supported_size);

cvQueryFrame(capture);

¡Debería ser suficiente!

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