OpenCV でのカメラ キャプチャ解像度の向上
-
08-06-2019 - |
質問
私のC/C++プログラムでは、 OpenCV ウェブカメラから画像をキャプチャします。カメラ (ロジクール クイックカム IM) 解像度でキャプチャできます 320×240, 640×480 そして 1280x960. 。しかし、何らかの奇妙な理由で、OpenCV は解像度の画像を提供します 320×240 のみ。を使用して解像度を変更する呼び出し cvSetCaptureProperty() 他の解像度値では機能しません。Web カメラで可能な他の解像度で画像をキャプチャするにはどうすればよいですか?
解決 2
解決策はないようです。解像度は次まで上げることができます 640×480 を使用して このハック によって共有されました ライフベルト77. 。再現された詳細は次のとおりです。
に追加 ハイギ.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
};
現在は再建されています ハイギ.dll.
他のヒント
私は Windows で openCV 1.1pre1 を使用しています (Windows では、このバージョンの openCv ではデフォルトで 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 のウェブカメラでテストしました
私は以前 Linux で画像処理を行ったことがありますが、OpenCV の組み込みカメラ機能は (ご存知のとおり) 不完全だったのでスキップしました。
OS によっては、openCV 経由ではなく、通常のチャネル経由でハードウェアに直接アクセスするほうがうまくいく場合があります。Linux を使用している場合、video4linux または video4linux2 を使用すると、比較的簡単に USB Web カメラにアクセスでき、Firewire に libavc1394 を使用できます。デバイスと、従うサンプル コードの品質に応じて、1 ~ 2 時間以内に必要なパラメータでデバイスを実行できるようになります。
編集して以下を追加しました:Windows の場合はご自身で行ってください。それほど難しいことではないと思いますが、私はやったことがありません。
使用することを強くお勧めします ビデオ入力ライブラリ, 、あらゆる DirectShow デバイス (同時に複数のデバイスも含む) をサポートし、より構成可能です。OpenCV で再生するには 5 分かかります。
このチケットをチェックしてください:https://code.ros.org/trac/opencv/ticket/376
「解決策は、新しい libv4l ベースのラッパーを使用することです。
libv4l-dev をインストールします (Ubuntu ではこのように呼ばれます)。
cmake を再実行すると、「V4L/V4L2:」が表示されます。libv4lを使用する」
再実行してください。解像度を変更できるようになりました。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を使用しています
cvSetCaptureProperty(キャプチャ, CV_CAP_PROP_FRAME_WIDTH, WIDTH );
cvSetCaptureProperty(キャプチャ, CV_CAP_PROP_FRAME_HEIGHT, HEIGHT);
cvQueryFrame(キャプチャ);
これは OpenCV 2.2 では動作しませんが、OpenCV 2.1 を使用すると正常に動作します。
Windows プラットフォームを使用している場合は、DirectShow (IAMStreamConfig) を試してください。
http://msdn.microsoft.com/en-us/library/dd319784%28v=vs.85%29.aspx
Windows では、VideoInput ライブラリを使用してみます。http://robocraft.ru/blog/computervision/420.html
Windows (Win98 から WinXP SP3) では、OpenCV がカメラ アクセスに Microsoft の VFW ライブラリを使用することが多いことがわかりました。これの問題は、非常に遅いことが多く (たとえば、最大 15 FPS のフレーム キャプチャ)、バグが多いことです (そのため、cvSetCaptureProperty が機能しないことがよくあります)。幸いなことに、通常は他のソフトウェア (特に、簡単に入手できるデモ プログラムである「AMCAP」) で解像度を変更でき、OpenCV が使用する解像度に影響します。たとえば、AMCAP を実行して解像度を 640x480 に設定すると、その時点から OpenCV はデフォルトでその解像度を使用します。
ただし、「videoInput」ライブラリなどの別の Windows カメラ アクセス ライブラリを使用できる場合は、 http://muonics.net/school/spring05/videoInput/ 非常に効率的な DirectShow (DirectX の一部) を使用してカメラにアクセスします。または、プロ品質のカメラをお持ちの場合は、多くの場合、カメラにアクセスできるカスタム 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 ドライバーが返していることがわかりました。 エビジー 彼らのリクエストのために!したがって、回避策の 1 つは、 highgui/cap_v4l.cpp でデフォルト値を直接変更することです。
*#define DEFAULT_V4L_WIDTH 1280 // Originally 640*
*#define DEFAULT_V4L_HEIGHT 720 // Originally 480*
その後、再コンパイルしただけです opencv ...問題なく 1280 x 720 に到達しました。もちろん、より良い修正は、取得を停止し、パラメータを変更し、その後ストリームを再開することですが、それを行うには opencv に十分慣れていません。
それが役立つことを願っています。
ミシェル・ベギー
これを試して:
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);
それだけで十分なはずです!