最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時間:2022年01月11日 09:50:15   作者:Zero___Chen  
圖片的蒙太奇效果,一般稱為馬賽克圖。由很多小圖拼接成一個大圖。這篇文章主要為大家介紹如何利用C++ OpenCV實現(xiàn)生成蒙太奇圖像,感興趣的可以了解一下

前言

本文將使用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)尺寸,將模板圖像分割成30x30個block,即使用30x30張素材圖像來生成我們的蒙太奇圖像。

二、讀取素材圖像

所有素材圖像。

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

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

	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;

我們將讀取進(jìn)來的所有素材圖像都resize成 Size(step_x, step_y)大小,并把它們都push_back到images容器內(nèi),以便后續(xù)使用。

三、生成蒙太奇模板

	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表示當(dāng)前素材圖像的索引
			int index = i * width + j;

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

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

	imshow("dst", dst);

通過兩個for循環(huán)就可以遍歷到每個蒙版區(qū)域。這個類似于遍歷圖像的所有像素,只不過我們把步長加大了而已。整個代碼的核心就是以下這兩句。

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

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

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

四、生成蒙太奇圖像

	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);

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

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

五、源碼

#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表示當(dāng)前素材圖像的索引
			int index = i * width + j;

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

			//將temp圖像賦值給需要生成的蒙太奇圖像對應(yīng)區(qū)域
			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;
}

總結(jié)

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

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

2、載入素材圖像。

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

4、將蒙版與模板圖像進(jìn)行融合,改變其像素權(quán)值就可以生成蒙太奇圖像了。

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

以上就是C++ OpenCV生成蒙太奇圖像的示例詳解的詳細(xì)內(nèi)容,更多關(guān)于C++ OpenCV蒙太奇圖像的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 解析c中stdout與stderr容易忽視的一些細(xì)節(jié)

    解析c中stdout與stderr容易忽視的一些細(xì)節(jié)

    本篇文章是對在c語言中stdout與stderr容易忽視的一些細(xì)節(jié)進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • 使用C語言實例描述程序中的內(nèi)聚和耦合問題

    使用C語言實例描述程序中的內(nèi)聚和耦合問題

    這篇文章主要介紹了用C語言實例描述程序中的內(nèi)聚和耦合,本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-08-08
  • C語言下快速排序(挖坑法)詳解

    C語言下快速排序(挖坑法)詳解

    大家好,本篇文章主要講的是C語言下快速排序(挖坑法)詳解,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • 詳解C++虛函數(shù)表存儲位置

    詳解C++虛函數(shù)表存儲位置

    相信大家知道虛表指針和虛函數(shù)存儲的位置,但對于虛函數(shù)表的存儲位置一時無法確定。本文就來和大家詳細(xì)聊聊相關(guān)內(nèi)容,希望對大家有所幫助
    2023-04-04
  • OpenCV實現(xiàn)繞圖片中任意角度旋轉(zhuǎn)任意角度

    OpenCV實現(xiàn)繞圖片中任意角度旋轉(zhuǎn)任意角度

    這篇文章主要為大家詳細(xì)介紹了在圖片不被裁剪時,opencv如何實現(xiàn)繞圖片中任意點旋轉(zhuǎn)任意角度,文中的示例代碼講解詳細(xì),需要的可以參考一下
    2022-09-09
  • 基于Matlab實現(xiàn)多目標(biāo)粘液霉菌算法的示例代碼

    基于Matlab實現(xiàn)多目標(biāo)粘液霉菌算法的示例代碼

    多目標(biāo)粘液霉菌算法(MOSMA),這是最近開發(fā)的粘液霉菌算法(SMA)的多目標(biāo)變體,用于處理工業(yè)中的多目標(biāo)優(yōu)化問題。本文將用Matlab實現(xiàn)這一算法,需要的可以參考一下
    2022-05-05
  • C語言中關(guān)于動態(tài)內(nèi)存分配的詳解

    C語言中關(guān)于動態(tài)內(nèi)存分配的詳解

    動態(tài)內(nèi)存是指在堆上分配的內(nèi)存,而靜態(tài)內(nèi)存是指在棧上分配的內(nèi)存。棧上分配的內(nèi)存是由系統(tǒng)分配和釋放的,空間有限,在復(fù)合語句或函數(shù)運行結(jié)束后就會被系統(tǒng)自動釋放而堆上分配的內(nèi)存則不會有這個問題。
    2021-09-09
  • C++ Explicit關(guān)鍵字詳細(xì)解析

    C++ Explicit關(guān)鍵字詳細(xì)解析

    以下是對C++中Explicit關(guān)鍵字的用法進(jìn)行了詳細(xì)的介紹,需要的朋友可以過來參考下,希望對大家有所幫助
    2013-09-09
  • C語言實現(xiàn)計算樹的深度的方法

    C語言實現(xiàn)計算樹的深度的方法

    這篇文章主要介紹了C語言實現(xiàn)計算樹的深度的方法,針對數(shù)據(jù)結(jié)構(gòu)中樹進(jìn)行操作的方法,在算法設(shè)計中比較常見,需要的朋友可以參考下
    2014-09-09
  • C/C++讀取大文件數(shù)據(jù)方式詳細(xì)講解

    C/C++讀取大文件數(shù)據(jù)方式詳細(xì)講解

    這篇文章主要介紹了C語言/C++讀取大文件數(shù)據(jù)的完整方式過程,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-09-09

最新評論

茂名市| 保康县| 浮梁县| 怀来县| 广汉市| 虹口区| 正阳县| 辽宁省| 攀枝花市| 石门县| 濮阳市| 全州县| 金山区| 永靖县| 家居| 昌图县| 姚安县| 南川市| 繁峙县| 扎兰屯市| 黄陵县| 尉犁县| 眉山市| 牙克石市| 浑源县| 玉山县| 华容县| 晋城| 青冈县| 石台县| 雷山县| 巢湖市| 修文县| 彭州市| 左权县| 蒙城县| 吉林市| 石城县| 石首市| 永和县| 大化|