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

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

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

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

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

OpenCV

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

C++

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

Q&A

3回答

1357閲覧

cv::VideoCapture capのcv::CAP_PROP_FRAME_WIDTHを表す定数3がシステムにどのように働くことで出力ウィンドウのサイズをいです。

carnage0216

総合スコア194

C

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

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

OpenCV

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

C++

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

0グッド

0クリップ

投稿2018/02/10 12:15

編集2018/02/10 12:47

❶(本題)

cv::VideoCapture cap(0); cap.set(cv::CAP_PROP_FRAME_WIDTH, 幅); cap.set(cv::CAP_PROP_FRAME_HEIGHT, 高さ);

に関して、cv::CAP_PROP_FRAME_WIDTH, 幅 cv::CAP_PROP_FRAME_HEIGHT, 高さがあります。

cv::CAP_PROP_FRAME_WIDTH, 幅の正体は定数の3、
cv::CAP_PROP_FRAME_HEIGHT, 高さの正体は定数の4とわかったのですが、この定数3と4が働くだけで出力ウィンドウの事前に設定したサイズで出力できる原理がイマイチわかりません。
定数が幅のサイズを制御する場所に働くのかななど。
(ここまでが本題)

なんだか、悩みに悩んでしまう憂鬱です。少し楽しんではいますが。
もちろん原理が理解できたら、出力できるウィンドウの大きさを変えるopencvなどの関数を改造したり新たな関数で出力ウィンドウのサイズの大きさなどを変えたいです。

しかし、まずは、上にも書いた通り
❷(本題)

cv::VideoCapture cap(0); cap.set(cv::CAP_PROP_FRAME_WIDTH, 幅); cap.set(cv::CAP_PROP_FRAME_HEIGHT, 高さ);

に関して、cv::CAP_PROP_FRAME_WIDTH, 幅 cv::CAP_PROP_FRAME_HEIGHT, 高さが定義されており、

cv::CAP_PROP_FRAME_WIDTH, 幅の正体は定数の3、
cv::CAP_PROP_FRAME_HEIGHT, 高さの正体は定数の4とわかったのですが、この定数3と4が働くだけでcv::CAP_PROP_FRAME_WIDTH, の幅と
cv::CAP_PROP_FRAME_HEIGHTの高さを設定して定数がコンパイル?あるいは別の何かに置き換えられて出力ウィンドウのサイズが変えられ理由であり原理が全くわかりません。定数が働くだけで幅のサイズが変わるわけないではないですか。何か勘違いしているかもしれませんが。
(ここまでが本題)

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

❸わたしはvideo captureに関与する幅や高さを表すのがなぜ定数などであり。なぜcv::CAP_PROP_FRAME_WIDTHの内容が定数3だけで語られており、defineやint main(int argc, char* argv[])などの標準関数でないのか不思議です。解説書を読んでも理解できますん。

❹あるいはただの定数という見栄えであり、cv::CAP_PROP_FRAME_WIDTHはハリボテで、実は他のヘッダファイルにcv::CAP_PROP_FRAME_WIDTH=const double width みたいな感じで定義されているんですかね。
詳しい方に細かい部分まで説明して頂けると大変ありがたいですし、勉強になります。
よろしくお願い致します。

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

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

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

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

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

guest

回答3

0

軽くソースを追ってみました。ある程度DirectShowの知識がないと理解できませんのであしからず。

映像のキャプチャーはサンプルグラバーフィルターを使っていました(フレームデータをメモリに取り込むだけならVMRやEMRは重すぎますね)。ストリームはNULLレンダラーで捨てています。

VideoCaptureクラスのsetメソッドでCAP_PROP_FRAME_WIDTHおよびCAP_PROP_FRAME_HEIGHTプロパティを設定すると、メンバ変数に設定値を保存してから内部クラスvideoInputstartメソッドが呼ばれます。

startメソッドではキャプチャー用のフィルターグラフを構築していますが、その過程でメンバ変数の設定値を元にAM_MEDIA_TYPE構造体に値をセットしてISampleGrabberインターフェイスのSetMediaTypeメソッドでフレームのフォーマットを設定しています。これにより、CAP_PROP_FRAME_WIDTH/CAP_PROP_FRAME_HEIGHTプロパティの設定がキャプチャー処理に反映されます。

あとはストリームがサンプルグラバーを通過するたびにコールバックが呼ばれてSetMediaTypeメソッドで設定されたフォーマットでフレームデータがバッファー領域に取り込まれ、最終的にVideoCaptureクラスのoperator >>Matオブジェクトに格納される、という仕組みです。

ちなみに、DirectShowはWindows固有の技術ですので、MacでOpenCVを使う場合は全く別の技術によって動作することになるでしょう(Macの事はよく知りませんが)。Linuxもまた然り。

そもそも、OpenCVはそのような面倒な手順やプラットフォーム毎の差異などの「余計なこと」に煩わされずに自分の作りたいことに集中できることが最大のメリット(のひとつ)であり、それを求めて皆がOpenCVを使うわけですが、何故中身の細かい動きにこだわるのか判りません。

あなたが何をしたいのか未だによく判らないのですが、OpenCVと同じような何かを作りたいのならOpenCVの仕組みを理解しないといけません。OpenCVの仕組みを理解したいのならOpenCVの使い方を理解しないといけません。OpenCVの使い方を理解したいのならOpenCVを使っていろいろプログラムを作って実際に動かして自分で確認してみるしかありません。そして、いろいろプログラムを作るにはそれなりにC/C++を使いこなせるようにならないといけません。

何度も繰り返している気がしますが、何事にも段階を踏むことが重要です。

投稿2018/02/11 02:15

catsforepaw

総合スコア5938

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

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

0

何度も書いてんだけど、VideoCapture にウィンドウ・サイズを設定する機能なんかありません。VideoCapture::set で設定するのはキャプチャするframeの大きさ。

cv::CAP_PROP_FRAME_HEIGHTの高さを設定して定数がコンパイル?あるいは別の何かに置き換えられて出力ウィンドウのサイズが変えられ理由であり原理が全くわかりません。

VideoCaputureの隠し関数 set_width(int w) /* frame幅を w にセットする */ があったとして、

VideoCapture::set(int command, int val) { if ( command == CAP_PROP_FRAME_WIDTH ) { set_width(val); } ... }

って書かれてるとしたら、納得する?

[追記]

OpenCV 3.4 のコードから VideoCapture::set() を追っかけてみた

C++

1bool VideoCapture::set(int propId, double value) 2{ 3 if (!icap.empty()) 4 return icap->setProperty(propId, value); 5 return cvSetCaptureProperty(cap, propId, value) != 0; 6}

さらに icap->setProperty は:

C++

1bool VideoCapture_DShow::setProperty(int propIdx, double propVal) 2{ 3 // image capture properties 4 bool handled = false; 5 switch (propIdx) 6 { 7 case CV_CAP_PROP_FRAME_WIDTH: 8 m_width = cvRound(propVal); // ← 幅をセットしてる現場を目撃! 9 handled = true; 10 break; 11 12 case CV_CAP_PROP_FRAME_HEIGHT: 13 m_height = cvRound(propVal); 14...

投稿2018/02/10 12:21

編集2018/02/10 14:43
episteme

総合スコア16614

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

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

carnage0216

2018/02/10 12:51

ちなみに、VideoCapture::set(int command, int val) { if ( command == CAP_PROP_FRAME_WIDTH ) { set_width(val); } ... }は実装できるのでしょうか?
episteme

2018/02/10 15:19 編集

納得できるなら、ナニが疑問なの? コード読めばいーじゃん!!! ...ざっくり読んでみたけど、おーむねそんなカンジやった(追記しといた)。
carnage0216

2018/02/10 15:18

やっと、CAP_PROP_FRAME_WIDTHの正体(標準関数)がわかりました。本当にどうもありがとうございます。
episteme

2018/02/10 15:20 編集

あなたの言う"標準関数"ってナニよ? ひょっとして標準関数っていうオレオレ語?
carnage0216

2018/02/10 15:44

えーと、載せていただいたプログラムより case CV_CAP_PROP_FRAME_WIDTH: m_width = cvRound(propVal); // ← 幅をセットしてる現場を目撃! handled = true; break; 以上は標準言語ではないのですか?何かと勘違いしていましたらすいません。
episteme

2018/02/10 15:45

標準言語ってナニよ? (なんかまた新しいコトバがでてきたぞ)
carnage0216

2018/02/10 15:46

私はコンパイラが元から持つ最小限のデータでコンパイラできるソースコードを標準言語だと入門書に書いてあったのですが。????
carnage0216

2018/02/10 15:46

あ、、、標準関数です
carnage0216

2018/02/10 15:47

ごめんなさい、お恥ずかしい間違いです。
episteme

2018/02/10 15:48

ごめん意味が分からん。しかも"標準関数"じゃなくなってるし。
carnage0216

2018/02/10 15:49

すいません。標準ライブラリ関数のことです。
episteme

2018/02/10 15:50

cvRoundが標準関数? ちがうよ。
carnage0216

2018/02/10 15:53

興奮して無責任なことを言ってしまいました。調べてきます。
episteme

2018/02/10 23:48

cvRoundが標準関数であったとしても、m_width = cvRound(propVal); は幅を m_width にセットした"だけ"であり、frameのキャプチャ時にm_widthがどう関与するのかは依然解明されてはいないけども。
carnage0216

2018/02/10 23:55

epistemeさん、本当にどうもありがとうございます。 本当に嬉しいです。
carnage0216

2018/02/11 00:06

え、ということは幅を決めたとして参照されないかもしれないってことですか?
episteme

2018/02/11 00:50 編集

知らんよ。set(なにを,どんだけ) が機能するからくりを読み解いただけ。 その後 cap >> frame した時点で設定された幅でcaptureするんでしょうけど。
guest

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

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

asm

2018/02/10 15:00

おっと、被った 環境に依存する面倒くさいところをライブラリが隠蔽してくれているので、 寝た子を起こすような事はやめるべき
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問