简介
朋友的生日快到啦,每年都会想一些奇奇怪怪的东西作为礼物= =,机缘巧合下,在b站看到了用多个图片拼接一个大照片思路 ->传送门,这个up用的是一个软件,但是感觉自己也可以用opencv来实现= =,于是便写了这么一个程序……
想想用朋友的偶像照片拼出朋友的自拍感觉会被打XD
源码
步骤
获取图片
主要要获取的图片是需要拼接的大图片和被拼接的小图片。我这边打算用朋友的自拍,小图片的获取比较难,小图片越多颜色会更加贴近,我使用的是200张偶像照片作为资源库。一个个从网上下载下来自然很慢,所以需要爬虫爬取一些照片,不会爬取只能求助一下万能的CSDN^^
->博客的传送门
PS:注意在name.txt里填写你要爬取的照片的关键字
爬取结果如图所示
实现思路
简单的思路就是每一张照片都有大致的色调,我把每个照片从几万像素点resize到几百的像素点,计算平均的RBG值,记录在vector里面。其次对大图进行分块,也是找到块中平均的RGB值,填入最接近的找到最接近的RGB值的小图。
这边有个注意点,如果想做一个高清的拼接图,必须在resize之前就把小图存起来,否则resize后的小图就是像素点……建议调试时用resize之后的小图,等到调试成功的时候再存入原图进行拼接,否则会浪费很多时间在拼接小图上。
遇到的问题
基本上没有什么大问题,小问题像是获取像素点的时候把x和y值搞反了,如果在获取像素点的时候发生了段错误基本上是因为这边–。
改进的思路
关于颜色单一的问题
如果资源库的图片不够多,且大图颜色较为单一时,图像在拼接的时候很容易就出现同一张图片多次出现的情况,这样就不能很好的把所有图片利用起来,这里我想到在每一个小图设置一个优先级priority,使用过一次之后降低它的优先级,允许其他张图片来补充这一块像素,当然为了防止颜色差异过大,仍然需要在一定的误差内。
例如A图和B图和C图,优先级相同都为0,误差计算公式为 $目前最小误差±优先级$ 某一块的RGB均值与三张图的RGB差分别为1,2,4,那么首先找到差值最小的A图,优先级减低为1,其次再寻找的时候再遍历一次三个图,发现B图是优先级最高,且满足误差范围[0,2],故选择B图。
第三次寻找误差范围是[0,3],此时没有高优先级的图满足,所以在优先级为1的图中找误差最小的A图,A图优先级变成2,误差范围[0,4],此时C图满足误差范围且优先级最高,故选择C图,这么选择的话既能保证用上了尽量多的图片,又能保证颜色误差不会过大。
关于识别图像
在找图片对应的时候,用RGB均值差找到相近图像只是一个比较粗略的办法,需要切割到足够小块才能保证和大图相近,但是在现实情况下这么处理很花时间,如果能通过图像识别的方法来处理的话能大大加快对应和拼接的进度,相关知识在下方的博客有介绍:
相似图片搜索的原理