ページ 11

OpenCVで複数の画像を1つのウィンドウに表示させる

Posted: 2014年8月29日(金) 13:22
by DOG
今、OpenCVで複数の画像を1つのウィンドウに表示させるためのコーディングで悩んでいるところがあります。
具体的には、元となる一枚の画像を水平反転・垂直反転・水平垂直反転させたもの4枚(元画像含む)を1つのウィンドウにお互いが重ならないように配置して、万華鏡風にしたいのですが複数の画像を1つのウィンドウに表示する仕方が分からずに困っています。
①元画像
②元画像を水平反転させたもの
③元画像を垂直反転させたもの
④元画像を水平垂直反転させたもの
とすると、
①②
③④
といったような配置をしたいです。
以下のようなコードだとそれぞれ別のウィンドウに表示されてしまいますので、どなたかご教授してくださると大変助かります。

コード:

#include<opencv2/opencv.hpp>
using namespace cv;

int main(int argc, char* argv[])
{
	cv::Mat src_img = cv::imread("flower.jpg");
	cv::Mat dst = cv::Mat((src_img.rows), (src_img.cols), CV_8UC3);

	cv::Mat v_img, h_img, b_img;
	cv::flip(src_img, v_img, 0); // 水平軸で反転(垂直反転)
	cv::flip(src_img, h_img, 1); // 垂直軸で反転(水平反転)
	cv::flip(src_img, b_img, -1); // 両方の軸で反転

	cv::namedWindow("vertical flip image", CV_WINDOW_AUTOSIZE | CV_WINDOW_FREERATIO);
	cv::namedWindow("horizontal flip image", CV_WINDOW_AUTOSIZE | CV_WINDOW_FREERATIO);
	cv::namedWindow("both flip image", CV_WINDOW_AUTOSIZE | CV_WINDOW_FREERATIO);
	cv::imshow("vertical flip image", v_img);
	cv::imshow("horizontal flip image", h_img);
	cv::imshow("both flip image", b_img);

	cv::waitKey(0);

	return 0;
}

Re: OpenCVで複数の画像を1つのウィンドウに表示させる

Posted: 2014年8月29日(金) 13:37
by h2so5
4つの画像を合成して1枚にすればいいと思います。

Re: OpenCVで複数の画像を1つのウィンドウに表示させる

Posted: 2014年8月30日(土) 00:00
by DOG
h2so5さん返信ありがとうございます。
たしかにその通りなのですが、どうしてもプログラム上で合成させたく思っております。
とりあえず、とあるサイトを参考にしながら以下のようにコードを組んでみました。
とりあえず元画像とそれを垂直反転させたものを横に連結させるというプログラムを組んだつもりなのですが、
垂直反転した画像だけしか出力されません・・・・
この原因が分かる方いらっしゃいますでしょうか。

コード:

#include<opencv2/opencv.hpp>

using namespace cv;

void stack(IplImage *img1, IplImage *img2)
{
	IplImage* stacked = cvCreateImage(cvSize(img1->width + img2->width, MAX(img1->height, img2->height)), IPL_DEPTH_8U, 3);
	cvZero(stacked);
	cvSetImageROI(stacked, cvRect(0, 0, img1->width, img1->height));
	cvAdd(img1, stacked, stacked, NULL);
	cvSetImageROI(stacked, cvRect(img1->width, 0, img2->width, img2->height));
	cvAdd(img2, stacked, stacked, NULL);
	cvShowImage("dst_img", stacked);
	cvResetImageROI(stacked);
}

int main(int argc, char* argv[])
{
	cv::Mat src_img = cv::imread("flower.jpg");
	cv::Mat dst = cv::Mat((src_img.rows), (src_img.cols), CV_8UC3);
 	cv::Mat v_img, h_img, b_img;
	
	cv::flip(src_img, v_img, 0); // 水平軸で反転(垂直反転)
	cv::flip(src_img, h_img, 1); // 垂直軸で反転(水平反転)
	cv::flip(src_img, b_img, -1); // 両方の軸で反転

	IplImage* Isrc_img = &static_cast<IplImage>(src_img); //MAT型をIplImageのポインタ型に変換(こうしないと上の関数が使えない)
	IplImage* Iv_img = &static_cast<IplImage>(v_img); //MAT型をIplImageのポインタ型に変換

	stack(Isrc_img, Iv_img); //元画像と垂直反転した画像を横に連結

	// wait for key event
	cv::waitKey(0);

	return 0;
}

Re: OpenCVで複数の画像を1つのウィンドウに表示させる

Posted: 2014年8月30日(土) 10:09
by usao
cvShowImage() の時点で,stackedにはROIが設定されている ので
その領域しか表示しないということになっています.

stack() の最後の2行の順番を入れ替えれば表示されるのではないでしょうか.
(あと,最後にちゃんとstackedを cvReleaseImage() しましょう.)

Re: OpenCVで複数の画像を1つのウィンドウに表示させる

Posted: 2014年8月30日(土) 14:44
by DOG
usaoさん、返信ありがとうございます。
仰るとおりに修正しましたら、意図したとおりの処理が行われました。
大変助かりました。ありがとうございました。