建了一个qq群:222954293,既方便大家一起交流学习,还可以传一些程序文件,欢迎大家加入交流。程序源码我就放群里啦。

前言

大家好呀,前两天烈阳天道1上映了,不知道大家看没看呢,里面还有一小段彦穿越虫洞与猴哥相遇的画面,彦女王啊啊啊~~

所以我去网上爬了二百来张我大学的风景画,然后找了以前存的彦女王的图片,生成了一幅蒙太奇画像。然后我两个热爱的就合体啦!

先看一下什么是蒙太奇图像吧,其实你肯定见过,只不过不知道叫蒙太奇而已:

一张大的图片,是由很多小的图片拼接而成的这种,就是蒙太奇图像啦(或者叫马赛克拼图),我要做的就是把我大学的风景图拼成彦的图片。

综述实现思路

文末附有python代码,本文为我写的C++代码

1:读取文件夹内的风景图片集,将每张剪裁到90*45大小并存入Mat容器内

2:将图片模板(彦的照片)扩大为1600*2700大小

3:计算图片集的直方图并将结果存到MatND容器内(直方图容器)

4:双重for循环以90*45的步长遍历图片模板计算各个区域的直方图,并将区域直方图与图片集的直方图进行比对,得到相似度最高的风景图片,将该风景图片替换模板对应区域

5:将4步得到的蒙太奇图与原模板图线性相加,得到更为逼真的效果

是不是很简单的过程?但就这么个过程,我调了一天的bug,然后被迫深入理解了C++的动态回收机制… … 建议感兴趣的小伙伴自己实现一下。

以下代码在主函数内顺次复制粘贴即可

1:读取图片集并预处理

//【1】图片集的采集与处理
int Images_number = 256;//图片集中图片的数量
int step_x = 80; //将图片剪裁为80*45大小
int step_y = 45;Mat srcImage;
vector<Mat> load_Images;//图片集容器
char filename[30];//存储图片名字
for (int i = 0; i < Images_number; i++) {Mat dstImage;sprintf_s(filename, "./风景图/ysu (%d).jpg", i);cout << filename << endl;srcImage = imread(filename); //Mat类图像resize(srcImage, dstImage, Size(step_x, step_y), 0, 0, INTER_NEAREST);load_Images.push_back(dstImage);
}
cout << "图片加载完毕" << endl;

主要用到了利用sprintf函数得到图片集有规律的命名,然后for循环依次将imread到的图片push_back添加到Mat容器内就可以了。

二百多张图片如何快速整齐的命名,,,看链接。

https://jingyan.baidu.com/article/b87fe19e4834a95218356814.html

2:调整原模板图的尺寸大小

//【2】将原模板图扩大到合适尺寸
Mat originalImage, showImage;
originalImage = imread("彦.jpg");
imshow("彦", originalImage);
resize(originalImage, showImage, Size(1600, 2700));

没啥好说的,就在基本保持原先长宽比例的条件下,让长宽都是90*45(图片集被裁剪的大小)的整数倍就好了。

3:计算图片集直方图

//【3】计算图片集的直方图
int width = showImage.cols; //模板图的长宽
int height = showImage.rows;
Mat frame;
vector<MatND> hsit_list;//直方图容器
//计算直方图的参数准备
int bins = 128; //直条数
int hist_sizes[] = { bins,bins,bins }; //存放每个维度的直方图尺寸数组 //  均为256条宽度
float range[] = { 0,256 };  //每一维数组的取值范围  // 均为0-255高度
const float* ranges[] = { range,range,range };
int channels[] = { 0,1,2 };
//for循环计算图片集的直方图并存储
for (int i = 0; i < Images_number; i++) {/*load_Images[i].copyTo(frame);*/MatND hsit_RGB;Mat frame;load_Images[i].copyTo(frame);calcHist(&frame, 1, channels, Mat(), hsit_RGB, 3, hist_sizes, ranges, true, false);hsit_list.push_back(hsit_RGB);
}

和第一步套路类似,循环计算了图片集所有图的直方图并存储到了一个直方图容器内。

4:遍历彦模板图,计算每一小块的直方图并对比,替换

//【4】遍历,寻找最匹配的图片并替换
int number_order;
for (int x = 0; x < height; x = x + step_y) {for (int y = 0; y < width; y = y + step_x) {Mat roiImage = montageImage(Rect(y, x, step_x, step_y));//Rect(y, x, step_x, step_y)//参数准备MatND hsit_roi;double match_ = 0.0;//匹配度calcHist(&roiImage, 1, channels, Mat(), hsit_roi, 3, hist_sizes, ranges, true, false);for (int i = 0; i < Images_number; i++) {double match;match = compareHist(hsit_roi, hsit_list[i], HISTCMP_CORREL);if (match > match_) {//寻找对比对最高的number_order = i;match_ = match;}}load_Images[number_order].copyTo(roiImage);}
}
cout << "【4】遍历,寻找最匹配的图片并替换成功" << endl;

首先两个步长分别为step_y和step_x的循环是遍历原图模板各个小块区域,并计算该块的直方图。

之后用一个for循环在第三步得到的直方图容器内,寻找与该块直方图匹配度最高的风景图片,然后将该风景图片替换原图对应区域。

到此运行完毕我们就可以得到一个不太完美的蒙太奇图片了:

虽然有些粗糙,但已经可以看出来了叭!效果可以调节裁剪的大小或者原图模板的大小来改善。但以我代码设置的参数,执行完都要好几分钟,如果有什么优化建议可以交流哈。

来看看女王的腿!

嗯,,竟然是用碑组成的。

我们还可以通过第五步,将上图左图与右图加权得到更为逼真的蒙太奇画像。

5:将效果图与原图加和

Mat dstImage;
addWeighted(showImage, 0.4, montageImage, 0.6, 0, dstImage);
imwrite("结果图.jpg", dstImage);
imwrite("show.jpg", montageImage);

加和后的效果图:

效果是不是好一些了?可以更改参数使效果更好。由于我还有毛概论文没写,就不瞎搞了~

THE END

本文灵感来自知乎@三木青年,代码都是我自己敲的,网上关于蒙太奇的大概只有我用的C++了,python代码可以看知乎链接:

https://zhuanlan.zhihu.com/p/168667043

同时欢迎大家关注公众号【Opencv视觉实践】,分享有趣好玩涨知识的案例哦。
这么骚的一篇文,你们真的不想来评论区和我说两句?看在彦的面子上给个赞吧!

用opencv给彦女王生成一副蒙太奇画像相关推荐

  1. 生成step文件_利用opencv给彦女王生成一副蒙太奇画像

    大家好呀,前两天烈阳天道1上映了,不知道大家看没看呢,里面还有一小段彦穿越虫洞与猴哥相遇的画面,彦女王啊啊啊~~ 所以我去网上爬了二百来张我大学的风景画,然后找了以前存的彦女王的图片,生成了一幅蒙太奇 ...

  2. 基于Matlab OpenCV的随机性形状生成算法

    文章目录 一.写在前面 1.前言 2.软件版本信息 3.出发点 二.输出结果展示 1.Matlab中 2.OpenCV中 三.原理 1.原理总述 2.Matlab 3.OpenCV 四.代码 1.Ma ...

  3. 使用Python+OpenCV+dlib为人脸生成口罩

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达推荐阅读 42个pycharm使用技巧,瞬间从黑铁变王者Google ...

  4. 用Cmake编译Opencv源码,生成动态库

    前期准备:安装Cmake和VS2010 一安装Cmake 1 . 2. 3. 二. 1. 将OpenCV2.4.9安装于以下目录: G:/opencv2.4.9 2. 使用CMake建立VS工程文件  ...

  5. 利用Opencv保存图片,并生成JPG格式,调整压缩质量。

     例如Photoshop软件保存JPG图像时有低.中.高和最佳的保存选项设置,对应生成的图像的大小也不同.用OpenCV生成的图像相对较大,可能类似对应Photoshop最佳的那种保存的,但是我想 ...

  6. 在OpenCV里实现棋盘生成

    在图像的算法处理里,经常要使用一些标准的图像来做测试,比如棋盘图像就是其中之一,它经常使用来测试一些噪声.摄像头校准等等.下面就来使用OpenCV来生成一些棋盘图像,如果你想生成文件,直接使用前面的保 ...

  7. 面部表情识别java_使用Python+OpenCV+dlib为人脸生成口罩

    来源:深度学习与计算机视觉 本文约4800字,建议阅读6分钟本文试图用OpenCV和dlib库来实现这个过程,在这里我们综合生成5种类型的口罩来绘制人脸图像. 本文使用OpenCV dlib库生成口罩 ...

  8. opencv读取黑白图片生成凹凸效果图

    黑白图 opencv 凹凸效果图 记录一下,有空再补充

  9. python生成一副扑克牌_【扑克游戏基本】用python打造出一副扑克牌并实操大转变...

    今天要用python写一副简单的扑克牌, 我们想用物件导向的概念, 分别定义类别「单张扑克牌」与「一副扑克牌」, 而「一副扑克牌」就由52张「单张扑克牌」所组成 类别- 单张扑克牌 一张扑克牌由「点数 ...

最新文章

  1. maven发布项目到私服-snapshot快照库和release发布库的区别和作用及maven常用命令
  2. Android Material各种颜色设置
  3. 汪潮涌:AI创业落地为王,技术和算法难以成为核心壁垒
  4. hive查看表中列的信息命令_快速了解hive
  5. [unreal4入门系列之十五] UE4中的动态数组:TArray容器
  6. Java阶段性测试--第二三大题参考代码
  7. java 不可修改的map_Java中如何实现不可变Map详解
  8. 【C/C++】递归算法
  9. 初识JAVA--foreach语句的应用
  10. C# 如何理解 ASP.NET Web API 的 REST
  11. oracle增量备份level0,Oracle备份类型level0、level1,增量、差异备份
  12. 某些网站加载的zul文件和zk文件是什么东西
  13. java pdf分页显示_使用iText“重新分页”PDF
  14. ICP备案线下注销 网站域名备案注销
  15. 台式/笔记本无线网卡_异常问题
  16. office(word)如何使用格式刷的方法。
  17. Android中使用sqlite数据库实现对象的存储
  18. 日期函数之Dateadd、Datediff
  19. 微信小程序用户自动检测最新版本并更新2020年最新版亲测
  20. 美团外卖广告智能算力的探索与实践

热门文章

  1. 【口胡】【坑:对偶问题】【Codeforces 671D】【JZOJ 5369】 幽雅的绽放吧,墨染之樱
  2. JS判断字符串是否为json字符串
  3. ubuntu20.04不显示wifi图标
  4. 怎样写出引人注目的求职简历?
  5. Mockito的@Mock与@MockBean
  6. ColorUI组件库简易教程之扩展插件
  7. scanf(“%3c%3c“, a, b)
  8. java中数学函数的使用
  9. c语言父亲节快乐,Happy Fathers Day 父亲节快乐(中英双语)-喜马拉雅
  10. 树莓派 NOOBS 安装系统