2008-08-18 134 views
50

在我的C/C++程序中,我使用OpenCV從我的網絡攝像頭捕捉圖像。相機(Logitech QuickCam IM)可以分辨率拍攝320x240,640x4801280x960。但是,由於一些奇怪的原因,OpenCV僅給我提供分辨率爲320x240的圖像。調用更改分辨率使用cvSetCaptureProperty()與其他分辨率值不起作用。如何通過網絡攝像頭捕捉其他分辨率的圖像?在OpenCV中增加相機捕捉分辨率

+0

注:「決議」一詞的共同濫用是指它在image.This像素數爲標準,而不是如何不同的形容。分辨率與像素的大小密切相關,而不是其數量。您可以使用分辨率較差的10MP圖像或高分辨率的一百萬像素。即使是足夠幸運的OpenCV文檔也不會犯這個錯誤。事實上,如果您例如訪問http://docs.opencv.org/modules/superres/doc/super_resolution.html並查看底部的參考資料,您會看到圖像分辨率與像素數目明顯不同。 – rbaleksandar 2014-04-29 10:43:54

回答

15

似乎沒有解決方案。分辨率可以提高到640x480使用this hack共享lifebelt77。下面是詳細信息轉載:

添加到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 

添加功能icvSetPropertyCAM_VFWcvcap.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; 
} 

和編輯captureCAM_VFW_vtable如下所示:

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

現在重建highgui.dll

+0

此方法的分辨率爲640x480? – 2012-04-05 01:25:42

5

我已經在linux中完成了圖像處理,並跳過了OpenCV內置的相機功能,因爲它(如您所發現的)不完整。

根據你的操作系統,你可能會有更多的運氣直接通過正常的渠道,而不是通過openCV硬件。如果您使用的是Linux,video4linux或video4linux2應該讓您可以輕鬆訪問USB攝像頭,並且您可以使用libavc1394進行Firewire。根據設備和您遵循的示例代碼的質量,您應該可以在一兩個小時內使設備運行所需的參數。

編輯添加:如果您的Windows是你自己的。我想這不是更難,但我從來沒有做過。

+0

我不知道我們怎麼能在Windows中做到這一點? – Abc 2017-09-04 11:52:18

5

我強烈建議使用VideoInput lib,它支持任何DirectShow設備(甚至同時支持多個設備)並且更易於配置。您將花費五分鐘時間來使用OpenCV。

41

我在Windows下使用openCV 1.1pre1(視頻輸入庫默認使用此版本的windows下的openCv)。

使用這些說明,我可以設置相機分辨率。請注意,我將調用舊的cvCreateCameraCapture而不是cvCaptureFromCam。

capture = cvCreateCameraCapture(cameraIndex); 

cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 640); 

cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 480); 


videoFrame = cvQueryFrame(capture); 

我已經與羅技,信託測試它和飛利浦網絡攝像頭

+1

對我來說也適用於OpenCV 1.1,我推薦這是被接受的答案。 – 2009-07-16 23:32:43

+0

是的,我確認這對我也適用。目前接受的解決方案是沒有必要的。 – hoju 2009-10-13 05:13:06

+0

文檔說這不支持,但它甚至可以在高清分辨率下工作。但是,如果請求的分辨率無法從相機獲得,它會默默回退默認分辨率。目前接受的解決方案是沒有必要的。 – Nestor 2010-03-09 01:25:12

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

應該足以!

-1

試試這個:

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

檢查這張票了: https://code.ros.org/trac/opencv/ticket/376

「的解決方案是使用較新的基於libv4l-包裝

  1. 安裝libv4l-DEV(。這就是它在Ubuntu中的稱呼)

  2. rerun cmake,你會看到「V4L/V4L2:Using libv4l」

  3. rerun make。現在分辨率可以改變。以「內置iSight對MBP。

測試此使用Ubuntu固定對我來說,可能對你藏漢工作。

0

我發現,在Windows(在Win98下到的WinXP SP3),OpenCV的意志經常使用微軟的VFW庫進行相機訪問,問題在於它通常很慢(比如說最大幀數爲15幀捕獲)和bug(因此爲什麼cvSetCaptureProperty通常不起作用)。幸運的是,通常你可以改變(特別是「AMCAP」,這是一個容易獲得的演示程序),它將影響OpenCV將使用的分辨率,例如,您可以運行AMCAP將分辨率設置爲640x480,然後OpenCV將使用那是默認的點起!

但是,如果您可以使用不同的Windows相機訪問庫,例如使用非常高效的DirectShow(DirectX的一部分)訪問相機的「videoInput」庫http://muonics.net/school/spring05/videoInput/。或者,如果您擁有專業品質的相機,那麼通常會附帶一個自定義API,以便您訪問相機,並且可以使用該API快速訪問,並可以更改分辨率和其他許多功能。

4

我使用Debian和Ubuntu,我有同樣的問題,我無法使用CV_CAP_PROP_FRAME_WIDTHCV_CAP_PROP_FRAME_HEIGHT改變視頻輸入的分辨率

我發現原因是缺少一個庫。 我安裝了lib4l-dev通過突觸,重建 OpenCV和問題解決了!

2

我發佈此確保沒有其他人浪費時間在此setproperty函數。我花了2天的時間看到沒有任何東西可以工作。所以我挖出了代碼(我第一次安裝了這個庫)。這就是實際發生的事情 - cvSetCaptureProperty,在CvCapture類中調用setProperty,並注意setProperty什麼也不做。它只是返回false。 相反,我會拿起另一個庫來爲OpenCV提供一個捕捉視頻/圖像。我正在使用OpenCV 2。2

0

cvSetCaptureProperty(capture,CV_CAP_PROP_FRAME_WIDTH,WIDTH);

cvSetCaptureProperty(capture,CV_CAP_PROP_FRAME_HEIGHT,HEIGHT);

cvQueryFrame(capture);

這不適用於OpenCV 2.2,但如果您使用OpenCV 2.1,它將正常工作!

5

代碼我終於在Python工作的一次亞倫煥指出我需要使用之前定義一組函數的參數。

#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

只是一個信息,可能是有價值的人有困難改變默認捕獲分辨率(640×480)!我用opencv 2.4.x和一個Logitech相機試驗了自己的問題......並找到了一種解決方法!

我檢測到的行爲是默認格式是設置爲初始參數時相機捕獲開始時(cvCreateCameraCapture),並改變高度或寬度的所有請求:

cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, ... 

cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, ... 
之後不可能有

!實際上,我發現添加ioctl函數的返回錯誤,V4l2驅動程序正在返回EBUSY的請求! 因此,一個解決辦法應該是直接在highgui/cap_v4l.cpp更改默認值:

*#define DEFAULT_V4L_WIDTH 1280 // Originally 640* 

*#define DEFAULT_V4L_HEIGHT 720  // Originally 480* 

在那之後,我只是重新編譯OpenCV的 ...抵達獲得1280×720,沒有任何問題!當然,更好的解決方法應該是停止採集,更改參數,然後重新啓動流,但是我對opencv不夠熟悉!

希望它會有所幫助。

米歇爾BEGEY