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)尺寸,將模板圖像分割成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;
我們將讀取進來的所有素材圖像都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表示當前素材圖像的索引 int index = i * width + j; //將當前素材圖像拷貝到temp零時變量 images[index].copyTo(temp); //將temp圖像賦值給需要生成的蒙太奇圖像對應區(qū)域 temp = dst(Rect(j * step_x, i * step_y, step_x, step_y)); } } imshow("dst", dst);
通過兩個for循環(huán)就可以遍歷到每個蒙版區(qū)域。這個類似于遍歷圖像的所有像素,只不過我們把步長加大了而已。整個代碼的核心就是以下這兩句。
//將當前素材圖像拷貝到temp零時變量 images[index].copyTo(temp); //將temp圖像賦值給需要生成的蒙太奇圖像對應區(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);
我們通過遍歷模板圖像所有像素,并改變它們的權值,就可以得到蒙太奇圖像啦。
這就是我們生成的蒙太奇圖像
五、源碼
#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圖像賦值給需要生成的蒙太奇圖像對應區(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; }
總結
本文使用OpenCV C++生成蒙太奇圖像,關鍵步驟有以下幾點。
1、將你需要生成的蒙太奇圖像模板resize成合適大小,使其恰好能夠被素材圖像填充。
2、載入素材圖像。
3、使用素材圖像去填充蒙版圖。核心就是上面的兩個for循環(huán)。
4、將蒙版與模板圖像進行融合,改變其像素權值就可以生成蒙太奇圖像了。
本文使用較為簡單,也比較容易理解的程序生成蒙太奇圖像。網(wǎng)上也有許多是使用直方圖匹配——將模板圖像分割成不等分區(qū)域,然后使用素材庫中的圖像與這些區(qū)域一一進行直方圖匹配,找到最匹配的那張圖像填充該區(qū)域。有興趣的小伙伴可以嘗試一下這種方法!!
以上就是C++ OpenCV生成蒙太奇圖像的示例詳解的詳細內(nèi)容,更多關于C++ OpenCV蒙太奇圖像的資料請關注腳本之家其它相關文章!
相關文章
c++ 構造函數(shù)中調(diào)用虛函數(shù)的實現(xiàn)方法
下面小編就為大家?guī)硪黄猚++ 構造函數(shù)中調(diào)用虛函數(shù)的實現(xiàn)方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-12-12C語言使用ffmpeg實現(xiàn)單線程異步的視頻播放器
這篇文章主要為大家詳細介紹了C語言如何使用ffmpeg實現(xiàn)單線程異步的視頻播放器功能,文中的示例代碼講解詳細,感興趣的小伙伴可以嘗試一下2022-12-12C語言當函數(shù)執(zhí)行成功時return1還是0
本文主要介紹了C語言當函數(shù)執(zhí)行成功時return1還是0,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-09-09