C++ OpenCV生成蒙太奇圖像的示例詳解

前言

本文將使用OpenCV C++ 生成蒙太奇圖像。

一、輸入模板圖像

原圖如圖所示。我們將對此圖生成蒙太奇圖像。

    Mat src = imread("Taylor.jpg");
    if (src.empty())
    {
        cout << "No image!" << endl;
        system("pause");
        return 0;
    }
 resize(src, src, Size(step_x*30, step_y*30), 1, 1, INTER_CUBIC);

這裡的step_x,step_y表示素材圖像尺寸。我們要把模板圖像resize成 Size(step_x 30, step_y*30)尺寸,將模板圖像分割成30×30個block,即使用30×30張素材圖像來生成我們的蒙太奇圖像。

二、讀取素材圖像

所有素材圖像。

//獲取文件夾下所有圖像路徑
int getImagePathList(string folder, vector<String> &imagePathList)
{
	glob(folder, imagePathList);
	return 0;
}

我們定義getImagePathList函數獲取文件夾下所有圖像的路徑。

	vector<Mat>images;
	string filename = "images/";
	cout << "loading..." << endl;

	vector<String> imagePathList;
	getImagePathList(filename, imagePathList);

	for (int i = 0; i < imagePathList.size(); i++)
	{
		Mat img = cv::imread(imagePathList[i]);

		resize(img, img, Size(step_x, step_y), 1, 1, INTER_AREA);

		images.push_back(img);

	}
	cout << "done!" << endl;

我們將讀取進來的所有素材圖像都resize成 Size(step_x, step_y)大小,並把它們都push_back到images容器內,以便後續使用。

三、生成蒙太奇模板

	int rows = src.rows;
	int cols = src.cols;
	//height:表示生成的蒙太奇圖像需要多少張素材圖像填充rows
	//width:表示生成的蒙太奇圖像需要多少張素材圖像填充cols
	int height = rows / step_y, width = cols / step_x;

	Mat temp;
	Mat dst = Mat(src.size(), CV_8UC3, Scalar(255, 255, 255));
	
	for (int i = 0; i < height; ++i)
	{
		for (int j = 0; j < width; ++j)
		{
			//index表示當前素材圖像的索引
			int index = i * width + j;

			//將當前素材圖像拷貝到temp零時變量
			images[index].copyTo(temp);

			//將temp圖像賦值給需要生成的蒙太奇圖像對應區域
			temp = dst(Rect(j * step_x, i * step_y, step_x, step_y));
		}
	}

	imshow("dst", dst);

通過兩個for循環就可以遍歷到每個蒙版區域。這個類似於遍歷圖像的所有像素,隻不過我們把步長加大瞭而已。整個代碼的核心就是以下這兩句。

	//將當前素材圖像拷貝到temp零時變量
	images[index].copyTo(temp);

	//將temp圖像賦值給需要生成的蒙太奇圖像對應區域
	temp = dst(Rect(j * step_x, i * step_y, step_x, step_y));

將所有的素材圖像copy到指定區域就可以生成蒙版圖像啦。接下來我們就得對這個蒙版圖像做像素處理瞭。

四、生成蒙太奇圖像

	for (int i = 0; i < rows; ++i)
	{
		for (int j = 0; j < cols; ++j)
		{
			//像素RGB值修改
			dst.at<Vec3b>(i, j)[0] = 0.312*dst.at<Vec3b>(i, j)[0] + 0.698*src.at<Vec3b>(i, j)[0];
			dst.at<Vec3b>(i, j)[1] = 0.312*dst.at<Vec3b>(i, j)[1] + 0.698*src.at<Vec3b>(i, j)[1];
			dst.at<Vec3b>(i, j)[2] = 0.312*dst.at<Vec3b>(i, j)[2] + 0.698*src.at<Vec3b>(i, j)[2];
		}
	}


	imshow("蒙太奇圖像", dst);

我們通過遍歷模板圖像所有像素,並改變它們的權值,就可以得到蒙太奇圖像啦。

這就是我們生成的蒙太奇圖像

五、源碼

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

//素材圖像尺寸
const int step_x = 20;
const int step_y = 20;

//獲取文件夾下所有圖像路徑
int getImagePathList(string folder, vector<String> &imagePathList)
{
	glob(folder, imagePathList);
	return 0;
}

int main()
{
	Mat src = imread("Taylor.jpg");
	if (src.empty())
	{
		cout << "No image!" << endl;
		system("pause");
		return 0;
	}

	resize(src, src, Size(step_x*30, step_y*30), 1, 1, INTER_CUBIC);

	vector<Mat>images;
	string filename = "images/";
	cout << "loading..." << endl;

	vector<String> imagePathList;
	getImagePathList(filename, imagePathList);

	for (int i = 0; i < imagePathList.size(); i++)
	{
		Mat img = cv::imread(imagePathList[i]);

		resize(img, img, Size(step_x, step_y), 1, 1, INTER_AREA);

		images.push_back(img);

	}
	cout << "done!" << endl;

	int rows = src.rows;
	int cols = src.cols;
	//height:表示生成的蒙太奇圖像需要多少張素材圖像填充rows
	//width:表示生成的蒙太奇圖像需要多少張素材圖像填充cols
	int height = rows / step_y, width = cols / step_x;

	Mat temp;
	Mat dst = Mat(src.size(), CV_8UC3, Scalar(255, 255, 255));
	
	for (int i = 0; i < height; ++i)
	{
		for (int j = 0; j < width; ++j)
		{
			//index表示當前素材圖像的索引
			int index = i * width + j;

			//將當前素材圖像拷貝到temp零時變量
			images[index].copyTo(temp);

			//將temp圖像賦值給需要生成的蒙太奇圖像對應區域
			temp = dst(Rect(j * step_x, i * step_y, step_x, step_y));
		}
	}

	imshow("dst", dst);
	

	for (int i = 0; i < rows; ++i)
	{
		for (int j = 0; j < cols; ++j)
		{
			//像素RGB值修改
			dst.at<Vec3b>(i, j)[0] = 0.312*dst.at<Vec3b>(i, j)[0] + 0.698*src.at<Vec3b>(i, j)[0];
			dst.at<Vec3b>(i, j)[1] = 0.312*dst.at<Vec3b>(i, j)[1] + 0.698*src.at<Vec3b>(i, j)[1];
			dst.at<Vec3b>(i, j)[2] = 0.312*dst.at<Vec3b>(i, j)[2] + 0.698*src.at<Vec3b>(i, j)[2];
		}
	}


	imshow("蒙太奇圖像", dst);
	waitKey(0);
	system("pause");
	return 0;
}

總結

本文使用OpenCV C++生成蒙太奇圖像,關鍵步驟有以下幾點。

1、將你需要生成的蒙太奇圖像模板resize成合適大小,使其恰好能夠被素材圖像填充。

2、載入素材圖像。

3、使用素材圖像去填充蒙版圖。核心就是上面的兩個for循環。

4、將蒙版與模板圖像進行融合,改變其像素權值就可以生成蒙太奇圖像瞭。

本文使用較為簡單,也比較容易理解的程序生成蒙太奇圖像。網上也有許多是使用直方圖匹配——將模板圖像分割成不等分區域,然後使用素材庫中的圖像與這些區域一一進行直方圖匹配,找到最匹配的那張圖像填充該區域。有興趣的小夥伴可以嘗試一下這種方法!!

以上就是C++ OpenCV生成蒙太奇圖像的示例詳解的詳細內容,更多關於C++ OpenCV蒙太奇圖像的資料請關註WalkonNet其它相關文章!

推薦閱讀: