本项目制作montage效果,data为源图片的路径
业务逻辑:
1.读取图片(目标效果图片,资源库图片)
2.分析目标效果图片,从资源库图片当中找到匹配图片
3.进行图片组合
4.生成结果图片
工程逻辑:
1.创建工程项目
①创建工程文件夹Montage
②将相关资源导入到项目中
③使用CMake进行编写
2.创建对应的代码源文件
①创建CMakeLists.txt
②创建montage.cpp
③创建工作目录build
3.按照业务逻辑制作相关代码
4.验证效果
上代码:
#include <opencv2/opencv.hpp>
#include <iostream>
#include <cstdio>
using namespace cv;
using namespace std;
int main(int argc, char const *argvc[]) {
int image_count = 39;
//想要生成的图片
Mat srcImage = imread("./xihu1.jpg");
cout << srcImage.size() << endl;
//通过resize方法,进行尺寸设置
resize(srcImage, srcImage, Size(1920, 1080));
cout << srcImage.size() << endl;
//存放资源文件
vector<Mat> source_images;
char filenames[20];
for (int i = 1; i <= image_count; i++) //image_count
{
Mat src_img;
sprintf_s(filenames, "./data/cat%d.jpg", i);
//根据路径读取文件
src_img = imread(filenames);
resize(src_img, src_img, Size(30, 30), 0, 0, INTER_NEAREST);
source_images.push_back(src_img);
}
//cout << source_images.size() << endl;
//imshow("first", source_images[1]);
//制作相关的步骤
int width = srcImage.cols;
int height = srcImage.rows;
//根据宽高 去计算横轴需要的图片个数
//根据颜色进行匹配
//生成对应图片
Mat montageImage;
resize(srcImage, montageImage, Size(1920, 1080));
/*
直方图:
1.根据图片的信息统计出直方图信息
2.根据直方图信息进行匹配
3.替换对应位置的图片
*/
int bins = 128;
int hist_sizes[] = { bins, bins, bins };
float range[] = { 0, 255 };
const float* ranges[] = { range, range, range };
int chanels[] = { 0, 1, 2 };
vector<MatND> hist_list;
for (int i = 0; i < image_count; i++)
{
MatND hist_RGB;
Mat frame;
source_images[i].copyTo(frame);
//计算直方图信息
calcHist(&frame, 1, chanels, Mat(), hist_RGB, 3, hist_sizes, ranges, true, false);
hist_list.push_back(hist_RGB);
}
int number_order = 0;
for (int y = 0; y < height; y += 30)
{
for (int x = 0; x < width; x += 30)
{
Mat roiImage = montageImage(Rect(x, y, 30, 30));
MatND hist_roi;
double match_max = 0.0;
calcHist(&roiImage, 1, chanels, Mat(), hist_roi, 3, hist_sizes, ranges, true, false);
for (int i = 0; i < image_count; i++)
{
double match;
match = compareHist(hist_roi, hist_list[i], HISTCMP_CORREL);
if (match > match_max)
{
//将匹配度最高的值算出来
number_order = i;
match_max = match;
}
}
source_images[number_order].copyTo(roiImage);
printf("正在生成中: \033[01;32m %.2f%% \r", (y / (double)1080 + x / (double)1920 / 100) * 100);
fflush(stdout);
}
}
Mat dstImage;
addWeighted(montageImage, 0.2, srcImage, 0.8, 3, dstImage);
imwrite("dstImage.jpg", dstImage);
imshow("montage", montageImage);
waitKey(0);
return 0;
}
展示效果: