Aumento de la resolución de captura de cámara en OpenCV

8 minutos de lectura

avatar de usuario
Ashwin Nanjappa

En mi programa C/C++, estoy usando OpenCV para capturar imágenes de mi cámara web. La Cámara (Logitech QuickCam MI) puede capturar en resoluciones 320×240, 640×480 y 1280×960. Pero, por alguna extraña razón, OpenCV me da imágenes de resolución. 320×240 solamente. Llamadas para cambiar la resolución usando cvSetCaptureProperty() con otros valores de resolución simplemente no funcionan. ¿Cómo capturo imágenes con las otras resoluciones posibles con mi cámara web?

  • Nota: un mal uso común del término “resolución” se refiere a él como la cantidad de píxeles en una imagen. NO es así como lo describen varios estándares. La resolución está estrechamente relacionada con el TAMAÑO de los píxeles y no con su NÚMERO. Puedes tener una imagen de 10MP con mala resolución o una de 1MP con alta resolución. Incluso la documentación de OpenCV, por suerte, no comete este error. De hecho si por ejemplo vas a docs.opencv.org/modules/superres/doc/super_solution.html y fíjate en las referencias de la parte inferior verás que se distingue claramente la resolución de la imagen del número de píxeles.

    – rbaleksandar

    29 de abril de 2014 a las 10:43

avatar de usuario
Grifo

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

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 webcams Logitech, Trust y Philips

  • También me funciona en OpenCV 1.1, y recomendaría que esta sea la respuesta aceptada.

    – Ray Hidayat

    16 de julio de 2009 a las 23:32

  • sí, confirmo que esto también funciona para mí. La solución actualmente aceptada no es necesaria.

    – hoju

    13 de octubre de 2009 a las 5:13

  • Los documentos dicen que esto no es compatible, pero incluso funciona con resoluciones HD. Sin embargo, si la resolución solicitada no está disponible en la cámara, vuelve a la resolución predeterminada de forma silenciosa. La solución actualmente aceptada no es necesaria.

    – Néstor

    9 de marzo de 2010 a las 1:25

  • verifique los valores de retorno de la propiedad cvSetCapture, no todas las cámaras aceptarán la instrucción

    – Martín Beckett

    5 oct 2010 a las 21:30

No parece haber una solución. La resolución se puede aumentar a 640×480 utilizando este truco compartido por salvavidas77. Aquí están los detalles reproducidos:

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

Añadir la función icvSetPropertyCAM_VFW para 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 de la siguiente manera:

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.

  • ¿Este método limita la resolución a 640×480?

    – postular laboratorios

    5 de abril de 2012 a las 1:25

He realizado procesamiento de imágenes en Linux antes y omití la funcionalidad de cámara integrada de OpenCV porque (como ha descubierto) está incompleta.

Dependiendo de su sistema operativo, puede tener más suerte yendo directamente al hardware a través de canales normales en lugar de a través de openCV. Si está utilizando Linux, video4linux o video4linux2 deberían brindarle un acceso relativamente trivial a las cámaras web USB y puede usar libavc1394 para firewire. Según el 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 es Windows. Me imagino que no es mucho más difícil pero nunca lo he hecho.

Sugiero fuertemente usar Librería de entrada de vídeo, admite cualquier dispositivo DirectShow (incluso varios dispositivos al mismo tiempo) y es más configurable. Pasarás cinco minutos para que se reproduzca con OpenCV.

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

“La solución es usar el nuevo contenedor basado en libv4l.

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

  2. vuelva a ejecutar cmake, verá “V4L/V4L2: Uso de libv4l”

  3. volver a ejecutar hacer. ahora se puede cambiar la resolución. Probado con visión integrada en MBP”.

Esto lo arregló para mí usando Ubuntu y también podría funcionar para usted.

avatar de usuario
forrest erickson

Código que finalmente puse a trabajar 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")

avatar de usuario
evangelos

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 la razón era una biblioteca perdida. lo instalé lib4l-dev a través de synaptic, reconstruido ¡OpenCV y el problema está SOLUCIONADO!

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad