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

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

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

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

C++

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

Q&A

解決済

1回答

1464閲覧

OpenCVで動画の4分割表示をしたい

tanaka_kazuya

総合スコア15

OpenCV

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

C++

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

0グッド

0クリップ

投稿2019/01/22 08:53

前提・実現したいこと

C++を使ったOpenCVで動画の表示をするプログラムを作成しています。
読み込んだ動画を縦横に2分割し、imshowで一つの画面に表示したいです。

イメージ説明

該当のソースコード

C++

1#include "stdafx.h" 2#include <opencv2/opencv.hpp> 3#pragma comment(lib, "opencv_world341d.lib") 4using namespace std; 5using namespace cv; 6 7int main() 8{ 9 VideoCapture cap("video.avi"); // ビデオファイルを開く 10 if (!cap.isOpened()) { // ビデオファイルが開けないとき 11 cout << "ビデオファイルが開けません。"; 12 cin.get(); 13 return -1; 14 } 15 16 Mat src; // Matオブジェクト生成 17 18 while (1) { // ループ開始 19 cap >> src; // 1フレーム読み込み 20 if (src.empty()) break; // フレームが空のとき終了 21 imshow("入力映像", src); // 1フレーム表示 22 if (waitKey(30) == 27) break; // キー入力待機(30ms) 23 } 24 return 0; 25} 26

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

Visual Studio 2017
OpenCV 3.4.1

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

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

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

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

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

guest

回答1

0

ベストアンサー

ヒントだけ。

幅高は以下で取得できます。

C++

1Mat src; 2int width = src.cols; 3int height = src.rows;

画像の一部を切り出すには、cv::Rectを使います。

C++

1cv::Rect roi(x, y, width, height); 2cv::Mat cropped = src(roi);

あとは、座標を適切に計算して、4回切り出すだけです。


コメントを受けて追記:

下記が良くないですね。

C++

1for (auto it = p.begin(); it != p.end(); ++it) { 2 // 関心領域を元の画像から矩形で切り出す 3 roi = src(Rect(it->x, it->y, src.cols / 2, src.rows / 2)); 4} 5 6imshow("入力映像", roi); // 1フレーム表示

for文の中で、roiに切り出した画像を上書きしてしまっています。このため、最後の画像しか表示されません。

ということは、上書きしないように4つ分Matを用意するか、ひとつずつ表示するか。
あともう一歩です!

投稿2019/01/22 10:19

編集2019/01/22 13:29
kazto

総合スコア7196

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

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

tanaka_kazuya

2019/01/22 13:19

回答ありがとうございます。 下のようにしてみたところ、4つに分けたうちの1つしか表示できませんでした。for文で4回切り出したまではわかります。roiには最後に切り出した画像のみ格納されているようで、imshowで表示すると最終画像のみ表示となってしまいます。どのようにすればいいでしょうか? #include "stdafx.h" #include <opencv2/opencv.hpp> #pragma comment(lib, "opencv_world341d.lib") using namespace std; using namespace cv; int main() { VideoCapture cap(0); // ビデオファイルを開く if (!cap.isOpened()) { // ビデオファイルが開けないとき cout << "ビデオファイルが開けません。"; cin.get(); return -1; } Mat src, roi; // Matオブジェクト生成 while (1) { // ループ開始 cap >> src; // 1フレーム読み込み if (src.empty()) break; // フレームが空のとき終了 //src1を 4分割するための点を定義 vector<Point> p = { { 0, 0 },{ src.cols / 2, 0 },{ 0, src.rows / 2 },{ src.cols / 2, src.rows / 2 } }; for (auto it = p.begin(); it != p.end(); ++it) { // 関心領域を元の画像から矩形で切り出す roi = src(Rect(it->x, it->y, src.cols / 2, src.rows / 2)); } imshow("入力映像", roi); // 1フレーム表示 if (waitKey(30) == 27) break; // キー入力待機(30ms) } return 0; }
kazto

2019/01/22 13:29

回答追記しました。
tanaka_kazuya

2019/01/22 17:27

回答ありがとうございます。 下記のようにしてみましたら、エラーでした。 roi1 = src(Rect(0, 0, src.cols / 2, src.rows / 2)); roi2 = src(Rect(src.cols / 2, 0, src.cols, src.rows / 2)); roi3 = src(Rect(0, src.rows / 2, src.cols / 2, src.rows)); roi4 = src(Rect(src.cols / 2, src.rows / 2, src.cols, src.rows)); imshow("入力映像", roi1); // 1フレーム表示 imshow("入力映像", roi2); imshow("入力映像", roi3); imshow("入力映像", roi4); ------------------------ 次のようにfor文でループすればいいのではと思いますが、書き方が分かりません。 for (auto it = p.begin(); it != p.end(); ++it) { // 関心領域を元の画像から矩形で切り出す roi1 = src(Rect(it->x, it->y, src.cols / 2, src.rows / 2)); for (int i = 0; i = 3; i++) { imshow("入力映像", roi1); } }
kazto

2019/01/22 23:28

エラーとは具体的にどのようなものが出ましたか?
yominet

2019/01/23 15:45

cv::Rectは (左,上,右,下) ではなくて、 (左,上,幅,高さ) ってところでしょうか
tanaka_kazuya

2019/01/23 16:45

kaztoさん回答ありがとうございます。 エラーですが、「ハンドルされていない例外が0×00007FFEE11F8EACで発生しました。Maicrosoft C++の例外:cv::Exception(メモリの場所0×00000048FD9BEA30)」とでます。 さらに ・roi {x=320 y=0 width=640 ...} const cv::Rect_<int> & ・this 0x00000048fd9bee60 {flags=1124024336 dims=2 rows=480 ...} cv::Mat * と表示されます。
tanaka_kazuya

2019/01/23 16:48

yominetさん回答ありがとうございます。 cv::Rect (x, y, width, height)というこですよね。 その通りに書いたつもりですが、間違いがあるでしょうか。
kazto

2019/01/23 22:00

ここですね。 roi3 = src(Rect(0, src.rows / 2, src.cols / 2, src.rows)); roi4 = src(Rect(src.cols / 2, src.rows / 2, src.cols, src.rows));
tanaka_kazuya

2019/01/24 11:44

回答ありがとうございます。 ようやく気づくことが出来ました。 cv::Rect (x, y, width, height)のwidth、heightの指定が間違っていました。 正しくは roi1 = src(Rect(0, 0, src.cols / 2, src.rows / 2)); roi2 = src(Rect(src.cols / 2, 0, src.cols / 2, src.rows / 2)); roi3 = src(Rect(0, src.rows / 2, src.cols / 2, src.rows / 2)); roi4 = src(Rect(src.cols / 2, src.rows / 2, src.cols / 2, src.rows / 2)); でした。 このときimshow()を4つ使い、4つのウインドウが生成されますが これらを一つのウインドウ内で表示するにはどうすればいいでしょうか。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問