使用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栈类实例分析
Jun 15 Python
python二分查找算法的递归实现方法
May 12 Python
python安装numpy&安装matplotlib& scipy的教程
Nov 02 Python
python机器学习理论与实战(四)逻辑回归
Jan 19 Python
浅谈pandas中DataFrame关于显示值省略的解决方法
Apr 08 Python
Python 确定多项式拟合/回归的阶数实例
Dec 29 Python
python字典一键多值实例代码分享
Jun 14 Python
Django实现web端tailf日志文件功能及实例详解
Jul 28 Python
python手写均值滤波
Feb 19 Python
Python单元测试及unittest框架用法实例解析
Jul 09 Python
python 实现性别识别
Nov 21 Python
pytorch实现手写数字图片识别
May 20 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安全配置 如何配置使其更安全
2011/12/16 PHP
php object转数组示例
2014/01/15 PHP
PHP实现针对日期,月数,天数,周数,小时,分,秒等的加减运算示例【基于strtotime】
2017/04/19 PHP
PHP getNamespaces()函数讲解
2019/02/03 PHP
用 Javascript 验证表单(form)中多选框(checkbox)值
2009/09/08 Javascript
javascript qq右下角滑出窗口 sheyMsg
2010/03/21 Javascript
基于jquery的让页面控件不可用的实现代码
2010/04/27 Javascript
Google Map V3 绑定气泡窗口(infowindow)Dom事件实现代码
2013/04/26 Javascript
100个不能错过的实用JS自定义函数
2014/03/05 Javascript
深入理解JavaScript系列(21):S.O.L.I.D五大原则之接口隔离原则ISP详解
2015/03/05 Javascript
jQuery中next方法用法实例
2015/04/24 Javascript
Bootstrap进度条组件知识详解
2016/05/01 Javascript
Bootstrap CSS布局之表格
2016/12/17 Javascript
微信小程序  http请求封装详解及实例代码
2017/02/15 Javascript
JS实现css hover操作的方法示例
2017/04/07 Javascript
vue-cli如何添加less 以及sass
2017/07/06 Javascript
NodeJS实现同步的方法
2019/03/02 NodeJs
python动态性强类型用法实例
2015/05/09 Python
python使用正则表达式替换匹配成功的组并输出替换的次数
2017/11/22 Python
Django渲染Markdown文章目录的方法示例
2019/01/02 Python
详解Python 解压缩文件
2019/04/09 Python
Python使用dict.fromkeys()快速生成一个字典示例
2019/04/24 Python
python适合做数据挖掘吗
2020/06/16 Python
Python页面加载的等待方式总结
2021/02/28 Python
AmazeUI 图标的示例代码
2020/08/13 HTML / CSS
怎样写演讲稿
2014/01/04 职场文书
爸爸的花儿落了教学反思
2014/02/20 职场文书
小学生学习感言
2014/03/10 职场文书
机关节能减排实施方案
2014/03/17 职场文书
激励员工的口号
2014/06/16 职场文书
海南召开党的群众路线教育实践活动总结大会新闻稿
2014/10/21 职场文书
2015年全国爱耳日活动总结
2015/02/27 职场文书
2015年幼儿园保育工作总结
2015/05/12 职场文书
迁徙的鸟观后感
2015/06/09 职场文书
招商银行收入证明
2015/06/17 职场文书
【海涛教你打dota】体验一超神发条:咱是抢盾专业户
2022/04/01 DOTA