質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

1回答

1294閲覧

OpenCV 録画した時間と出力された動画の長さの乖離

t-moya

総合スコア0

OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2022/06/22 08:45

OpenCVを用いてRasberry Pi 4にUSB接続したwebカメラから動画を撮影しようとしています。解像度を変更せず、デフォルトの640, 360で撮影したところ、問題なくスムーズな動画を得ることができました(実際の時間と同じ時間で録画できている)。一方で、capture.setやcv2.VideoWriterで以下のように1280, 720の解像度に変更すると10秒程度録画したとしても動画ファイルとしては数秒に圧縮され、早送りしたような動画になってしまいました。調べたところ、カメラの設定であるcapture.setと出力する動画の設定であるcv2.VideoWriterでのFPSに乖離があることでこのような早送り動画になっているとのことですが、同じFPS 30で設定しているにも関わらず、なぜこのようなことが起きているのかわかりません。webカメラを用いて高解像度の動画を撮影したいので、もし解決方法をご存知であれば、教えていただけると大変助かります。
よろしくお願いいたします。

import cv2 capture = cv2.VideoCapture(0, cv2.CAP_V4L) WIDTH = 1280 HEIGHT = 720 FPS = 30 capture.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc('M', 'J', 'P', 'G')) capture.set(cv2.CAP_PROP_FRAME_WIDTH, WIDTH) capture.set(cv2.CAP_PROP_FRAME_HEIGHT, HEIGHT) capture.set(cv2.CAP_PROP_FPS, FPS) fourcc = cv2.VideoWriter_fourcc('M','J','P','G') videoWriter = cv2.VideoWriter('test.avi', fourcc, 30, (1280, 720)) while (True): ret, frame = capture.read() videoWriter.write(frame) if cv2.waitKey(1) == 27: break capture.release() videoWriter.release() cv2.destroyAllWindows()

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

can110

2022/06/22 09:08

カメラがその解像度とFPSの組み合わせに対応していない可能性があります。 ret = capture.set(cv2.CAP_PROP_FPS, FPS)のようにしてTrueが返ってくるかを確認ください。
fana

2022/06/22 09:10

「カメラから画像を取得して,VideoWriterに書き込む」というループの動作速度が完璧に 30FPS に一致しない限りは,出力された動画を再生した際には > 早送り や逆に「スロー」に見えることになるでしょう.
t-moya

2022/06/22 11:55

ありがとうございます。 具体的には1分撮影しても7秒の動画になってしまっています。また、capture.set(cv2.CAP_PROP_FRAME_WIDTH, WIDTH)などで解像度を変更しない場合は、スムーズな動画が撮れているので、capture.setによる解像度の変更が乖離を生んでいるようですが、原因がわからないといったところです。今カメラが手元にないので、明日Trueか返ってくるかも確認してみようと思います。
jbpb0

2022/06/22 15:01 編集

while (True): のすぐ上に i = 0 を、 videoWriter.write(frame) のすぐ下に(インデントを合わせて) i = i + 1 を、コードの一番最後に print(i) を、それぞれ追加して実行したら、test.aviに何フレーム保存したのかが分かりますけど、それは 撮影時間(秒)x30 とだいたい合いますでしょうか?
t-moya

2022/06/23 00:17 編集

ありがとうございます。試しに60秒撮影したところ、最後に出力されたiは212でした。なので、60秒あたり212フレーム(3.5FPS)保存しており、動画の出力としてFPS30が設定されているとすると、212フレームが7秒に圧縮されているのは妥当そうです。なので、VideoWriterは問題なく、capture.setのFPSの設定がうまくいっていないようでした。ちなみに、解像度を下げていくと、iの値は上がっている様子でした(1280x720は444、640x360は1332)。 capture.setはTrueが返ってきており、print(capture.getcv2.CAP_PROP_FPS)としてもちゃんと30となっていました。ラズパイの処理速度の問題でしょうか?
fana

2022/06/23 01:11 編集

> capture.set(cv2.CAP_PROP_FPS, FPS) これにどれだけの意味があるのか? っていう話ですね. 仮に,この指定によって「カメラ装置側が 1/30 秒ごとに撮影する」動作になったとしても,「あなたのプログラムがカメラ装置側から撮影結果画像をもらう処理」の速度が1/30毎になるわけではないのだから.
fana

2022/06/23 01:13 編集

概ね,以下のようなイメージだと考えればわかりやすいかな. ・capture.read() は,カメラ装置側がその時点で持っている「最新の撮影画像」を取得する処理. ・カメラ装置側は「最新の撮影画像」を1/30秒毎に更新している. なので,capture.read() を実施しているプログラム側が「カメラが 1/30 毎に撮影している画像の全て」を得られるわけではない. プログラムのループ処理が「遅い」場合,「飛び飛びの」画像をサンプリングするだけになる.
fana

2022/06/23 01:19

(言うまでもない気がするけど)画像解像度により生じる違いは,画像サイズがでかいほど種々の処理に要する時間も増えるから前記「サンプリング」の頻度が遅くなってしまう,ということですね. サンプリング間隔に関しては「カメラからのキャプチャ」と「動画への書き出し」を別スレッドにすれば多少は緩和できる可能性はあるかもだけど,本質的な話は変わらない.
t-moya

2022/06/23 12:11

詳細に説明していただき、大変ありがとうございました。OpenCVでは難しいこと、よく理解できました。v4l2-ctlであれば30fpsが実現できそうなので、試してみたいと思います。
jbpb0

2022/06/23 12:28

私が紹介したWebサイトの二つ目の方の「エンコード性能の検証」で、ffmpeg使って条件を変えながら「fps」を測ってますので、それやってみてください それで「fps≒30」出ない条件なら、python+opencvでもダメです 「無圧縮」以外に1280x720で「fps≒30」出る条件はありますでしょうか?
t-moya

2022/06/23 12:39

アドバイスいただき、ありがとうございます。 紹介いただいたサイトを参考にffmpeg使って試してみたところ、1280x720 mjpeg(4CPU)でfps≒30がでました!1920x1080でもfps≒30がでました!
guest

回答1

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問