biei.jpg
lena_small.jpg
/**------------------------------------------------------------*
 * @file	overwriteImage.cpp
 * @brief	warpAffineを用いて画像内に別の画像を描画する
 *			(ピクチャー・イン・ピクチャー機能)
 *------------------------------------------------------------*/
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

#include <stdlib.h>
#include <stdio.h>

using namespace std;

const char winName[]="picture in picture";

/**------------------------------------------------------------*
 * @fn			OpenCVのピクチャーインピクチャ
 * @brief		画像内に画像を貼り付ける(並行移動量指定)
 * @param[in ]	srcImg	背景画像
 * @param[in ]	smallImg	前景画像
 * @param[in ]	tx	前景画像の左上x座標
 * @param[in ]	ty	前景画像の左上y座標
 *------------------------------------------------------------*/
 void PinP_tr(const cv::Mat &srcImg, const cv::Mat &smallImg, const int tx, const int ty)
 {
	//背景画像の作成
	cv::Mat dstImg = srcImg.clone();

	//前景画像の変形行列
	cv::Mat mat = (cv::Mat_<double>(2,3)<<1.0, 0.0, tx, 0.0, 1.0, ty);

	//アフィン変換の実行
	cv::warpAffine(smallImg, dstImg, mat, dstImg.size(), CV_INTER_LINEAR, cv::BORDER_TRANSPARENT);
	imshow(winName, dstImg);
 }

/**------------------------------------------------------------*
 * @fn			OpenCVのピクチャーインピクチャ
 * @brief		画像内に画像を貼り付ける(回転角度指定)
 * @param[in ]	srcImg	背景画像
 * @param[in ]	smallImg	前景画像
 * @param[in ]	angle	回転角度[degree]
 *------------------------------------------------------------*/
 void PinP_rot(const cv::Mat &srcImg, const cv::Mat &smallImg, const double angle)
 {
	//背景画像の作成
	cv::Mat dstImg = srcImg.clone();

	//前景画像の変形行列
	cv::Point2d ctr(smallImg.cols/2, smallImg.rows/2);//前景画像の回転中心
	cv::Mat mat = cv::getRotationMatrix2D(ctr, angle, 1.0);//回転行列の作成

	cv::warpAffine(smallImg, dstImg, mat, dstImg.size(), CV_INTER_LINEAR, cv::BORDER_TRANSPARENT);
	imshow(winName, dstImg);
 }

/**------------------------------------------------------------*
 * @fn			OpenCVのピクチャーインピクチャ
 * @brief		画像内に画像を貼り付ける(回転角度、移動量指定)
 * @param[in ]	srcImg	背景画像
 * @param[in ]	smallImg	前景画像
 * @param[in ]	angle	回転角度[degree]
 * @param[in ]	tx	前景画像の左上x座標
 * @param[in ]	ty	前景画像の左上y座標
 *------------------------------------------------------------*/
 void PinP_rot_tr(const cv::Mat &srcImg, const cv::Mat &smallImg, const double angle, const double tx, const double ty)
 {
	//背景画像の作成
	cv::Mat dstImg = srcImg.clone();

	//前景画像の変形行列
	cv::Point2d ctr(smallImg.cols/2, smallImg.rows/2);//前景画像の回転中心
	cv::Mat mat = cv::getRotationMatrix2D(ctr, angle, 1.0);//回転行列の作成
	mat.at<double>(0,2) +=tx;//回転後の平行移動量
	mat.at<double>(1,2) +=ty;//回転後の平行移動量

	//アフィン変換の実行
	cv::warpAffine(smallImg, dstImg, mat, dstImg.size(), CV_INTER_LINEAR, cv::BORDER_TRANSPARENT);
	imshow(winName, dstImg);
 }

/**------------------------------------------------------------*
 * @fn			OpenCVのピクチャーインピクチャ
 * @brief		画像内に画像を貼り付ける(位置を座標で指定)
 * @param[in ]	srcImg	背景画像
 * @param[in ]	smallImg	前景画像
 * @param[in ]	p0	前景画像の左上座標
 * @param[in ]	p1	前景画像の右下座標
 *------------------------------------------------------------*/
 void PinP_point(const cv::Mat &srcImg, const cv::Mat &smallImg, const cv::Point2f p0, const cv::Point2f p1)
 {
	//背景画像の作成
	cv::Mat dstImg = srcImg.clone();

	//3組の対応点を作成
	vector<cv::Point2f> src, dst;
	src.push_back(cv::Point2f(0, 0));
	src.push_back(cv::Point2f(smallImg.cols, 0));
	src.push_back(cv::Point2f(smallImg.cols, smallImg.rows));

	dst.push_back(p0);
	dst.push_back(cv::Point2f(p1.x, p0.y));
	dst.push_back(p1);

	//前景画像の変形行列
	cv::Mat mat = cv::getAffineTransform(src, dst);

	//アフィン変換の実行
	cv::warpAffine(smallImg, dstImg, mat, dstImg.size(), CV_INTER_LINEAR, cv::BORDER_TRANSPARENT);
	imshow(winName, dstImg);
 }

/**------------------------------------------------------------*
 * @fn			main
 * @brief		メイン関数
 *------------------------------------------------------------*/
int main(int argc, char** argv)
{
	cv::Mat srcImg, smallImg;

	//画像読み込み
	srcImg   = cv::imread("biei.jpg");
	smallImg = cv::imread("lena_small.jpg");

	if( (srcImg.data==NULL) || (smallImg.data==NULL) )
	{
		printf("------------------------------\n");
		printf("image not exist\n");
		printf("------------------------------\n");
		return EXIT_FAILURE;
	}
	else
	{
		printf("------------------------------\n");
		printf("Press ANY key to progress\n");
		printf("------------------------------\n");
	}

	cv::namedWindow(winName); //ウィンドウ生成

	//平行移動
	PinP_tr(srcImg, smallImg, 100, 100);
	cv::waitKey(0); //キーボード処理

	//回転
	PinP_rot(srcImg, smallImg, 45);
	cv::waitKey(0); //キーボード処理

	//回転+平行移動
	PinP_rot_tr(srcImg, smallImg, 45, 100, 100);
	cv::waitKey(0); //キーボード処理

	//座標指定
 	cv::Point2f p0(100,100);
 	cv::Point2f p1(450,380);
	PinP_point(srcImg, smallImg, p0, p1);
	cv::waitKey(0); //キーボード処理

	return EXIT_SUCCESS;
}