千人成像

前言

开小差

爬取花瓣网图片

马赛克拼图

(第一步,第二步)

(第三步,第四步)

成效

感谢

018.10.14

前言

昨天,或者说是今天也行,我难得晚睡。到2点的时候让电脑歇息了,人却没有睡意,于是摁亮手机。微博是可以逛逛的。

没承想是迎来这样的画面——

渣浪还自觉帮我播放了这个视频

我……

为什么大半夜了还强迫我吃狗粮???

C可忍,Java或许能忍,Python不能忍!

于是——

PS:不得不说,由于图片源太少,效果有些差。

开小差

说明:手机存有许多女友照片的人请绕道。

我本想去一些“大名鼎鼎”的网站找图片,却得到这样的结果

作为社会主义的接班人,我打心底唾弃这些人拖累国家全面小康建设。都什么年代了,居然连布料多一点的衣服都买不起

老司机我只好凭着一身浩然正气打开了谷歌搜索

(这样的照片我还说个溜溜球)

好了好了,不扯啦。

爬取花瓣网图片

爬取花瓣网不存在什么难点,但需要注意一个地方。在分析图片链接来源的时候

通过浏览器能看到返回来的应该是json数据,但当我们直接requests.get()访问对应接口时,返回来的却是html。经过测试,需要在请求头中加上

此时再去请求,得到的就是json格式的数据了。

可老实说,我更偏爱使用正则,因此直接请求html,再利用re模块解析网页

最后得到两千多张照片

马赛克拼图

千人成像的原理其实就是将一张完整的图片分成许多个小块,通过一定的计算,把每个小块用其他图片(颜色相近的图片)替换。最后给个透明度,把两张图片重合。此时得到的图片就会是开篇的那种效果。倘若图片足够多,颜色足够丰富,效果会更佳。

第一步

首先我们需要对图片裁剪,使得大图片的面积是小图片面积的整数倍。

PIL的ImageOps提供了来实现了裁剪这一功能

这里我对大图片边长的设置为IMG_WIDTH = 6000,每个小图片的宽为SLICE_WIDTH = 60

第二步

好了,我们可能需要了解一下什么是HSV颜色模型了。

在这个模型中,H表示色调,S表示饱和度,V表示明度。更深的东西没必要扩展,你只要知道维基百科中对这个模型有这样一段描述:

艺术家有时偏好使用HSL或HSV而不选择三原色光模式(即RGB模型)或 印刷四分色模式(即CMYK模型),因为它类似于人类感觉颜色的方式,具有较强的感知度。RGB和CMYK分别是加法原色和减法原色模型,以原色组合的方式定义颜色,而HSV以人类更熟悉的方式封装了关于颜色的信息:“这是什么颜色?深浅如何?明暗如何?”。

我们能够从上面解析出人类的认色能力更接近HSV。所以我们引入HSV,是为了让它来充当媒介,把小图片和大图片中的“块”联系起来。

然而Image只为我们提供了获取RGB的方法:

但Python的内置模板预料到我们或许需要RGB转HSV,因此提供了方法。需要注意这个方法接收的参数是[0, 1]中的浮点数,所以使用的时候:

计算一张图片的平均HSV代码如下:

第三步

我们还需要通过大图片的“块”找到颜色相近的小图片。这里有一点选择排序的思想,即设置一个允许值allowedDiff,并认为这个值是最小值,每当出现比它还要小的值的时候,就把更小值赋给allowedDiff。直到不再满足if中的条件为止。

而颜色相似度计算公式为:

第四步

创建画布,在某个位置上截取大图片的“块”,将HSV均值最相近的小图片粘贴到画布的对应的位置上,构成一张由许多小图片组成的大图片。如下所示:

看起来是不是有点感觉了。但因为图片源的色彩不够丰富,所以差异性还蛮大的。我们可以稍稍弥补这个缺陷。利用方法按照一定的透明度,重合新的大图片和原先的大图片,最后保存,就大功告成了。

成效

感谢

参考知乎er 今晚的风儿很喧嚣

https://www.zhihu.com/question/27621722/answer/269085034

参考CSDNer qidu1998

https://blog.csdn.net/qidu1998/article/details/79062663

参考杭州电子科技大学学报

https://wenku.baidu.com/view/f2f1b0f7a58da0116d17490e.html

参考维基百科

https://zh.wikipedia.org/wiki/HSL和HSV色彩空间

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181020G0VLWG00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券