Linux用のC++/Qtプログラムを作成しようとしています。Webカメラから静止画像の写真を撮り、写真にいくつかの変換(トリミング、サイズ変更など)を行い、それをjpegファイルに保存します。
しかし、私はいくつかの問題に遭遇しました。主な問題は、標準のUVC(USBビデオデバイスクラス)Linuxドライバーが現在、直接静止画像のキャプチャをサポートしていないことです http://www.ideasonboard.org/uvc/ 。
したがって、静止画像をキャプチャするには2つの方法があります。カメラからのビデオストリームから1フレームを撮るか、デジタルポータブルカメラのように別の写真を撮ることができます。 2番目の方法はLinux uvcドライバーではサポートされていないため、最初の方法が唯一の方法です。ただし、問題は、ビデオストリームからフレームを取得する場合、写真のサイズをビデオプレビューウィンドウのビデオのサイズよりも大きくできないことです。したがって、2メガピクセルの写真を撮りたい場合は、1600x1200のサイズでビデオストリームを開始する必要があります。これは快適ではありません(少なくとも、Qtでは、ビデオストリームのサイズはビデオプレビューウィンドウのサイズに依存します)。
Linux 2 APIのビデオがあることは知っていますが、このタスクに役立つかもしれませんが、それを使用する方法がわかりません。現在gstreamerを学習していますが、これらのツールを使用して必要なことを行う方法がわかりません。
だから、私はどんな助けにも感謝します。 Linux、GStreamer、v4l2 API、およびその他のLinux固有のものを知っている人にとっては、それは難しい問題ではないと思います。
ちなみに、プログラムはウェブカメラロジクールC270 HDでのみ使用されます。
私を助けてください。これを行うのに役立つAPIまたはフレームワークがわかりません。ご存知かもしれません。
残念ながら、opencvのC4V2呼び出しは、UVCドライバーを使用して最初から試してみたどのカメラでも静止画像のキャプチャに機能しませんでした。
問題をデバッグするために、cコードを直接呼び出すcコードでこれを達成しようと試みてきました。
私は見つかったコードの例 here で遊んでいます。ビデオストリームからフレームをプルする方法を使用します。
あなたはそれをコンパイルすることができます:
gcc -O2 -Wall `pkg-config --cflags --libs libv4l2` filename.c -o filename
3つのlogitechカメラを使って実験しました。最高のものは、Logicool C910のようです。しかし、それでも重大な問題があります。
このコードを使用して同じタスクを実行しようとしたときに発生した問題を次に示します。
幅と高さが1920x1080に設定されていると、ほぼ常に機能します。
他の可能性をコマンドラインから直接クエリすると、たとえば次のようになります。
v4l2-ctl --list-formats-ext
そして、カメラがバッファを解放するのを待っているselectでハングする他の「利用可能な」より小さなサイズのいくつかを試します。
また、たとえば次のようにして、コマンドラインから他のサイズを直接設定しようとすると、
v4l2-ctl -v height=320 -v width=240 -v pixelformat=YUYV
次に確認してください
v4l2-ctl -V
正しいピクセルフォーマットが返されますが、多くの場合、正しいサイズではありません。
どうやら VCサイト に記載されているこのカメラはUVCであるため、v4l2との互換性は十分ではありません。他のカメラと同じように悪いと思います。私が試した他の2つもサイトに互換性があると記載されていましたが、問題はさらに深刻でした。
これを投稿した後、LogitechC910でさらにテストを行いました。他の誰かを助けてくれる場合に備えて、結果を投稿すると思いました。
上記のv4l2グラバーコードを、v4l2でクエリしたときにカメラがサポートしていると主張するすべての形式でテストするスクリプトを書きました。結果は次のとおりです。
640x480 => Hangs on clearing buffer
160x120 => Works
176x144 => Works
320x176 => Works
320x240 => Works
432x240 => Works
352x288 => Works
544x288 => Works
640x360 => Works
752x416 => Hangs on clearing buffer
800x448 => Hangs on clearing buffer
864x480 => Works
960x544 => Works
1024x576 => Works
800x600 => Works
1184x656 => Works
960x720 => Works
1280x720 => Works
1392x768 => Works
1504x832 => Works
1600x896 => Works
1280x960 => Works
1712x960 => Works
1792x1008 => Works
1920x1080 => Works
1600x1200 => Works
2048x1536 => Works
2592x1944 => Hangs on clearing buffer.
デフォルトの設定である640x480が機能しないことがわかりました。それが私やメッセージボードに投稿した他のほとんどのユーザーを悩ませていました。
ビデオフレームを取得しているため、起動時に最初のフレームを取得すると、露出が正しくない場合があります(多くの場合、黒またはそれに近い)。これは、ビデオカメラとして使用されているため、最初のフレームを気にせずに露出を調整するためだと思います。これも私と最初のフレームを黒または黒に近いと思った他の人を捕らえ、それをある種のエラーだと思ったと思います。後のフレームには正しい露出があります
上記の地雷を回避し、すべてのエラーメッセージを無視すると、このカメラでpythonラッパーを使用したopencvが正常に動作することがわかります。エラーメッセージは、カメラがv4l2を受け入れる間の事実によるものです。コマンドは正しく応答しないので、幅を設定すると実際には正しく設定されますが、不正な幅で応答します。
pythonラッパーを使用してopencvで実行するには、次のようにします。
import cv2
import numpy
cap = cv2.VideoCapture(0) #ignore the errors
cap.set(3, 960) #Set the width important because the default will timeout
#ignore the error or false response
cap.set(4, 544) #Set the height ignore the errors
r, frame = cap.read()
cv2.imwrite("test.jpg", frame)
**Download And Install 'mplayer'**
mplayer -vo png -frames 1 tv://
mplayer -vo png -frames 1 tv://
カメラの準備がまだ整っていないため、緑色の画面が出力される場合があります。
mplayer -vo png -frames 2 tv://
フレーム数を増やして、カメラが正しい画像を提供する数を選択できます。
このプログラムはどうですか?
#include<opencv2/opencv.hpp>
using namespace cv;
int main()
{
VideoCapture webcam;
webcam.open(0);
Mat frame;
char key;
while(true)
{
webcam >> frame;
imshow("My Webcam",frame);
key = waitKey(10);
if(key=='s')
break;
}
imwrite("webcam_capture.jpg", frame);
webcam.release();
return 0;
}
これにより、ウェブカメラで許可されている最大サイズの画像がキャプチャされます。 Qtを使用して、効果を追加したり、キャプチャした画像のサイズを変更したりできます。そして、OpenCVはQtと統合するのが非常に簡単です:)