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

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

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

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

C

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

OpenCV

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

OS

OS(オペレーティングシステム)は、システムソフトウェアの一種であり、一般的に、ハードウェアを直接的に管理・操作する最も中心的な機能を有するソフトウェアがオペレーティングシステムとして呼ばれます。

Q&A

解決済

2回答

10659閲覧

cv::VideoCapture capのcv::CAP_PROP_FRAME_WIDTHの中身とどのようにPCのシステムに働くのか知りたいです。

carnage0216

総合スコア194

Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

C

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

OpenCV

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

OS

OS(オペレーティングシステム)は、システムソフトウェアの一種であり、一般的に、ハードウェアを直接的に管理・操作する最も中心的な機能を有するソフトウェアがオペレーティングシステムとして呼ばれます。

0グッド

0クリップ

投稿2018/02/09 09:51

編集2018/02/09 12:29
cv::VideoCapture cap(0); cap.set(cv::CAP_PROP_FRAME_WIDTH, 幅); cap.set(cv::CAP_PROP_FRAME_HEIGHT, 高さ);

はopencvから提供されたソースコードです。出力ウィンドのサイズを変える働きをします。
以上のソースコードに関しての質問なのですが、載せましたプログラム

* eye-tracking.cpp: * Eye detection and tracking with OpenCV * * This program tries to detect and tracking the user's eye with webcam. * At startup, the program performs face detection followed by eye detection * using OpenCV's built-in Haar cascade classifier. If the user's eye detected * successfully, an eye template is extracted. This template will be used in * the subsequent template matching for tracking the eye. */ #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/objdetect/objdetect.hpp> cv::CascadeClassifier face_cascade; cv::CascadeClassifier eye_cascade; /** * Function to detect human face and the eyes from an image. * * @param im The source image * @param tpl Will be filled with the eye template, if detection success. * @param rect Will be filled with the bounding box of the eye * @return zero=failed, nonzero=success */ int detectEye(cv::Mat& im, cv::Mat& tpl, cv::Rect& rect) { std::vector<cv::Rect> faces, eyes; face_cascade.detectMultiScale(im, faces, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, cv::Size(30,30)); for (int i = 0; i < faces.size(); i++) { cv::Mat face = im(faces[i]); eye_cascade.detectMultiScale(face, eyes, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, cv::Size(20,20)); if (eyes.size()) { rect = eyes[0] + cv::Point(faces[i].x, faces[i].y); tpl = im(rect); } } return eyes.size(); } /** * Perform template matching to search the user's eye in the given image. * * @param im The source image * @param tpl The eye template * @param rect The eye bounding box, will be updated with the new location of the eye */ void trackEye(cv::Mat& im, cv::Mat& tpl, cv::Rect& rect) { cv::Size size(rect.width * 2, rect.height * 2); cv::Rect window(rect + size - cv::Point(size.width/2, size.height/2)); window &= cv::Rect(0, 0, im.cols, im.rows); cv::Mat dst(window.width - tpl.rows + 1, window.height - tpl.cols + 1, CV_32FC1); cv::matchTemplate(im(window), tpl, dst, CV_TM_SQDIFF_NORMED); double minval, maxval; cv::Point minloc, maxloc; cv::minMaxLoc(dst, &minval, &maxval, &minloc, &maxloc); if (minval <= 0.2) { rect.x = window.x + minloc.x; rect.y = window.y + minloc.y; } else rect.x = rect.y = rect.width = rect.height = 0; } int main(int argc, char** argv) { // Load the cascade classifiers // Make sure you point the XML files to the right path, or // just copy the files from [OPENCV_DIR]/data/haarcascades directory face_cascade.load("haarcascade_frontalface_alt2.xml"); eye_cascade.load("haarcascade_eye.xml"); // Open webcam cv::VideoCapture cap(0); // Check if everything is ok if (face_cascade.empty() || eye_cascade.empty() || !cap.isOpened()) return 1; // Set video to 320x240 cap.set(CV_CAP_PROP_FRAME_WIDTH, 320); cap.set(CV_CAP_PROP_FRAME_HEIGHT, 240); cv::Mat frame, eye_tpl; cv::Rect eye_bb; while (cv::waitKey(15) != 'q') { cap >> frame; if (frame.empty()) break; // Flip the frame horizontally, Windows users might need this cv::flip(frame, frame, 1); // Convert to grayscale and // adjust the image contrast using histogram equalization cv::Mat gray; cv::cvtColor(frame, gray, CV_BGR2GRAY); if (eye_bb.width == 0 && eye_bb.height == 0) { // Detection stage // Try to detect the face and the eye of the user detectEye(gray, eye_tpl, eye_bb); } else { // Tracking stage with template matching trackEye(gray, eye_tpl, eye_bb); // Draw bounding rectangle for the eye cv::rectangle(frame, eye_bb, CV_RGB(0,255,0)); } // Display video cv::imshow("video", frame); } return 0; }

の91~93行目の

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


プログラムのヘッダファイル
<opencv2/imgproc/imgproc.hpp>
<opencv2/highgui/highgui.hpp>
<opencv2/objdetect/objdetect.hpp>のいずれかにcv::CAP_PROP_FRAME_WIDTHとcv::CAP_PROP_FRAME_HEIGHTの定義などが標準関数で書いてあるのでしょうか?

コンパイルする際に標準関数でないとコンパイル出来ないような気もしますが。

もう一つ質問があるのですが、以上に書いた

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

がWindowsのウィンドの大きさに関与したシステムのデータに働くため出力ウィンドのサイズを変えることができるのでしょうか?

長文ですが、どうかよろしくお願いします。

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

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

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

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

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

yumetodo

2018/02/10 09:23

ところでhttps://ja.stackoverflow.com/questions/41614/opencv%e3%81%ae%e9%96%a2%e6%95%b0cv-cap-prop-frame-height%e3%81%ae%e4%b8%ad%e8%ba%ab%e3%81%8c%e7%9f%a5%e3%82%8a%e3%81%9f%e3%81%84%e3%81%a7%e3%81%99 でマルチポストされていませんか?
episteme

2018/02/10 15:30

↑ うわー...答える気が失せたわ。
carnage0216

2018/02/10 23:06 編集

はい、わたしが投稿したものす。知りたいという好奇心ゆえに他サイトにも登録していました。軽率な行為でした。 epistemeさんには大変申し訳ないことをしてしまいました。 本当に申し訳ありませんでした。 どうか許して頂けないでしょうか。 そして、epistemeさんが調べてくれていなかったら未だに暗中模索していました。 yumetodoさんにもお世話になっているので複雑ですが、人の質問を勝手に載せるのはやめてください。 僕に責任がありますが。
episteme

2018/02/10 23:32

↑ネットにあげるってのはバラマキを認めると同義やぞ。あなたはすべての引用にいちいち許可を得ているか?
carnage0216

2018/02/10 23:34

はい。許可をとります。
episteme

2018/02/10 23:39 編集

質問にあるOpenCVのコード、引用許可を取ったのか! スゲー あなたがそうすることを止めないが、誰であれ勝手な引用を妨げることはできんからね。
carnage0216

2018/02/10 23:39

そんなわけないじゃないですか。今回の件においては私がいけなかったです。わたしはyumetodoさんのような面倒な事はしないですが。
episteme

2018/02/10 23:44

先に謝っとく、申し訳ない。僕も積極的に面倒なことしてる。マルチポスト大嫌いだから。
carnage0216

2018/02/10 23:57

こちらこそ、申し訳ありませんでした。epistemeさんにはいつも助けて頂き、感謝しております。
yumetodo

2018/02/12 05:38 編集

無宣言のマルチポストは個人的には即BANものだと思っています(宣言してやるなら許す人です、私もここで質問してやっぱり本家StackOveflowに投げるとかやるので)。「umetodoさんにもお世話になっているので複雑ですが、人の質問を勝手に載せるのはやめてください。 」ってWeb上の公開されているページのURLを貼ることに許諾が必要というのは王政復古感ある話ですね、ばかばかしい。URLは著作物ではないのだから著作権法の定める引用を持ち出すまでもない。teratailと日本語版StackOveflowは回答者がかぶっているのでマルチポストはすぐわかります。
carnage0216

2018/02/12 12:33

わたしはyumetodoさんほど賢くないのでよくわかりませんが、気分を害されたなら悪いことをしました。ごめんなさい。
guest

回答2

0

ベストアンサー

後学のためにこういうときの調べ方を。

幸いOpenCVはdoxygenによってドキュメントがまともに生成されているプロジェクトなので、まず公式ドキュメントを見ます。
https://docs.opencv.org/
から利用しているOpenCVのバージョンを選びます。
ex.) OpenCV 3.4ならhttps://docs.opencv.org/3.4.0/

検索枠に試しにCAP_PROP_FRAME_WIDTHと入れてみると選択肢が出ます。今回は一つだけですね。
OpenCV: Flags for video I/O
するとVideoCapturePropertiesというenum定数だとわかるわけです。

Width of the frames in the video stream.

なんていう説明がかかれていますね。

ついでにSee alsoと書かれているのでVideoCapture::set()も見てみましょうか。

ParametersのpropIdに

Property identifier from...

とあります。メンバ関数名がsetだけじゃ何をセットするやらわからんので第1引数はそれを識別するものだ、ということがわかりますね。

Noteに

Even if it returns true this doesn't ensure that the property value has been accepted by the capture device. See note in VideoCapture::get()

とかいう脅し文句があるので急いでVideoCapture::get()も見に行きましょう。

すると

The returned value might be different from what really used by the device or it could be encoded using device dependant rules (eg. steps or percentage). Effective behaviour depends from device driver and API Backend

とあります。まあそりゃそうだよなって内容ですね、たとえばVFRな映像にcv::CAP_PROP_FPSをidentifierにsetやらgetやらしても意味のある結果はどう考えても産まないですよね。

そんな感じで公式ドキュメント眺めるとええぞ!みたいな話でした。


しかしこの整数の必要性は何なのでしょうか?

という疑問が出るだろうと思って

メンバ関数名がsetだけじゃ何をセットするやらわからんので第1引数はそれを識別するものだ、ということがわかりますね。

と書いたんですが不十分だったようなので補足します。まあ別にset/getっていう関数にenumを渡して動的ディスパッチしなくても、例えばset_cap_prop_fps()みたいな関数を作る実装にしても良かったと思うんですが、シンボル名を減らしたかったのか何なのか、とにかくOpenCVの開発者たちはその選択肢を選ばなかったようです。


CV_CAP_PROP_FRAME_WIDTHの正体についてはCamera.Handle,"Width", &nTempを引数とする関数PvAttrUint32Getとしてもいいのでしょうか?

だめです。落ち着いて上で取り上げたVideoCapture::set()を読んでください。

Reading / writing properties involves many layers. Some unexpected result might happens along this chain.

VideoCapture -> API Backend -> Operating System -> Device Driver -> Device Hardware

とあります。いいですか?API Backendですよ?で、ググればわかるのですでにお調べのことと思いますが、PvAttrUint32GetっていうのはPvAPIのものです。他のAPIの場合も当然ありえます。

投稿2018/02/09 16:46

編集2018/02/09 18:24
yumetodo

総合スコア5850

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

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

carnage0216

2018/02/09 17:52

回答どうもありがとうございます。調べると enum { CAP_PROP_POS_MSEC =0, CAP_PROP_POS_FRAMES =1, CAP_PROP_POS_AVI_RATIO =2, CAP_PROP_FRAME_WIDTH =3, CAP_PROP_FRAME_HEIGHT =4, CAP_PROP_FPS =5,と出てきます。 しかしこの整数の必要性は何なのでしょうか? また以下のプログラム double CvCaptureCAM_PvAPI::getProperty( int property_id ) { tPvUint32 nTemp; switch ( property_id ) { case CV_CAP_PROP_FRAME_WIDTH: PvAttrUint32Get(Camera.Handle, "Width", &nTemp); return (double)nTemp;  case CV_CAP_PROP_FRAME_HEIGHT: PvAttrUint32Get(Camera.Handle, "Height", &nTemp); return (double)nTemp; の case CV_CAP_PROP_FRAME_WIDTH: PvAttrUint32Get(Camera.Handle, "Width", &nTemp);に関してですが、 case CV_CAP_PROP_FRAME_WIDTH:の場合、関数PvAttrUint32Getが呼び出され、引数がCamera.Handle,"Width", &nTempであるとのことですが、CV_CAP_PROP_FRAME_WIDTHの正体についてはCamera.Handle,"Width", &nTempを引数とする関数PvAttrUint32Getとしてもいいのでしょうか? プログラムは以下のサイトから持ってきました。 https://github.com/npinto/opencv/blob/master/modules/highgui/src/cap_pvapi.cpp#L286
carnage0216

2018/02/09 19:38

ご丁寧にありがとうございます。 危険ならば今回のやり方とは別のやり方としてパブリックなどを使おうと思います。 ほかに出力ウィンドウのサイズを変える方法はパブリック(勉強中です。)を使う以外にありますでしょうか? どうかよろしくお願いします。
carnage0216

2018/02/09 19:43

set_cap_prop_fps()みたいな関数を実装するにしても VideoCapture -> API Backend -> Operating System -> Device Driver -> Device HardwareよりDevice Hardwareなどまで調べないといけないようでハードルが高すぎるので無理ですね。
carnage0216

2018/02/09 21:53 編集

こちらにのhttps://www.buildinsider.net/small/opencv/006の動画像処理でのウィンドウのサイズを変える事ができるプログラムでしょうか? #include <opencv2/core.hpp> #include <opencv2/videoio.hpp> // videoioのヘッダーをインクルード #include <iostream> int main(int argc, const char* argv[]) { // 幅320px、高さ240px、3チャンネルのインスタンスを生成する cv::Mat img(cv::Size(320, 240), CV_8UC3, cv::Scalar(0, 0, 255)); int fourcc = cv::VideoWriter::fourcc('X', 'V', 'I', 'D'); double fps = 30.0; bool isColor = true; // (1)動画ファイルを書き出す準備を行う cv::VideoWriter writer("videofile.avi", fourcc, fps, img.size(), isColor); // (2)動画ファイル書き出しの準備に成功したかチェックする(失敗していればエラー終了する) if (!writer.isOpened()) return -1; for (int i = 0; i < 300; i++) { // (3)画像データを動画ファイルに書き出す writer << img; } return 0 ちなみに cv::VideoCapture cap(0); cap.set(cv::CAP_PROP_FRAME_WIDTH, 幅); cap.set(cv::CAP_PROP_FRAME_HEIGHT, 高さ); と cv::Mat img(cv::Size(320, 240), CV_8UC3, cv::Scalar(0, 0, 255)); はウィンドウのサイズを変えますが何か違いはあるのでしょうか? どちらも動画での処理が出来るので変わりは無いように思えます。
episteme

2018/02/10 00:05

「結果が同じなら同じ」と判断するなら同じです。 カメラとフィルムのどちらの設定の違いか、ってことですから。
yumetodo

2018/02/10 02:04

> 危険ならば今回のやり方とは別のやり方としてパブリックなどを使おうと思います。 ・・・ええっと私の理解力が低いのか、何を言っているのかさっぱりわからない。
yumetodo

2018/02/10 02:06

>Device Hardwareなどまで調べないといけないようで そんな必要はないですね、OpenCVをforkしてメンバ関数を追加して既存の実装見ながら真似ればできます。それがメンテナンス性と可読性を大幅に下げることになるのでそれを許容するならですが。
carnage0216

2018/02/10 05:27

epistemeさん、yumetodoさんどうもありがとうございます。
carnage0216

2018/02/10 05:48

yumetodoさんの「OpenCVをforkしてメンバ関数を追加して既存の実装見ながら真似する」方法でset_cap_prop_fps()のような関数を作りたいのですが、まずは何をすればいいでしょうか?
episteme

2018/02/10 05:52

fork(ディレクトリまるごとコピーを作成)し、まずはそのままbuildする。build成功したらあとは好きにいぢくりまわせ。 ...あなたはそんなことがしたいのか?
yumetodo

2018/02/10 06:34 編集

>set_cap_prop_fps()のような関数を作りたいのですが まじでやめとけ。無駄にforkするとかメンテできない未来しか見えない。正気か?
carnage0216

2018/02/10 08:08

正気と言うか、事の重大さがあまり理解できていないです。
yumetodo

2018/02/10 09:20

その記事の内容と私やLouiS0616さんやepistemeが言っていることって同じですよね? 結局あなたが何をしたいのかわからない。Windowsのサイズだけを変えたいのか、ウィンドウのサイズを変更しつつ追従して画像の大きさも変えたいのかどっち?そしてどっちにしてもやるべき手段はすでに回答されています。あなたがもう一度回答を読み直せば解決です。
carnage0216

2018/02/10 09:55

すいませんでした。 もう一度、まとめてから改めて質問させて頂きます。
carnage0216

2018/02/10 11:02

もしかしたら既に答えて頂いているかも知れませんが、なぜcv::VideoCapture cap(0);の cap.set(cv::CAP_PROP_FRAME_WIDTH, 幅); cap.set(cv::CAP_PROP_FRAME_HEIGHT, 高さ); に関して、CAP_PROP_FRAME_WIDTH =3, CAP_PROP_FRAME_HEIGHT =4, と定義がありますが 定数3,4の情報のみで幅や高さが変えられるのか全く理解できません。なぜでしょうか? CAP_PROP_FRAME_WIDTH の定数3が別の何かに働くのですか? 定数3.4のみでどうやって幅や高さを設定できるのか。 CAP_PROP_FRAME_WIDTH は定数3でありますが、その3がどのように作用してサイズの幅をどのように決めているのか知りたいです。
episteme

2018/02/10 11:11 編集

cap.set(なにを, どんだけ); ってことなんだが... // たとえば class 長方形 { int 幅; int 高さ; public: void set(int なにを, int どんだけ) { if ( なにを == 0 ) { 幅 = どんだけ; } if ( なにを == 1 ) { 高さ = どんだけ; } ... なんかわからんとこある?
guest

0

cv::CAP_PROP_FRAME_WIDTHとcv::CAP_PROP_FRAME_HEIGHTの定義などが標準関数で書いてあるのでしょうか?

それらはただの整数です。opencv/videoio.hpp #L128

C++

enum VideoCaptureProperties {
CAP_PROP_POS_MSEC =0, //!< Current position of the video file in milliseconds.
CAP_PROP_POS_FRAMES =1, //!< 0-based index of the frame to be decoded/captured next.
CAP_PROP_POS_AVI_RATIO =2, //!< Relative position of the video file: 0=start of the film, 1=end of the film.
CAP_PROP_FRAME_WIDTH =3, //!< Width of the frames in the video stream.
CAP_PROP_FRAME_HEIGHT =4, //!< Height of the frames in the video stream.
...

あくまでもどのプロパティを参照するか示す役割しかありませんので。
『3番の棚に書類あるじゃん、これに置き換えといて!』みたいな。


Windowsのウィンドの大きさに関与したシステムのデータに働くため出力ウィンドのサイズを変えることができるのでしょうか?

以前の私の回答にepistemeさんがコメントされていますね。

違うってば。

VideoCapture は Web-cameraとかが作るframeの連続から1-frame切り取るクラスで、
cap >> image; によって切り取られた1-frameがimageに取り込まれます。
なので cap.set(...) は切り取られた cv::Mat imageの幅/高さ(つまり行列の列数/行数)を決定します。
画面に書いてるのは imshow("video", image)、 関数 imshow が、与えたimageの幅/高さに応じてウィンドウのclient-areaを設定してます。

ウィンドウのサイズを変えているわけでなく、
取得する画像の大きさが変わることで、追随してウィンドウのサイズが変わるだけです。

投稿2018/02/09 09:58

LouiS0616

総合スコア35658

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

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

carnage0216

2018/02/09 10:25

いつもどうもありがとうございます。あの解釈が間違っているかもしれませんが、 VideoCapturePropertiesのCAP_PROP_FRAME_WIDTH =3,やCAP_PROP_FRAME_HEIGHT =4はあくまで目印みたいなもので、実際はVideoCaptureの関数imshowがclient-areaに働くことで出力ウィンドウのサイズを変えることができるということでしょうか?
LouiS0616

2018/02/09 10:30

imshowはVideoCaptureのメソッドではないですよ。 VideoCaptureのインスタンスはあくまで1フレームを持ってくるだけ、imshowはあくまで画像(Mat)を画面に出力するだけ、それらの働きは独立です。
LouiS0616

2018/02/09 10:33

前もってVideoCaptureのプロパティを書き換えることで、持ってくる画像の大きさを変えているんです。 imshowは指定された画像をよしなに表示しているだけです。 なお、表示ウィンドウ自体には別のプロパティがあります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問