使用opencv处理图片展示montage照片

本项目制作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;
}

展示效果:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值