使用Python制作缩放自如的圣诞老人(圣诞树)


Posted in Python onDecember 25, 2019

圣诞节又要到了,虽说我们中国人不提倡过西方的节日,但是商家们还是很喜欢的,估计有对象的男孩纸女孩纸们也很喜欢吧。

使用Python制作缩放自如的圣诞老人(圣诞树)

今天的主题是为大家展示如何用python做一个不断变大的圣诞老人,就像西游记中能够随意变幻大小的神仙妖怪那样,算是送给大家的小礼物,先上个图吧!

使用Python制作缩放自如的圣诞老人(圣诞树)

不要心急,盯着图片看5秒

思路要点:

  • 通过缩放获取等比大小的一组图片
  • 将上述图片叠加到固定大小的底图中
  • 按顺序组合图片生成动图

1、图片缩放

本篇文章的大部分工作都是基于opencv实现,而opencv进行图片缩放是极其容易的,不过这次我们要生成的是一组等比缩放的图片,所以在cv2.resize方法的使用上可能跟以往略有出入,先来看函数原型:

cv2.resize(src, dsize[, dst[, fx[, fy[, interpolation]]]])

其中src是原图片,dsize是目标图片大小,当dsize为0的时候,我们就可以通过fx和fy两个参数来分别设置水平轴和垂直轴方向的缩放比例了。这样说可能有些抽象,我们举个例子来说明:

for i in range(1, 40, 1): 
 img = cv2.resize(image, (0, 0), fx=i/30, fy=i/30) 
 cv2.imwrite(str(i)+'.png', img)

运行上面这段代码会生成39张不同比例的图片,目标图片的大小由缩放比例fx和fy来控制,最小的一幅图边长是原图的1/30,最大的图片边长是原图的1.3倍(下图):

使用Python制作缩放自如的圣诞老人(圣诞树)

既然等比缩放的图片有了,是不是可以选定一个坐标原点,直接合成动图呢?答案是不行,因为常规的动图生成方法要求素材图片必须是相同的尺寸(像素),下面我们就来着重解决这一问题。

2、底图叠加

python中实现两幅图片叠加的办法有很多,但是他们都存在缺陷——要么叠加的图片必须是相同大小,要么难以控制图片叠加的具体位置。对此,小编采取的办法是在两幅图之间进行“像素级”的替换。

1).生成底图

待叠加的图片中,上层图片就使用刚才获取到的一系列等比缩放图,下层图片我们就生成一张固定大小的空白图片。需要注意,这里生成的空白图片必须大于最大的一幅缩放图。

生成空白底图分两步完成,第一步生成固定大小(垂直轴和水平轴的长度)的二维数组;第二步使用cv2.cvtColor进行颜色空间变换。代码如下:

blank = np.ones((blankh, blankw), dtype=np.uint8) * 255 
ret = cv2.cvtColor(blank, cv2.COLOR_GRAY2BGR)

其实上面代码中的ret本质上是一个三维数组,我们可以把它打印出来查看(下图),但是通过cv2.imshow方法展示出来就是一张空白图片了。这其中涉及一些较为底层的内容,大家了解就好,文中不再赘述。

使用Python制作缩放自如的圣诞老人(圣诞树)

2).像素替换

正如刚才所说,opencv中的一幅图其实是一个三维数组,其实也可以把它看作是二维数组,数组中的

每个元素是形如 [255, 255, 255] 的列表,其中存放的是图片每个像素的颜色参数。也就是说,如果我们想实现一幅图片叠加到另一幅图片这样的视觉效果,可以对被叠加图片对应位置的

像素进行替换赋值。代码形式如下图所示,其中i和j分别为图片在垂直方向和水平方向的坐标。

ret[i, j, 0] = image[i, j, 0] 
ret[i, j, 1] = image[i, j, 1] 
ret[i, j, 2] = image[i, j, 2]

对一幅图片而言,坐标原点是在左上角(下图所示)。此外,为了保证最终得到动图的效果,不能简单的将图片以坐标原点为基准进行叠加,比较好的办法是把叠加原点设在底图下边缘的中心位置。

使用Python制作缩放自如的圣诞老人(圣诞树)

原理搞清楚后就可以开始图片叠加操作了,在此期间需要进行一些像素对应位置的计算,虽然稍微有点绕但是并不复杂,详细的转化公式就不写了,我们直接看代码:

使用Python制作缩放自如的圣诞老人(圣诞树)

上面代码中的image是已经缩放完毕的圣诞老人图片,blankh和blankw分别是空白图片的高度和宽度,这个尺寸可以根据需求自行设置。

下图展示的是一幅缩放比例1/2左右的图片和底图叠加后的效果,为了观察方便,我给图片加了一个边框。

使用Python制作缩放自如的圣诞老人(圣诞树)

3、生成动图

之前我们已经解决了单幅图片与底图的叠加,为了准备合成动图所需素材,还要对多个等比缩放的图片进行底图叠加操作。缩放比例间隔越小、准备的图片素材越多,生成的动图也就越平滑。

当然,动图的效果如何还要综合考虑多个因素,这里小编还是采用39幅图片组合动图。其中最小的图形高度是原图的1/30,最大的图形高度是原图的1.3倍。与底图叠加后的图片就是下面这个样子。

使用Python制作缩放自如的圣诞老人(圣诞树)

下面来说说动图的合成,将多个相同尺寸的图片合成动图可以使用imageio这个库来实现,核心代码只有一条:

imageio.mimwrite('目标文件名称.gif', gifList, duration=0.15)

其中第一个参数是git目标文件名称;gifList是一组列待合成的图片,也就是上面图片中展示的那些;最后一个参数duration表示画面切换间隔,单位为秒。

现在通过下面这段代码进行动图合成。

file_path = 'pic' 
imgList = os.listdir(file_path) 
imgList = ['pic/'+img for img in imgList] 
gifList = [imageio.imread(img) for img in imgList] 
imageio.mimwrite('gif.gif', gifList, duration=0.15)

来看合成后的动图效果(下图),仔细看看好像有点问题,怎么图中的圣诞老人忽大忽小?这跟我们预想的不一样啊。

使用Python制作缩放自如的圣诞老人(圣诞树)

其实这个问题是出在合成图片的顺序上,我们尝试打印上面代码中的imgList变量,结果如下:

使用Python制作缩放自如的圣诞老人(圣诞树)

可以看到,素材图片并不是按照我们预想的顺序排序。这在python的文件处理中也算是个比较常见的问题,解决方案之一是可以按照图片的创建时间排序,具体操作是在上面的第二行代码之后插入一条语句:

imgList = sorted(imgList,key=lambda x: os.path.getmtime(os.path.join(file_path, x)))

现在再次进行动图合成,就可以实现文章开头的效果了。

当然了,这种动图制作方法不仅限于圣诞老人,任何图片理论上都是可以的。比如说,我们还可以做一棵不断长大的圣诞树!

总结

以上所述是小编给大家介绍的使用Python制作缩放自如的圣诞老人,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Python 相关文章推荐
Python中Collection的使用小技巧
Aug 18 Python
Python科学计算之Pandas详解
Jan 15 Python
Django查询数据库的性能优化示例代码
Sep 24 Python
Python cookbook(数据结构与算法)在字典中将键映射到多个值上的方法
Feb 18 Python
python异步实现定时任务和周期任务的方法
Jun 29 Python
python3.6+django2.0+mysql搭建网站过程详解
Jul 24 Python
Python3 chardet模块查看编码格式的例子
Aug 14 Python
Python的几种主动结束程序方式
Nov 22 Python
flask实现验证码并验证功能
Dec 05 Python
python 使用事件对象asyncio.Event来同步协程的操作
May 04 Python
Python的历史与优缺点整理
May 26 Python
在Django中使用MQTT的方法
May 10 Python
python 实现list或string按指定分段
Dec 25 #Python
python cv2在验证码识别中应用实例解析
Dec 25 #Python
python中的逆序遍历实例
Dec 25 #Python
Win系统PyQt5安装和使用教程
Dec 25 #Python
Python3 把一个列表按指定数目分成多个列表的方式
Dec 25 #Python
Python3 main函数使用sys.argv传入多个参数的实现
Dec 25 #Python
Win下PyInstaller 安装和使用教程
Dec 25 #Python
You might like
php读取html并截取字符串的简单代码
2009/11/30 PHP
Zend framework处理一个http请求的流程分析
2010/02/08 PHP
php方法调用模式与函数调用模式简例
2011/09/20 PHP
<script defer> defer 是什么意思
2009/05/10 Javascript
jQuery中animate动画第二次点击事件没反应
2015/05/07 Javascript
JavaScript编写检测用户所使用的浏览器的代码示例
2016/05/05 Javascript
js通过classname来获取元素的方法
2016/11/24 Javascript
网站发布后Bootstrap框架引用woff字体无法正常显示的解决方法
2016/11/24 Javascript
Web技术实现移动监测的介绍
2017/09/18 Javascript
微信小程序实现图片压缩功能
2018/01/26 Javascript
分享5个顶级的JavaScript Ajax组件库
2018/09/16 Javascript
详解解决Vue相同路由参数不同不会刷新的问题
2018/10/12 Javascript
详解Vue源码学习之双向绑定
2019/04/10 Javascript
微信小程序pinker组件使用实现自动相减日期
2020/05/07 Javascript
JQuery实现折叠式菜单的详细代码
2020/06/03 jQuery
解决vue一个页面中复用同一个echarts组件的问题
2020/07/19 Javascript
python连接mysql并提交mysql事务示例
2014/03/05 Python
详解字典树Trie结构及其Python代码实现
2016/06/03 Python
Django数据结果集序列化并展示实现过程
2020/04/22 Python
python 多线程死锁问题的解决方案
2020/08/25 Python
Python爬虫之Selenium实现关闭浏览器
2020/12/04 Python
常用的四种CSS透明属性介绍
2014/04/12 HTML / CSS
京东港澳售:京东直邮港澳台
2018/01/31 全球购物
会话Bean的种类
2013/11/07 面试题
酒店管理求职信范文
2014/04/06 职场文书
职业道德模范事迹材料
2014/08/24 职场文书
副校长竞聘演讲稿
2014/09/01 职场文书
群众路线剖析材料
2014/09/30 职场文书
行政执法队伍作风整顿剖析材料
2014/10/11 职场文书
公路局群众路线教育实践活动第一阶段工作汇报
2014/10/25 职场文书
教师个人学习总结
2015/02/11 职场文书
2015年党日活动总结范文
2015/03/25 职场文书
节约用电通知
2015/04/25 职场文书
合同审查法律意见书
2015/06/04 职场文书
毕业感言怎么写
2015/07/31 职场文书
演讲稿:态度决定一切
2019/04/02 职场文书