使用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基础教程之popen函数操作其它程序的输入和输出示例
Feb 10 Python
Python实现list反转实例汇总
Nov 11 Python
Python实现的批量下载RFC文档
Mar 10 Python
Windows下PyMongo下载及安装教程
Apr 27 Python
Python3 加密(hashlib和hmac)模块的实现
Nov 23 Python
Python Paramiko模块的使用实际案例
Feb 01 Python
Python实现账号密码输错三次即锁定功能简单示例
Mar 29 Python
基于FME使用Python过程图解
May 13 Python
使用OpenCV实现道路车辆计数的使用方法
Jul 15 Python
Python实现LR1文法的完整实例代码
Oct 25 Python
python二维图制作的实例代码
Dec 03 Python
利用python进行文件操作
Dec 04 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 curl 上传文件代码实例
2015/04/27 PHP
Thinkphp5 微信公众号token验证不成功的原因及解决方法
2017/11/12 PHP
php实现socket推送技术的示例
2017/12/20 PHP
JS 实现Json查询的方法实例
2013/04/12 Javascript
Javascript中的异步编程规范Promises/A详细介绍
2014/06/06 Javascript
JavaScript中消除闭包的一般方法介绍
2015/03/16 Javascript
javascript常用功能汇总
2015/07/05 Javascript
JS装饰器函数用法总结
2018/04/21 Javascript
Vue Element 分组+多选+可搜索Select选择器实现示例
2018/07/23 Javascript
JavaScript定时器使用方法详解
2020/03/26 Javascript
[30:51]DOTA2上海特级锦标赛主赛事日 - 3 胜者组第二轮#1Liquid VS MVP.Phx第一局
2016/03/04 DOTA
[05:37]DOTA2-DPC中国联赛 正赛 Elephant vs iG 选手采访
2021/03/11 DOTA
[01:23:24]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Elephant BO3 第三场 2月7日
2021/03/11 DOTA
wxPython中listbox用法实例详解
2015/06/01 Python
Python实现App自动签到领取积分功能
2018/09/29 Python
Django框架模板注入操作示例【变量传递到模板】
2018/12/19 Python
浅谈python 读excel数值为浮点型的问题
2018/12/25 Python
Python编程在flask中模拟进行Restful的CRUD操作
2018/12/28 Python
python读取几个G的csv文件方法
2019/01/07 Python
Python线程指南分享
2019/11/19 Python
Python3的unicode编码转换成中文的问题及解决方案
2019/12/10 Python
Python自动巡检H3C交换机实现过程解析
2020/08/14 Python
HTML5实现签到 功能
2018/10/09 HTML / CSS
TripAdvisor德国:全球领先的旅游网站
2017/12/07 全球购物
设计4个线程,其中两个线程每次对j增加1,另外两个线程对j每次减少1。写出程序。
2014/12/30 面试题
高校毕业生自我鉴定
2013/10/27 职场文书
《蚂蚁和蝈蝈》教学反思
2014/02/24 职场文书
《陈涉世家》教学反思
2014/04/12 职场文书
2014年党员自我评议对照检查材料
2014/09/20 职场文书
标准离婚协议书(2014版)
2014/10/05 职场文书
通知函格式范文
2015/04/27 职场文书
2015年教师见习期工作总结
2015/05/20 职场文书
房屋所有权证明
2015/06/19 职场文书
Pandas搭配lambda组合使用详解
2022/01/22 Python
一文弄懂MySQL索引创建原则
2022/02/28 MySQL
MySQL详细讲解变量variables的用法
2022/06/21 MySQL