使用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 相关文章推荐
pyqt4教程之messagebox使用示例分享
Mar 07 Python
Python中zip()函数用法实例教程
Jul 31 Python
Python常用列表数据结构小结
Aug 06 Python
用map函数来完成Python并行任务的简单示例
Apr 02 Python
Python映射拆分操作符用法实例
May 19 Python
python 中的int()函数怎么用
Oct 17 Python
Python中常见的异常总结
Feb 20 Python
Python字符串通过'+'和join函数拼接新字符串的性能测试比较
Mar 05 Python
python添加菜单图文讲解
Jun 04 Python
Python编程快速上手——PDF文件操作案例分析
Feb 28 Python
pycharm进入时每次都是insert模式的解决方式
Feb 05 Python
Python 类,对象,数据分类,函数参数传递详解
Sep 25 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 定界符 使用技巧
2009/06/14 PHP
如何用PHP做到页面注册审核
2017/03/02 PHP
PHP中上传文件打印错误错误类型分析
2019/04/14 PHP
点击隐藏页面左栏或右栏实现js代码
2013/04/01 Javascript
基于jquery实现后台左侧菜单点击上下滑动显示
2013/04/11 Javascript
JavaScript中使用Math.PI圆周率属性的方法
2015/06/14 Javascript
JavaScript实现数组随机排序的方法
2015/06/26 Javascript
jquery实现具有嵌套功能的选项卡
2016/02/12 Javascript
利用JQuery写一个简单的异步分页插件
2016/03/07 Javascript
JSON 的正确用法探讨:Pyhong、MongoDB、JavaScript与Ajax
2016/05/15 Javascript
jQuery回到顶部的代码
2016/07/09 Javascript
BootStrap Table 分页后重新搜索问题的解决办法
2016/08/08 Javascript
Javascript中内建函数reduce的应用详解
2016/10/20 Javascript
微信小程序教程系列之新建页面(4)
2017/04/17 Javascript
jQuery实现动态删除LI的方法
2017/05/30 jQuery
Vue2几种常见开局方式详解
2017/09/09 Javascript
浅谈Angular文字折叠展开组件的原理分析
2017/11/24 Javascript
深入理解JavaScript 中的执行上下文和执行栈
2018/10/23 Javascript
通过npm或yarn自动生成vue组件的方法示例
2019/02/12 Javascript
webpack 代码分离优化快速指北
2019/05/18 Javascript
用Vue.js方法创建模板并使用多个模板合成
2019/06/28 Javascript
详解package.json版本号规则
2019/08/01 Javascript
利用一个简单的例子窥探CPython内核的运行机制
2015/03/30 Python
python批量实现Word文件转换为PDF文件
2018/03/15 Python
Python实现一个带权无回置随机抽选函数的方法
2019/07/24 Python
python字符串格式化方式解析
2019/10/19 Python
python多线程高级锁condition简单用法示例
2019/11/07 Python
详解如何用canvas画一个微笑的表情
2019/03/14 HTML / CSS
科室工作个人总结的自我评价
2013/10/29 职场文书
教师师德师风个人整改方案
2014/09/18 职场文书
大学生联谊活动策划书(光棍节)
2014/10/10 职场文书
简短的人生哲理(38句)
2019/08/13 职场文书
读《推着妈妈去旅行》有感1500字
2019/10/15 职场文书
浅析Python中的随机采样和概率分布
2021/12/06 Python
攻击最高的10只幽灵系神奇宝贝,坚盾剑怪排第一,第五最为可怕
2022/03/18 日漫
使用Cargo工具高效创建Rust项目
2022/08/14 Javascript