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

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

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

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

OpenCV

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

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

1回答

13221閲覧

OpenCVでカメラからフレームを取得するのを高速化したい

nuiri1343

総合スコア54

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

OpenCV

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

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

3クリップ

投稿2018/09/05 06:46

前提・実現したいこと

USBカメラから画像を取得するプログラムを書いております。
できるだけ誤差なく指定したFPS通りに撮影、保存がしたいなと考えております。

もちろん、誤差を0にするのは不可能であるということは承知しております。
下記のプログラムは、カメラからフレームを取得するプログラムです。
この後、取得した画像をファイルとして保存する機能を追記するつもりです。

ですが、現時点で cap >> frameの行にて時間がかかりすぎています。
ここをできるだけ速くフレームの取得ができるようにするには、何かアイデアはありませんでしょうか。

該当のソースコード

C++

1#include"main.h" 2 3#define FPS 20 4 5 6int main(void) { 7 8 9 VideoCapture cap(0); //カメラ用変数 10 Mat frame; //画像用変数 11 if (!cap.isOpened()) { //カメラが認識できなかった場合 12 return -1; 13 } 14 15 cap.set(CV_CAP_PROP_FRAME_WIDTH, 640); //撮影画像サイズ(幅) 16 cap.set(CV_CAP_PROP_FRAME_HEIGHT, 480); //撮影画像サイズ(高さ) 17 18 19 LARGE_INTEGER freq, start, now; 20 if (!QueryPerformanceFrequency(&freq)) { //時間の単位取得 21 return -2; //失敗 22 } 23 if (!QueryPerformanceCounter(&start)) { //開始時間取得 24 return -2; //失敗 25 } 26 27 double fpsCounter = 1.0; //撮影トリガー用変数 28 29 while (1) { 30 31 if (!QueryPerformanceCounter(&now)) { //現在時間取得 32 return -3; //失敗 33 } 34 double time = (double)(now.QuadPart - start.QuadPart) / freq.QuadPart; //経過時間算出 35 36 if (time >= fpsCounter) { //fpsCounter以上の時間が経過していた場合撮影を行う 37 printf("%f(%f)\n", time,time-fpsCounter); //撮影時の経過時間,と誤差を標準出力 38 39 cap >> frame; //カメラから画像取得 40 41 //imshow("", frame); //画像を画面出力 42 fpsCounter += 1.0 / FPS; //カウンター更新 43 } 44 45 46 if (waitKey(1) == 0x1b) //Escキーが押されたら終了 47 break; 48 49 } 50 51 return 0; 52}

補足情報(FW/ツールのバージョンなど)

OpenCV-3.4.2
VisualStudio2017

OS:Windows10
CPU:Core i7-8700K
メモリ:DDR4 8GB×2
GPU:GTX 1060 6GB

どうかよろしくお願いいたします。

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

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

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

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

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

guest

回答1

0

事前に確認したいのですが

1.OpenCVのドキュメントは見ていますか?

2.ビデオカメラにおける「トリガーモード」という考え方は理解してますか?

3.ソースを見る限り、cap>>frameをタイマーで挟んで時間を計測してないようですが、
前後でQueryPerformanceCounterを呼んで差を出した場合どのくらいの値になりますか?

投稿2018/09/05 16:49

yominet

総合スコア187

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

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

nuiri1343

2018/09/17 04:41

1:初心者でそれが何のことかよくわからないのですが、多分見ていないと思います。申し訳ありません。 2:トリガーモードとはなんでしょうか。理解できてないと思います。ごめんなさい 3:やってみたところ、十分な明るさで、且つ動くもののない動画の時は0.01秒~0.02秒でしたが、動くものが入ると途端に0.4秒~1秒程になります。カメラに物体をものすごく近づけたりすると3秒程になりますが、これは暗いからでしょうか。
ttb

2018/09/19 15:52 編集

2.「カメラ トリガーモード」あたりで検索すると出てくるようです。何も気にせず使えば「トリガーなし」がデフォルトのカメラは多そうです? 3.その動作から推測するに、そのカメラは、フレームが固定された間隔(例えば20FPSなら0.05秒)ごとに出てくるのではなく、撮影が終わり次第フレームが出力されるようですね。 OpenCVのVideoCaptureクラスの cap>>frame は、次のフレームが来るまで待つ動作を行います(さすがに連続30秒くらい来ないとタイムアウトしたかも)。 質問主さんが使われているカメラは、周囲が暗いと1フレームの撮影に時間がかかるカメラなのでしょう。私のイメージでは、ほとんどの動画用カメラは指定したFPS通りに画像が出てくると思っているのですが、質問主さんの使われているカメラはそうなっていないようです。 結論的には、カメラの設定を変えるか、そのような高速出力に対応したカメラを用意する必要がありそうです。 (若干余談ですが、周囲が暗いと1回の撮影が長くなるのは、静止画カメラでは当たり前の話です。画面の明るさは、周囲の光の強さ×時間 で決まるので、周囲が暗いと一定の光量が得られるまで時間がかかるので、撮影時間が長くなります。) (なお、人間の目は、光の強さに関しては非常に高性能なので、結構暗い所でも十分な光量が得られて物体が見えますが、動画用カメラのように1フレームあたりの時間は決まっているようで、あまりに暗すぎると十分な光量が得られず、暗くて見えないようです。)
Wind

2018/09/19 16:52

補足情報に使用しているUSBカメラの型番が欲しいところですね。
yominet

2018/09/25 15:07

公式ドキュメント https://docs.opencv.org/3.4.2/ cv::VideoCapture class https://docs.opencv.org/3.4.2/d8/dfe/classcv_1_1VideoCapture.html cv::VideoCapture::setで設定できる項目(使用するハード、API等によって対応してるかどうかは変わる) https://docs.opencv.org/3.4.2/d4/d15/group__videoio__flags__base.html#gaeb8dd9c89c10a5c63c139bf7c4f5704d この中に cv::VideoCaptureProperties::CAP_PROP_AUTO_EXPOSURE があるので、これをOFFにすることができれば、自動露出は停止できるかもしれません トリガーモードについて ttbさんがすでに触れていますが、動画撮影では常にとり続けているため cap >> frame; を、「ループ内で時間を測り、正しいタイミングで呼び出す」意味はありません
Wind

2018/09/25 16:23

>(使用するハード、API等によって対応してるかどうかは変わる) ここが一番大事でしょう。 ハードが対応していなかったら、ソフトで何をやっても無理です。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問