私のC/C ++プログラムでは、OpenCVを使用してWebカメラから画像をキャプチャしています。カメラ(Logitech QuickCam IM)は、320x240、640x480、および1280x960の解像度でキャプチャできます。しかし、奇妙な理由で、OpenCVは解像度320x240の画像しか提供しません。他の解像度値でcvSetCaptureProperty()を使用して解像度を変更するための呼び出しは、機能しません。ウェブカメラで可能な他の解像度で画像をキャプチャするにはどうすればよいですか?
15 に答える
Windows で openCV 1.1pre1 を使用しています (このバージョンの Windows では、デフォルトで videoinput ライブラリが使用されます)。
これらの手順で、カメラの解像度を設定できます。cvCaptureFromCam の代わりに古い cvCreateCameraCapture を呼び出すことに注意してください。
capture = cvCreateCameraCapture(cameraIndex);
cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH, 640 );
cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT, 480 );
videoFrame = cvQueryFrame(capture);
Logitech、Trust、Philips のウェブカメラでテストしました
解決策はないようです。lifebelt77が共有するこのハックを使用して、解像度を640x480に上げることができます。再現された詳細は次のとおりです。
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_VFWを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;
}
次のように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を再構築しました。
私は以前にLinuxで画像処理を行ったことがありますが、OpenCVに組み込まれているカメラ機能は(ご存知のとおり)不完全であるためスキップしました。
OSによっては、openCVではなく、通常のチャネルを介してハードウェアに直接アクセスできる場合があります。Linuxを使用している場合、video4linuxまたはvideo4linux2を使用すると、USB Webカメラに比較的簡単にアクセスでき、firewireにlibavc1394を使用できます。デバイスと従うサンプルコードの品質に応じて、1〜2時間で必要なパラメーターを使用してデバイスを実行できるようになります。
追加するために編集:そのWindowsの場合、あなたはあなた自身です。それほど難しいことではないと思いますが、一度もやったことはありません。
VideoInput libを使用することを強くお勧めします。これは、任意の DirectShow デバイス (同時に複数のデバイスも) をサポートし、より構成可能です。OpenCV でプレイするのに 5 分かかります。
このチケットをチェックしてください: https://code.ros.org/trac/opencv/ticket/376
「解決策は、新しい libv4l ベースのラッパーを使用することです。
libv4l-dev をインストールします (これが Ubuntu での呼び方です)
cmake を再実行すると、「V4L/V4L2: Using libv4l」が表示されます。
make を再実行します。解像度を変更できるようになりました。MBP のビルトイン isight でテスト済みです。」
これにより、Ubuntuを使用して修正されたので、あなたにも役立つかもしれません。
Aaron Haun が set 関数の引数を使用する前に定義する必要があると指摘した後、ようやく 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")
私はdebianとubuntuを使用していますが、同じ問題があり、CV_CAP_PROP_FRAME_WIDTHとCV_CAP_PROP_FRAME_HEIGHTを使用してビデオ入力の解像度を変更できませんでした
その理由はライブラリの欠落であることがわかりました。シナプスを介してlib4l-devをインストールし、OpenCVを再構築しましたが、問題は解決しました!
この setproperty 関数で他の誰も時間を無駄にしないようにするために、これを投稿しています。これに 2 日間費やして、何も機能していないように見えることを確認しました。そこで、コードを掘り出しました (最初にライブラリをインストールしました)。これが実際に起こることです - cvSetCaptureProperty は CvCapture クラス内で setProperty を呼び出しますが、setProperty は何もしません。false を返すだけです。代わりに、別のライブラリを使用して、OpenCV にキャプチャ ビデオ/画像をフィードします。OpenCV 2.2 を使用しています
Windows プラットフォームを使用している場合は、DirectShow (IAMStreamConfig) を試してください。
http://msdn.microsoft.com/en-us/library/dd319784%28v=vs.85%29.aspx
Windows (Win98 から WinXP SP3 まで) では、OpenCV はカメラへのアクセスに Microsoft の VFW ライブラリを使用することがよくあります。これに関する問題は、多くの場合、非常に遅く (最大 15 FPS のフレーム キャプチャなど)、バグが多いことです (そのため、cvSetCaptureProperty が機能しないことがよくあります)。幸いなことに、通常は他のソフトウェア (特に、簡単に入手できるデモ プログラムである "AMCAP") で解像度を変更でき、OpenCV が使用する解像度に影響します。たとえば、AMCAP を実行して解像度を 640x480 に設定すると、それ以降、OpenCV はデフォルトでそれを使用します。
ただし、非常に効率的な DirectShow (DirectX の一部) を使用してカメラにアクセスする「videoInput」ライブラリhttp://muonics.net/school/spring05/videoInput/など、別の Windows カメラ アクセス ライブラリを使用できる場合。または、プロ品質のカメラを持っている場合は、カメラにアクセスできるカスタム API が付属していることが多く、それを使用して、解像度やその他の多くのことを変更する機能を備えた高速アクセスを行うことができます。
デフォルトのキャプチャ解像度 (640 x 480) を変更するのが難しい人にとって、価値のある情報が 1 つだけあります。私は opencv 2.4.x と 1 台の Logitech カメラでこのような問題を自分で実験しました ...そして 1 つの回避策を見つけました!
私が検出した動作は、カメラ キャプチャが開始されたとき (cvCreateCameraCapture) にデフォルトの形式が初期パラメータとして設定され、高さまたは幅の変更をすべて要求することです。
cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH, ...
また
cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT, ...
後でできません!事実上、ioctl 関数のリターン エラーを追加して、V4l2 ドライバーが要求に対してEBUSYを返していることを発見しました。したがって、回避策の 1 つは、 highgui/cap_v4l.cpp でデフォルト値を直接変更することです。
*#define DEFAULT_V4L_WIDTH 1280 // Originally 640*
*#define DEFAULT_V4L_HEIGHT 720 // Originally 480*
その後、opencvを再コンパイルしたところ...問題なく1280 x 720に到達しました!もちろん、取得を停止し、パラメータを変更し、その後ストリームを再開する方が適切な修正方法ですが、私はそれを行うための opencv に精通していません!
それが役立つことを願っています。
ミシェル・ベジェ
cvSetCaptureProperty( キャプチャ, CV_CAP_PROP_FRAME_WIDTH, WIDTH );
cvSetCaptureProperty(キャプチャ、CV_CAP_PROP_FRAME_HEIGHT、HEIGHT);
cvQueryFrame(キャプチャ);
これは OpenCV 2.2 では機能しませんが、OpenCV 2.1 を使用すると問題なく機能します。
Windows では、VideoInput ライブラリを使用してみてください: http://robocraft.ru/blog/computervision/420.html
これを試して:
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);
十分なはずです!