2008-08-18 38 views
50

In meinem C/C++ - Programm verwende ich OpenCV, um Bilder von meiner Webcam zu erfassen. Die Kamera (Logitech QuickCam IM) kann mit Auflösungen 320x240, 640x480 und 1280x960 erfassen. Aber aus irgendeinem Grund gibt OpenCV mir Bilder der Auflösung 320x240 nur. Aufrufe zum Ändern der Auflösung mit cvSetCaptureProperty() mit anderen Auflösungswerten funktionieren einfach nicht. Wie nehme ich Bilder mit den anderen Auflösungen auf, die mit meiner Webcam möglich sind?In OpenCV wird die Auflösung der Kameraaufnahme erhöht.

+0

Hinweis: eine gemeinsame Missbrauch des Begriffs „Auflösung“ bezieht sich auf sie als die Anzahl der Pixel in einem image.This ist nicht, wie verschiedene Standards beschreiben. Die Auflösung hängt eng mit der Größe der Pixel und nicht mit ihrer NUMMER zusammen. Sie können ein 10MP-Bild mit einer schlechten Auflösung oder ein 1MP mit hoher Auflösung haben. Auch die Dokumentation von OpenCV macht glücklicherweise diesen Fehler nicht. Wenn Sie beispielsweise zu http://docs.opencv.org/modules/superres/doc/super_resolution.html gehen und die Referenzen unten betrachten, werden Sie sehen, dass die Bildauflösung deutlich von der Anzahl der Pixel unterschieden wird. – rbaleksandar

Antwort

15

Es scheint keine Lösung zu geben. Die Auflösung kann auf 640x480 unter Verwendung von this hack geteilt durch lifebelt77 erhöht werden. Hier sind die Details wiedergegeben:

In den 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 

Fügen Sie die Funktion icvSetPropertyCAM_VFW zu 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; 
} 

und bearbeiten captureCAM_VFW_vtable wie folgt:

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

Jetzt neu aufgebaut highgui.dll.

+0

Diese Methode begrenzt die Auflösung auf 640x480? –

5

Ich habe die Bildverarbeitung in Linux vor und übersprungen OpenCV eingebaute Kamera-Funktionalität, weil es (wie Sie entdeckt haben) unvollständig ist.

Abhängig von Ihrem Betriebssystem haben Sie mehr Glück, wenn Sie direkt über normale Kanäle zur Hardware gehen, im Gegensatz zu openCV. Wenn Sie Linux verwenden, sollte video4linux oder video4linux2 Ihnen relativ trivialen Zugriff auf USB-Webcams geben, und Sie können libavc1394 für Firewire verwenden. Abhängig vom Gerät und der Qualität des Beispielcodes, den Sie befolgen, sollten Sie in der Lage sein, das Gerät innerhalb von ein bis zwei Stunden mit den gewünschten Parametern zu starten.

Bearbeitet um hinzuzufügen: Sie sind auf eigene Faust, wenn es Windows ist. Ich kann mir vorstellen, dass es nicht viel schwieriger ist, aber ich habe es noch nie gemacht.

+0

Ich frage mich, wie können wir es in Windows machen? – Abc

5

Ich empfehle dringend, VideoInput lib zu verwenden, es unterstützt jedes DirectShow-Gerät (sogar mehrere Geräte zur gleichen Zeit) und ist konfigurierbar. Du wirst fünf Minuten damit verbringen, mit OpenCV zu spielen.

41

Ich benutze OpenCV 1.1pre1 unter Windows (videoInput-Bibliothek wird standardmäßig von dieser Version von openCv unter Windows verwendet).

Mit diesen Anweisungen kann ich die Kameraauflösung einstellen. Beachten Sie, dass ich die alte cvCreateCameraCapture anstelle von cvCaptureFromCam aufruft.

capture = cvCreateCameraCapture(cameraIndex); 

cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 640); 

cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 480); 


videoFrame = cvQueryFrame(capture); 

Ich habe es mit Logitech, Vertrauen getestet und Philips Webcams

+1

Funktioniert auch für mich auf OpenCV 1.1, und ich würde dies als die akzeptierte Antwort empfehlen. –

+0

yep, ich bestätige das funktioniert auch für mich. Die derzeit akzeptierte Lösung ist nicht notwendig. – hoju

+0

Die Dokumentation sagt, dass dies nicht unterstützt wird, aber es funktioniert sogar bei HD-Auflösungen.Wenn die angeforderte Auflösung jedoch nicht von der Kamera verfügbar ist, wird stillschweigend eine Standardauflösung zurückgenommen. Die derzeit akzeptierte Lösung ist nicht notwendig. – Nestor

-3
cvQueryFrame(capture); 

cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, any_supported_size); 

cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, any_supported_size); 

cvQueryFrame(capture); 

sollte gerade genug sein!

+0

Vielleicht können Sie versuchen, mehr über Ihren Code zu erklären. Da Sie eine sehr alte Frage beantwortet haben, kommt der ursprüngliche Fragesteller möglicherweise nicht zurück, kann aber anderen helfen. – Swapnil

+0

OP besagt, dass 'cvSetCaptureProperty' nicht funktioniert. –

-1

Versuchen Sie folgendes:

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

Sie schlagen also vor, den Anfangsparameter auf -1 zu setzen, dann? Was erreicht das? – JoshDM

+2

Der Anfangsparameter -1 für cvCreateCameraCapture wählt das erste verfügbare Gerät/Kamera aus. – Matthias

5

prüfen dieses Ticket aus: https://code.ros.org/trac/opencv/ticket/376

„Die Lösung ist die neuere libv4l-basierte Wrapper verwenden

  1. installieren libv4l-dev (. so heißt es in Ubuntu)

  2. wiederholen cmake, Sie werden sehen "V4L/V4L2: Verwenden von libv4l"

  3. erneut ausführen. Jetzt kann die Auflösung geändert werden. getestet mit integrierten iSight auf MBP.“

Dieses regelte es für mich mit Ubuntu und könnte für Sie aswell Arbeit.

+0

Wo sollte der cmake aufgerufen werden? –

+0

erinnern Sie sich nicht jetzt. http://opencv.willowgarage.com/wiki/InstallGuide http://opencv.willowgarage.com/wiki/InstallGuide%20%3A%20Debian Könnte helfen –

+0

Wird libv4l-basierte Wrapper für Windows arbeiten? – Abc

0

Ich finde, dass in Windows (ab Win98 auf WinXP SP3), OpenCV wird oft verwenden Microsoft VFW-Bibliothek für den Zugriff auf die Kamera.Das Problem dabei ist, dass es oft sehr langsam (sagen wir eine maximale 15 FPS Frame-Aufnahme) und fehlerhaft (daher warum cvSetCaptureProperty oft nicht funktioniert). Glücklicherweise können Sie die ändern B. in einer anderen Software (insbesondere "AMCAP", einem leicht verfügbaren Demoprogramm), und es wird die von OpenCV verwendete Auflösung beeinflussen.Sie können beispielsweise AMCAP ausführen, um die Auflösung auf 640x480 zu setzen, und dann wird OpenCV verwenden das standardmäßig von diesem weiter!

Aber wenn Sie eine andere Windows-Kamera zugreifen können Bibliothek wie die "videoInput" -Bibliothek http://muonics.net/school/spring05/videoInput/, die die Kamera mit sehr effizienten DirectShow (Teil von DirectX) zugreifen. Oder wenn Sie eine Kamera mit professioneller Qualität haben, dann wird sie oft mit einer benutzerdefinierten API geliefert, mit der Sie auf die Kamera zugreifen können, und Sie können diese für einen schnellen Zugriff verwenden, um die Auflösung und viele andere Dinge zu ändern.

4

ich Debian und Ubuntu verwenden, ich hatte das gleiche Problem, ich konnte nicht die Auflösung des Eingangsvideos ändern CV_CAP_PROP_FRAME_WIDTH und CV_CAP_PROP_FRAME_HEIGHT mit

Ich stellte sich heraus, dass der Grund eine fehlende Bibliothek war. Ich installierte lib4l-dev durch synaptic, umgebaut OpenCV und das Problem ist gelöst!

2

Ich poste dies, um sicherzustellen, dass niemand sonst Zeit mit dieser setproperty-Funktion verschwendet. Ich verbrachte 2 Tage damit, zu sehen, dass nichts zu funktionieren scheint. Also grub ich den Code aus (ich hatte die Bibliothek das erste Mal installiert). Dies geschieht tatsächlich - cvSetCaptureProperty, ruft setProperty in der CvCapture-Klasse auf und zeigt an, dass setProperty nichts tut. Es gibt nur falsch zurück. Stattdessen werde ich mit einer anderen Bibliothek abholen, um OpenCV ein Capture Video/Bilder zu füttern. Ich benutze OpenCV 2.2

0

cvSetCaptureProperty (Erfassung, CV_CAP_PROP_FRAME_WIDTH, WIDTH);

cvSetCaptureProperty (Erfassung, CV_CAP_PROP_FRAME_HEIGHT, HEIGHT);

cvQueryFrame (capture);

Das funktioniert nicht mit OpenCV 2.2, aber wenn Sie OpenCV 2.1 verwenden, wird es gut funktionieren!

5

-Code Ich habe endlich in Python arbeiten einmal Aaron Haun ich vor mit ihnen die Argumente der Set-Funktion zu definieren, wies darauf hin, benötigt.

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

Nur eine Information, die für Leute nützlich sein könnte, die Schwierigkeiten haben, die Standardaufnahmeauflösung (640 x 480) zu ändern! Ich habe ein solches Problem mit opencv 2.4.x und einer Logitech-Kamera ausprobiert ... und einen Workaround gefunden!

Das Verhalten I erfasst wird, dass das Standardformat Setup als Anfangsparameter ist, wenn Kameraerfassung gestartet (cvCreateCameraCapture) und alle Anforderungs Höhe oder Breite zu ändern:

cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, ... 

oder

cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, ... 

sind danach nicht möglich! Effektiv entdeckte ich mit Hinzufügung des Rückkehrfehlers der ioctl Funktionen, daß V4l2 Fahrer EBUSY für thet Anträge zurückbringt! Daher sollte man Abhilfe sein, den Standardwert zu ändern direkt in highgui/cap_v4l.cpp:

*#define DEFAULT_V4L_WIDTH 1280 // Originally 640* 

*#define DEFAULT_V4L_HEIGHT 720  // Originally 480* 

Danach habe ich neu kompiliert nur opencv ... und kam 1280 x 720 ohne Probleme zu bekommen! Natürlich sollte eine bessere Lösung darin bestehen, die Erfassung zu stoppen, die Parameter zu ändern und den Stream danach neu zu starten, aber ich bin nicht genug mit opencv dafür vertraut!

Ich hoffe, es wird helfen.

Michel BEGEY