第3回 OpenCV教室

ROI(Region Of Interest)を用いた画像のコピー

以下のプログラムを実際に動かしてみよう。

#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

#ifdef _DEBUG
    //Debugモードの場合
    #pragma comment(lib,"opencv_core2411d.lib")
    #pragma comment(lib,"opencv_highgui2411d.lib")
#else
    //Releaseモードの場合
    #pragma comment(lib,"opencv_core2411.lib")
    #pragma comment(lib,"opencv_highgui2411.lib")
#endif

using namespace std;

int main() {
	cv::Mat img = cv::imread("puppy.bmp"); 
	cv::Mat logo = cv::imread("KAIT_logo.png"); 

	cv::Mat imgROI(img, cv::Rect(img.cols - logo.cols, img.rows - logo.rows, logo.cols, logo.rows));
	logo.copyTo(imgROI);

	cv::namedWindow("大学のロゴ on 犬");
	cv::imshow("大学のロゴ on 犬", img);

	cv::waitKey(0);

	return 0;
}

処理対象ファイルは以下の「puppy.bmp」「KAIT_logo.png」とする。

puppy.bmp
KAIT_logo.png

結果は以下のようになる。

C言語版

上記をC言語で書くと以下のようになる。

#include <opencv2/core/core_c.h>
#include <opencv2/highgui/highgui_c.h>

#ifdef _DEBUG
    //Debugモードの場合
    #pragma comment(lib,"opencv_core2411d.lib")
    #pragma comment(lib,"opencv_highgui2411d.lib")
#else
    //Releaseモードの場合
    #pragma comment(lib,"opencv_core2411.lib")
    #pragma comment(lib,"opencv_highgui2411.lib")
#endif

int main() {
	IplImage* img = cvLoadImage("puppy.bmp", CV_LOAD_IMAGE_UNCHANGED);
	IplImage* logo = cvLoadImage("KAIT_logo.png", CV_LOAD_IMAGE_UNCHANGED);

	cvSetImageROI(img, cvRect(img->width - logo->width, img->height - logo->height, logo->width, logo->height));
	cvCopy(logo, img, NULL);
	cvResetImageROI(img);

	cvNamedWindow("大学のロゴ on 犬", CV_WINDOW_AUTOSIZE);
	cvShowImage("大学のロゴ on 犬", img);

	cvWaitKey(0);

	cvReleaseImage(&img);
	cvReleaseImage(&logo);
	cvDestroyAllWindows();

	return 0;
}

マスクを用いた画像のコピー

マスクは8bitのグレースケールで、処理をさせたいピクセルに非0の値を格納することで選択的な処理が可能となる。 以下のプログラムを実際に動かしてみよう。

#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

#ifdef _DEBUG
    //Debugモードの場合
    #pragma comment(lib,"opencv_core2411d.lib")
    #pragma comment(lib,"opencv_highgui2411d.lib")
#else
    //Releaseモードの場合
    #pragma comment(lib,"opencv_core2411.lib")
    #pragma comment(lib,"opencv_highgui2411.lib")
#endif

using namespace std;

int main() {
	cv::Mat img = cv::imread("puppy.bmp"); 
	cv::Mat logo = cv::imread("KAIT_logo.png"); 

	cv::Mat mask(logo.rows, logo.cols, CV_8UC1);
	for (int y = 0; y < logo.rows; y++) {
		for (int x = 0; x < logo.cols; x++) {
			int blue = logo.at<cv::Vec3b>(y,x)[0];
			int green = logo.at<cv::Vec3b>(y,x)[1];
			int red = logo.at<cv::Vec3b>(y,x)[2];

			if (blue > 100 && green > 100 && red > 100) {
				mask.at<uchar>(y,x) = 0;
			}
			else {
				mask.at<uchar>(y,x) = 255;
			}
		}
	}

	cv::Mat imgROI(img, cv::Rect(img.cols-logo.cols, img.rows - logo.rows, logo.cols, logo.rows));
	logo.copyTo(imgROI, mask);

	cv::namedWindow("マスク");
	cv::imshow("マスク", mask);

	cv::namedWindow("大学のロゴ on 犬");
	cv::imshow("大学のロゴ on 犬", img);

	cv::waitKey(0);

	return 0;
}

生成したマスク画像
マスクを用いてコピーした結果

C言語版

上記をC言語で書くと以下のようになる。

#include <opencv2/core/core_c.h>
#include <opencv2/highgui/highgui_c.h>

#ifdef _DEBUG
    //Debugモードの場合
    #pragma comment(lib,"opencv_core2411d.lib")
    #pragma comment(lib,"opencv_highgui2411d.lib")
#else
    //Releaseモードの場合
    #pragma comment(lib,"opencv_core2411.lib")
    #pragma comment(lib,"opencv_highgui2411.lib")
#endif

int main() {
	int x, y;
	int blue, green, red;
	IplImage *img, *logo, *mask;
	uchar *ptr1, *ptr2;

	img = cvLoadImage("puppy.bmp", CV_LOAD_IMAGE_UNCHANGED);
	logo = cvLoadImage("KAIT_logo.png", CV_LOAD_IMAGE_UNCHANGED);

	mask = cvCreateImage(cvSize(logo->width, logo->height), IPL_DEPTH_8U, 1);
	for (y = 0; y < logo->height; y++) {
		ptr1 = (uchar*)(logo->imageData + y * logo->widthStep);
		ptr2 = (uchar*)(mask->imageData + y * mask->widthStep);

		for (x = 0; x < logo->width; x++) {
			blue = (int)ptr1[x * 3];
			green = (int)ptr1[x * 3 + 1];
			red = ptr1[x * 3 + 2];

			if (blue > 100 && green > 100 && red > 100) {
				ptr2[x] = 0;
			}
			else {
				ptr2[x] = (uchar)255;
			}
		}
	}

	cvSetImageROI(img, cvRect(img->width - logo->width, img->height - logo->height, logo->width, logo->height));
	cvCopy(logo, img, mask);
	cvResetImageROI(img);

	cvNamedWindow("マスク", CV_WINDOW_AUTOSIZE);
	cvShowImage("マスク", mask);

	cvNamedWindow("大学のロゴ on 犬", CV_WINDOW_AUTOSIZE);
	cvShowImage("大学のロゴ on 犬", img);

	cvWaitKey(0);

	cvReleaseImage(&img);
	cvReleaseImage(&logo);
	cvReleaseImage(&mask);
	cvDestroyAllWindows();

	return 0;
}