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

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

ただいまの
回答率

90.50%

  • C#

    9064questions

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

  • C

    4543questions

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

  • C++

    4445questions

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

  • OpenCV

    1518questions

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

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

受付中

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,224

carnage0216

score 122

❶(本題)

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 みたいな感じで定義されているんですかね。
詳しい方に細かい部分まで説明して頂けると大変ありがたいですし、勉強になります。
よろしくお願い致します。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

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

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

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

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

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

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

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

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

+2

何度も書いてんだけど、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() を追っかけてみた

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

さらに icap->setProperty は:

bool VideoCapture_DShow::setProperty(int propIdx, double propVal)
{
    // image capture properties
    bool handled = false;
    switch (propIdx)
    {
    case CV_CAP_PROP_FRAME_WIDTH:
        m_width = cvRound(propVal); // ← 幅をセットしてる現場を目撃!
        handled = true;
        break;

    case CV_CAP_PROP_FRAME_HEIGHT:
        m_height = cvRound(propVal);
...

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/02/10 21:48

    納得できます。

    キャンセル

  • 2018/02/10 21:51

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

    キャンセル

  • 2018/02/10 22:01 編集

    納得できるなら、ナニが疑問なの? コード読めばいーじゃん!!!

    ...ざっくり読んでみたけど、おーむねそんなカンジやった(追記しといた)。

    キャンセル

  • 2018/02/11 00:18

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

    キャンセル

  • 2018/02/11 00:20 編集

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

    キャンセル

  • 2018/02/11 00:44

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

    キャンセル

  • 2018/02/11 00:45

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

    キャンセル

  • 2018/02/11 00:46

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

    キャンセル

  • 2018/02/11 00:46

    あ、、、標準関数です

    キャンセル

  • 2018/02/11 00:47

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

    キャンセル

  • 2018/02/11 00:48

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

    キャンセル

  • 2018/02/11 00:49

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

    キャンセル

  • 2018/02/11 00:50

    https://9cguide.appspot.com/r_lib.html

    以上のようなものです。

    キャンセル

  • 2018/02/11 00:50

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

    キャンセル

  • 2018/02/11 00:53

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

    キャンセル

  • 2018/02/11 08:48

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

    キャンセル

  • 2018/02/11 08:55

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

    キャンセル

  • 2018/02/11 09:06

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

    キャンセル

  • 2018/02/11 09:49 編集

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

    キャンセル

+2

軽くソースを追ってみました。ある程度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++を使いこなせるようにならないといけません。

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

VideoCapture::set
icapとは
icap(その2)

結果として
https://github.com/opencv/opencv/blob/05b15943d6a42c99e5f921b7dbaa8323f3c042c6/modules/videoio/src/cap_winrt_capture.cpp#L187
https://github.com/opencv/opencv/blob/05b15943d6a42c99e5f921b7dbaa8323f3c042c6/modules/videoio/src/cap_dshow.cpp#L3247

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/02/11 00:00

    おっと、被った

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

    キャンセル

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

  • C#

    9064questions

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

  • C

    4543questions

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

  • C++

    4445questions

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

  • OpenCV

    1518questions

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

  • トップ
  • C#に関する質問
  • cv::VideoCapture capのcv::CAP_PROP_FRAME_WIDTHを表す定数3がシステムにどのように働くことで出力ウィンドウのサイズをいです。