私は、Webカメラから写真を撮ることができるコマンドラインツールを探しています(できるだけ早く)、標準出力に書き込みます。また、入力フォーマット、解像度、出力フォーマットなどの設定ができるようにしたいと思います。
私の最初の試みはffmpegでした:
ffmpeg -f video4linux2 -video_size 1920x1080 -input_format yuyv422 -i /dev/video0 -f image2 -frames:v 1 -qscale:v 2 pipe:1
ただし、これには2つの欠点があります。
画像がstdoutに書き込まれるまで約3秒かかります。これは、ウェブカメラを初期化する必要があるためと思われます。
この方法で撮影された写真はかなり暗いです。おそらく、ウェブカメラは明るさなどを調整するためにビュービデオフレームをキャプチャする必要があります。
私の次のアイデアは、ウェブカメラからビデオフレームを継続的にキャプチャし(つまり、「ウェブカメラをアクティブに保つ」)、これらのビデオフレームをどこかにストリーミングしてどこかに、シングルを取得することですビデオフレームをオンデマンドで画像に変換します。しかし、私はこれを行う方法を知りません(そしてより良い方法があるかどうか)。
編集:画像をstdoutに書き込む1回限りのコマンドが必要なので、httpサーバーで使用してhttpGETリクエストを処理できます。写真を撮ると機械の機械的プロセスが妨げられるため、迅速に行う必要があります。
私のウェブカメラの場合、fswebcam
は0.5秒未満で写真を撮ります。
$ time fswebcam test1.jpg
...
real 0m0.491s
user 0m0.024s
sys 0m0.000s
Stdoutに書き込んでから保存するには、少し時間がかかります。
$ time fswebcam - > test2.jpg
...
real 0m0.538s
user 0m0.029s
sys 0m0.000s
n秒(--loop n
)ごとに画像を撮ることもできます。これが必要な場合(説明していませんが理由できるだけ速くしたい、およびループが役立つかどうか、またはどのように役立つか)。
fswebcam --list-controls
で表示されるコントロールを使用して、画像を明るくしたり、コントラストなどを調整したりできます。
これを実装したいRaspberryPiでは、FPSがカメラがサポートする値の半分に減少するため(FPSが低い=次のビデオフレームまでの遅延が増える可能性があるため)、最適ではありませんが、自分で1つの可能な解決策を見つけました。画像として抽出されます)。
Ffmpegを使用して、ビデオデータを/ dev/video0のハードウェアデバイスから v4l2-loopback デバイスの/ dev/video1にコピーします。この方法では、ffmpegが/ dev/video0でカメラを読み取っているので、カメラはアクティブのままですが、ffmpegの別のインスタンスを使用して/ dev/video1から画像を抽出できます。
Raspbian GNU/Linux 9(ストレッチ)にv4l2-loopbackをインストールするには:
apt-get install raspberrypi-kernel-headers
( Re:カーネルヘッダーのインストール方法 )apt-get install v4l2loopback-dkms
( v4l2-ループバック分布 )modprobe v4l2loopback
またはより多くのデバイスでmodprobe v4l2loopback devices=2
( v4l2-loopback run )ビデオを/ dev/video0から/ dev/video1にコピーするには:
ffmpeg -f video4linux2 -video_size 1920x1080 -input_format yuyv422 -i /dev/video0 -codec copy -f video4linux2 /dev/video1
私のカメラはmjpegとyuyv422の形式をサポートしていますが、ループバックデバイスにコピーできるのは「raw」形式のみなので、yuyv422を使用する必要があります。カメラはyuyv422および1920x1080で最大6 fpsをサポートしますが、Raspberry Pi 2モデルBはループバックデバイスに約3 fpsをコピーすることしかできません。
これで、質問ですでに説明したコマンドを使用して、JPEGとして画像を抽出できます。
ffmpeg -f video4linux2 -video_size 1920x1080 -input_format yuyv422 -i /dev/video1 -f image2 -frames:v 1 -qscale:v 2 pipe:1
またはビットマップとして:
ffmpeg -f video4linux2 -video_size 1920x1080 -input_format yuyv422 -i /dev/video1 -c:v bmp -f image2 -pix_fmt bgr24 -frames:v 1 pipe:1
ループバックデバイスからこれらのコマンドを読み取ると、画像は暗くならず、標準出力に送信するのに約1.3秒(JPEG)または1.1秒(ビットマップ)かかります。