使用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中使用PDB库调试程序
Apr 05 Python
详细解读Python中的__init__()方法
May 02 Python
python爬虫之百度API调用方法
Jun 11 Python
Python编程argparse入门浅析
Feb 07 Python
python使用多进程的实例详解
Sep 19 Python
python实现kmp算法的实例代码
Apr 03 Python
python通过robert、sobel、Laplace算子实现图像边缘提取详解
Aug 21 Python
tesserocr与pytesseract模块的使用方法解析
Aug 30 Python
Python爬虫库BeautifulSoup的介绍与简单使用实例
Jan 25 Python
django 扩展user用户字段inlines方式
Mar 30 Python
keras 解决加载lstm+crf模型出错的问题
Jun 10 Python
Pandas替换及部分替换(replace)实现流程详解
Oct 12 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数组一对一替换实现代码
2012/08/31 PHP
PHP实现手机号码中间四位用星号(*)隐藏的自定义函数分享
2014/09/27 PHP
Laravel 5 框架入门(三)
2015/04/09 PHP
php技术实现加载字体并保存成图片
2015/07/27 PHP
微信公众平台开发教程②微信端分享功能图文详解
2019/04/10 PHP
PHP如何使用array_unshift()在数组开头插入元素
2020/09/01 PHP
JAVASCRIPT keycode总结
2009/02/04 Javascript
$(document).ready(function() {})不执行初始化脚本
2014/06/19 Javascript
下拉框select的绑定示例
2014/09/04 Javascript
使用javascript实现Iframe自适应高度
2014/12/24 Javascript
jQuery实现自定义下拉列表
2015/01/05 Javascript
jQuery Ajax页面局部加载方法汇总
2016/06/02 Javascript
JS短信验证码倒计时功能的实现(没有验证码,只有倒计时)
2016/10/27 Javascript
MvcPager分页控件 适用于Bootstrap
2017/06/03 Javascript
基于构造函数的五种继承方法小结
2017/07/27 Javascript
js断点调试心得分享(必看篇)
2017/12/08 Javascript
微信小程序之分享页面如何返回首页的示例
2018/03/28 Javascript
详解如何给React-Router添加路由页面切换时的过渡动画
2019/04/25 Javascript
详解微信小程序-获取用户session_key,openid,unionid - 后端为nodejs
2019/04/29 NodeJs
vue之延时刷新实例
2019/11/14 Javascript
JavaScript交换变量的常用方法小结【4种方法】
2020/05/07 Javascript
js实现Element中input组件的部分功能并封装成组件(实例代码)
2021/03/02 Javascript
Python内置数据类型详解
2014/08/18 Python
浅谈python for循环的巧妙运用(迭代、列表生成式)
2017/09/26 Python
python2.7实现FTP文件下载功能
2018/04/15 Python
Python Json模块中dumps、loads、dump、load函数介绍
2018/05/15 Python
Python3+django2.0+apache2+ubuntu14部署网站上线的方法
2018/07/07 Python
django实现模型字段动态choice的操作
2020/04/01 Python
菲律宾旅游网站:Expedia菲律宾
2017/10/11 全球购物
澳大利亚连衣裙和女装在线:Esther
2017/11/11 全球购物
不遵守课堂纪律的检讨书
2014/09/24 职场文书
2015年党员个人剖析材料
2014/12/18 职场文书
中秋客户感谢信
2015/01/22 职场文书
南京导游词
2015/02/03 职场文书
入党积极分子考察意见
2015/06/02 职场文书
村官2015年度工作总结
2015/10/14 职场文书