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

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

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

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

Python

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

受付中

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

t-moya
t-moya

総合スコア0

OpenCV

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

Python

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

1回答

0評価

0クリップ

190閲覧

投稿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()

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

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がでました!

まだ回答がついていません

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

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

ただいまの回答率
87.20%

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

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

質問する

関連した質問

同じタグがついた質問を見る

OpenCV

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

Python

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