Domanda

Nel mio programma C/C++, sto utilizzando OpenCV per catturare le immagini dalla mia webcam.La fotocamera (Logitech QuickCam IM) possono acquisire a risoluzioni 320x240, 640x480 e 1280x960.Ma, per qualche strana ragione, OpenCV mi dà immagini di risoluzione 320x240 solo.Chiamate a modificare la risoluzione utilizzando cvSetCaptureProperty() con la risoluzione di altri valori non funzionano.Come faccio a catturare le immagini con le altre risoluzioni possibili con la mia webcam?

È stato utile?

Soluzione 2

Non sembra esserci una soluzione. La risoluzione può essere aumentata a 640x480 utilizzando questo hack condiviso da lifebelt77 . Ecco i dettagli riprodotti:

Aggiungi a 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

Aggiungi la funzione icvSetPropertyCAM_VFW su 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;
}

e modifica captureCAM_VFW_vtable come segue:

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

Ora ricostruito highgui.dll .

Altri suggerimenti

Sto usando openCV 1.1pre1 in Windows (la libreria di input video è usata di default da questa versione di openCv in Windows).

Con queste istruzioni posso impostare la risoluzione della fotocamera. Nota che chiamo il vecchio cvCreateCameraCapture invece di cvCaptureFromCam.

capture = cvCreateCameraCapture(cameraIndex);

cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH, 640 );

cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT, 480 );


videoFrame = cvQueryFrame(capture);

L'ho provato con Logitech, Trust e le webcam Philips

Ho già elaborato le immagini in Linux prima e ho saltato la funzionalità della fotocamera integrata di OpenCV perché (come hai scoperto) incompleta.

A seconda del tuo sistema operativo potresti avere più fortuna andando direttamente all'hardware attraverso i normali canali invece che attraverso openCV. Se stai usando Linux, video4linux o video4linux2 dovrebbero darti un accesso relativamente banale alle webcam USB e puoi usare libavc1394 per firewire. A seconda del dispositivo e della qualità del codice di esempio che segui, dovresti riuscire a far funzionare il dispositivo con i parametri desiderati in un'ora o due.

Modificato per aggiungere: sei da solo se è Windows. Immagino che non sia molto più difficile ma non l'ho mai fatto.

Consiglio vivamente di utilizzare VideoInput lib , supporta qualsiasi dispositivo DirectShow (anche più dispositivi allo stesso tempo) ed è più configurabile. Trascorrerai cinque minuti per farlo giocare con OpenCV.

Dai un'occhiata a questo biglietto: https://code.ros.org/trac/opencv/ticket/376

" La soluzione è utilizzare il più recente wrapper basato su libv4l.

  1. installa libv4l-dev (ecco come si chiama in Ubuntu)

  2. Riesegui Cmake, vedrai " V4L / V4L2: Uso di libv4l "

  3. riesegui make. ora la risoluzione può essere cambiata. testato con isight integrato su MBP. "

Questo mi ha risolto usando Ubuntu e poteva funzionare anche per te.

Codice Ho finalmente funzionato in Python dopo che Aaron Haun ha sottolineato che dovevo definire gli argomenti della funzione set prima di usarli.

#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")

Sto usando Debian e Ubuntu, ho avuto lo stesso problema, non ho potuto cambiare la risoluzione dell'ingresso video usando CV_CAP_PROP_FRAME_WIDTH e CV_CAP_PROP_FRAME_HEIGHT

Ho scoperto che il motivo era una biblioteca mancante. Ho installato lib4l-dev tramite Synaptic, ricostruito OpenCV e il problema è RISOLTO!

Sto pubblicando questo per assicurarmi che nessun altro sprechi tempo con questa funzione setproperty. Ho trascorso 2 giorni su questo per vedere che nulla sembra funzionare. Quindi ho estratto il codice (avevo installato la libreria la prima volta). Questo è ciò che realmente accade: cvSetCaptureProperty, chiama setProperty all'interno della classe CvCapture e ecco setProperty non fa nulla. Restituisce semplicemente falso. Invece prenderò usando un'altra libreria per alimentare OpenCV per catturare video / immagini. Sto usando OpenCV 2.2

  

cvSetCaptureProperty (cattura, CV_CAP_PROP_FRAME_WIDTH, WIDTH);

     

cvSetCaptureProperty (cattura, CV_CAP_PROP_FRAME_HEIGHT, HEIGHT);

     

cvQueryFrame (cattura);

Questo non funzionerà con OpenCV 2.2, ma se usi OpenCV 2.1 funzionerà benissimo!

Se ti trovi sulla piattaforma Windows, prova DirectShow (IAMStreamConfig).

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

In Windows prova a utilizzare la libreria VideoInput: http://robocraft.ru/blog/computervision/420.html

Trovo che in Windows (da Win98 a WinXP SP3), OpenCV userà spesso la libreria VFW di Microsoft per l'accesso alla telecamera. Il problema è che è spesso molto lento (diciamo un massimo di 15 frame frame FPS) e buggy (quindi perché cvSetCaptureProperty spesso non funziona). Fortunatamente, di solito puoi modificare la risoluzione in altri software (in particolare "AMCAP", che è un programma demo facilmente disponibile) e influirà sulla risoluzione che OpenCV utilizzerà. Ad esempio, puoi eseguire AMCAP per impostare la risoluzione su 640x480, e da quel momento OpenCV la utilizzerà per impostazione predefinita!

Ma se puoi utilizzare una diversa libreria di accesso alle telecamere di Windows come "videoInput" libreria http://muonics.net/school/spring05/videoInput/ che accede alla telecamera usando DirectShow molto efficiente (parte di DirectX). O se hai una fotocamera di qualità professionale, spesso verrà fornita un'API personalizzata che ti consente di accedere alla fotocamera e potresti usarla per un accesso rapido con la possibilità di modificare la risoluzione e molte altre cose.

Solo un'informazione che potrebbe essere utile per le persone che hanno difficoltà a cambiare la risoluzione di acquisizione predefinita (640 x 480)! Mi sono sperimentato un tale problema con opencv 2.4.xe una videocamera Logitech ... e ho trovato una soluzione alternativa!

Il comportamento che ho rilevato è che il formato predefinito è impostato come parametri iniziali all'avvio dell'acquisizione della fotocamera (cvCreateCameraCapture) e tutte le richieste per modificare altezza o larghezza:

cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH, ... 

o

cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT, ...

non sono possibili in seguito! In effetti, ho scoperto con l'aggiunta dell'errore di ritorno delle funzioni ioctl che il driver V4l2 sta restituendo EBUSY per le richieste! Pertanto, una soluzione alternativa dovrebbe essere quella di modificare il valore predefinito direttamente in highgui / cap_v4l.cpp:

*#define DEFAULT_V4L_WIDTH  1280    // Originally 640* 

*#define DEFAULT_V4L_HEIGHT 720     // Originally 480*

Dopodiché, ho appena ricompilato opencv ... e sono arrivato per ottenere 1280 x 720 senza alcun problema! Ovviamente, una soluzione migliore dovrebbe essere quella di interrompere l'acquisizione, modificare i parametri e riavviare lo stream dopo, ma non ho abbastanza familiarità con opencv per farlo!

Spero che possa aiutare.

Michel BEGEY

Prova questo:

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

dovrebbe essere sufficiente!

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top