当前位置: 首页 > 编程日记 > 正文

美翻朋友圈:用Python生成蒙太奇马赛克图片

题图 | 视觉中国

来源 | ZackSock(ID:ZackSock)

我们有时候会听到这么一个词--“蒙太奇”,但却不知道这个词是什么意思。蒙太奇原为建筑学术语,意为构成、装配。而后又延伸为一种剪辑理论:当不同镜头拼接在一起时,往往又会产生各个镜头单独存在时所不具有的特定含义。

这就是我们经常听到了蒙太奇手法,在电影《飞屋环游记》中皮克斯运用蒙太奇手法,用一个不到5分钟的短片展现了主角的大半人生,感动无数观众。下面我们就看看今天的内容同蒙太奇有何关系。

效果展示

说这么多都是虚的,下面我们看看实现的效果,到底什么是蒙太奇马赛克图片,这里用小松菜奈的照片作为测试:

原图效果图对比


最左边的是蒙太奇图缩小的效果,第二个则是正常大小显示的效果,第三张是原图,第四张是截取的某个区域的细节。从图四可以很容易看出,我们的蒙太奇图片是使用许多不同的图片拼接而成的。

代码实现

程序的实现分为几个步骤,首先我们需要准备工作,一个是我们的底图,也就是上面的图三。另外就是需要一个图片集,这个图片集的选取有几个规范,首先不能有gif图和png图片,其次就是图片的颜色尽量丰富,图片数量也多一些,这样效果会更好。另外就是选取长宽比接近1的图片效果会更好。然后就是我们代码部分的工作了:

  1. 图片预处理

  2. 获取颜色的主色调列表

  3. 遍历底图的每个像素块

  4. 在色调列表中寻找与当前色调块最相近的图片

  5. 将图片修改大小后粘贴到当前遍历的色调块

  6. 保存图片

大家对于上面的步骤或许还有些疑问,这些疑问在具体实现中细说。先看看我们要用到的一些模块:

import os
import cv2
import math
import numpy as np

其中opencv的安装如下:

pip install opencv-python

3.1、图片预处理

人工挑图片还是比较麻烦的,所以我们只要求人先挑好一些图片,然后我们将不符合规范的图片删除即可:

def renameImages(path)://获取图片路径列表filelist = [path + i for i in os.listdir(path)]//用数字给图片命名img_num = str(len(filelist))name = int(math.pow(10, len(img_num)))//遍历列表for file in filelist://删除gif和png图片if file.endswith('.gif') or file.endswith('.GIF') or file.endswith('.png') or file.endswith('.PNG'):os.remove(file)continue# 对图片以数字编号重命名os.rename(file, path + str(name) + '.jpg')name += 1

执行上面的方法后我们就把合适的图片筛选出来了。

3.2、获取颜色的主色调列表

获取主色调列表前我们需要先获取主色调,这里直接使用bgr值的平均值作为主色调:

def getDominant(im):"""获取主色调"""b = int(round(np.mean(im[:, :, 0])))g = int(round(np.mean(im[:, :, 1])))r = int(round(np.mean(im[:, :, 2])))return (b, g, r)

通常RGB模式的图片我们接触的比较多,但是在OpenCV中图片是以BGR模式读取,每个字母的含义是一样的,只是顺序不同,这里需要注意一下。接下来我们获取主色调列表:

def getColors(path):"""获取图片列表的色调表"""colors = []# 获取图片列表filelist = [path + i for i in os.listdir(path)]# 遍历列表for file in filelist:# 读取图片im = cv2.imdecode(np.fromfile(file, dtype=np.uint8), -1)try:# 获取图片主色调dominant = getDominant(im)except:continue# 将主色调添加到色调列表中colors.append(dominant)return colors

有了色调列表,我们对比颜色的操作就可以直接同色调列表进行了。

3.3、寻找主色调最接近的图片

我是通过比较两张图片主色调的BGR值,然后将差的绝对值相加的方式获得色调的差异:

def fitColor(color1, color2):"""返回两个颜色之间的差异大小"""# 求出b通道之间的差异b = color1[0] - color2[0]# 求出g通道之间的差异g = color1[1] - color2[1]# 求出r通道之间的差异r = color1[2] - color2[2]# 返回绝对值的和return abs(b) + abs(g) + abs(r)

3.4、遍历,寻找并粘贴

这里就是我们的方法主体了,内容比较多,我们先看看代码:

def generate(im_path, imgs_path, box_size, multiple=1):"""生成图片"""# 读取图片列表img_list = [imgs_path + i for i in os.listdir(imgs_path)]# 读取图片im = cv2.imread(im_path)im = cv2.resize(im, (im.shape[1]*multiple, im.shape[0]*multiple))# 获取图片宽高width, height = im.shape[1], im.shape[0]# 遍历图片像素for i in range(height // box_size+1):for j in range(width // box_size+1):# 图块起点坐标start_x, start_y = j * box_size, i * box_size# 初始化图片块的宽高box_w, box_h = box_size, box_size# 截取当前遍历到的图块box_im = im[start_y:, start_x:]if i == height // box_size:box_h = box_im.shape[0]if j == width // box_size:box_w = box_im.shape[1]if box_h == 0 or box_w == 0:continue# 获取主色调dominant = getDominant(im[start_y:start_y+box_h, start_x:start_x+box_w])img_loc = 0# 差异,同主色调最大差异为255*3dif = 255 * 3# 遍历色调表,查找差异最小的图片for index in range(colors.__len__()):if fitColor(dominant, colors[index]) < dif:dif = fitColor(dominant, colors[index])# 色调列表同图片列表的位置是一致的,所以我们获取色调下标即可img_loc = index# 读取差异最小的图片,img_list[img_loc]为差异最小的图片box_im = cv2.imdecode(np.fromfile(img_list[img_loc], dtype=np.uint8), -1)# 转换成合适的大小box_im = cv2.resize(box_im, (box_w, box_h))# 铺垫色块im[start_y:start_y+box_h, start_x:start_x+box_w] = box_imj += box_wi += box_h# 返回结果图return im

首先我们看看传入的参数都是什么含义:

im_path    : 底图的路径
imgs_path : 图片列表的根目录
box_size : 像素块的大小
multiple=1 : 图片的缩放大小,默认为1

前面两个参数非常好理解。对于box_size参数的解释就是效果图四种,每张照片的尺寸,因为我全部以正方形处理,所以只有一个大小。而multiple参数则是缩放大小,当我们底图为50*50没有设置缩放时,结果图也是50*50,当我们将缩放设置为2,结果图则为100*100。因为图片太小的话看不到像素块中的图片,所以利用缩放让效果更好,但是缩放值设置过大的话图片内存会大许多。其它部分的解释都在代码中了。最后再给大家看一张效果图:

效果图片


因为事先效果不是非常乐观,所以给大家看一张朦胧的效果图。

推荐阅读

  • 真没想到,Python 还能实现 5 毛特效

  • 作词家下岗系列:教你用 AI 做一个写歌词的软件

  • AI修复100年前晚清影像喜提热搜,这两大算法立功了

  • 阿里云自研数据仓库 AnalyticDB 再捧 TPC 全球冠军

  • 调查了 17,000 多位程序员,当前的云原生开发现状究竟如何?

  • CSW:惊天巨骗 or 比特币“图腾”中本聪?

  • 从 0 到 70%:Chrome 上位揭秘!

  • 你点的每个“在看”,我都认真当成了AI

相关文章:

在SQL Server 2008中配置文件流(FILESTREAM)

SQL Server 2008推出了一个新的特性叫做文件流(FILESTREAM)&#xff0c;它使得基于SQL Server的应用程序可以在文件系统中存储非结构化的数据&#xff0c;例如文档、图片、音频、视频等等。文件流主要将SQL Server数据库引擎和新技术文件系统(NTFS)集成在一起;它主要以varbinar…

mysql limit offset

Java代码 SELECT keyword FROM keyword_rank WHERE advertiserid59 order by keyword LIMIT 2 OFFSET 1; 比如这个SQL &#xff0c;limit后面跟的是2条数据&#xff0c;offset后面是从第1条开始读取 Java代码 SELECT keyword FROM keyword_rank WHERE advertiserid59 order …

获取磁盘符信息

项目中有个子模块是ftp客户端&#xff0c;需要罗列本地各个磁盘符&#xff0c;比如C盘、D盘、E盘、F盘。然后进行一些相关的上传下载就比较方便&#xff0c;具体样子如下所示&#xff1a; 需要利用一个Combox控件实现。 废话不多说&#xff0c;先上代码&#xff1a; void …

成为计算机视觉工程师的第一个月,我都学会了什么?

作者 | Richmond Alake译者 | 弯月题图 | 自视觉中国出品 | AI科技大本营&#xff08;ID&#xff1a;rgznai100&#xff09;我写这篇文章的目的是为了向那些没有接触过机器学习行业的人们介绍一下我作为计算机视觉工程师第一个月以来的体验&#xff0c;希望这些内部信息能够让你…

天然良方对付小病

打嗝、口臭、消化不良……我们的身体时常会受到一些小毛病的困扰。20位来自美国各大医院的权威医生在美国《预防》杂志网站上发表文章&#xff0c;向读者介绍了一些纯天然的便捷方法&#xff0c;来快速应对这些小病。 生姜止吐。先用热水冲泡生姜片&#xff0c;过滤后把姜汤倒在…

Spring中使用Schedule调度

在spring中两种办法使用调度&#xff0c;以下使用是在spring4.0中。 一、基于application配置文件&#xff0c;配置入下&#xff1a; 1 <bean id"jobDetail" class"org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">…

DNS域名解析优化之tinydns/djbdns篇——测试篇

要开始还债了。 今天整理了一下一套bind9的配置&#xff0c;把记录都清理了一番。想了想&#xff0c;顺带安装了个geoipdns来做性能测试。整理记录的时候用bind-to-tinydns转换了一下记录格式。这些过程以后再说。 NS服务器是同一台Dell PowerEdge 2950。先启动的geoipdns&…

使用Combox控件的一个问题

Combox控件是MFC里边一个比较常用的控件&#xff0c;基本可以看成是一个文本框和一个下拉列表组合而成。但是我在用的时候碰到了一个问题&#xff0c;当我用AddString()函数加了4,5个字符串后&#xff0c;运行之后点击下拉箭头并没有下拉框的显示&#xff0c;或者说显示不出来。…

深度学习基础总结,无一句废话(附完整思维导图)

作者 | Python与算法社区责编 | Carol封图 | CSDN 付费下载于自视觉中国线型回归预测气温、预测销售额、预测商品价格等模型&#xff1a;权重&#xff0c;偏差模型训练&#xff1a;feed 数据学习模型参数值&#xff0c;使得误差尽可能小训练集、测试集、验证集、样本、标签、特…

unity, monoDevelop ide 代码提示不起作用的解决方法

monoDevelop ide 代码提示不起作用&#xff0c;可能是因为ide里索引了一些不存在的文件&#xff0c;检查一下solution窗口里是否有文件变红&#xff0c;如下图中springControlEx.cs。将变红的文件remove掉&#xff0c;然后去unity菜单中点File->Save Project。

DeeCamp 2020 赛题大公开!快来看你想选哪个

DeeCamp 2020 开放性竞赛赛题来啦&#xff0c;快来看看有没有你感兴趣的题目&#xff01;加入DeeCamp2020&#xff0c;你将和来自全球的优秀小伙伴组队挑战真实世界的难题&#xff0c;还能冲刺大奖。五大赛道&#xff0c;14个新颖赛题&#xff0c;总有一款适合你&#xff01;De…

Combox控件下拉选择不同值触发的动作响应

项目中需要根据combox控件下拉列表选择不同的值&#xff0c;然后能触发相应的动作。比如我的项目中&#xff0c;通过combox空间的下拉列表选择不同的C盘&#xff0c;D盘&#xff0c;E盘&#xff0c;F盘&#xff0c;然后能在list控件中把各个盘符的文件目录列出来。 那么触发…

不用se11创建表结构,作smartforms

Call form时不用传内表&#xff0c;切记。 1。在Global Definitions->types页面里输&#xff1a; types:begin of wa_test, matnr like mara-marnt, maktx like makt-maktx, end of wa_test. types:it_test type wa_test occurs 1. 2. 在Global Definitions->Global Data…

linux入门(三)常见Linux指令及其用法

一、上回说到说到Linux的shell指令运行的原理&#xff0c;这回我们来看看Linux中shell的权限管理&#xff0c;所谓的“权限”是指某一类人做某一件事的权利。在shell中这一类人被分为了三种&#xff1a;&#xff08;1&#xff09;文件拥有者user&#xff08;2&#xff09;文件拥…

设置Enter键为默认键

进行MFC编程中&#xff0c;很多时候需要设置快捷键&#xff0c;比如我的项目中&#xff0c;播放器的实现&#xff0c;需要快进、快退、播放、暂停等&#xff0c;除了具体的按钮操作外应该还能通过键盘的快捷键来进行操作。 关于如何设置一个菜单的快捷键或是一个按钮的快捷键&…

MAML-Tracker:用目标检测思路做目标跟踪?小样本即可得高准确率丨CVPR 2020

来源 | 微软研究院AI头条&#xff08;ID: MSRAsia&#xff09;编者按&#xff1a;目标检测与目标跟踪这两个任务有着密切的联系。针对目标跟踪任务&#xff0c;微软亚洲研究院提出了一种通过目标检测技术来解决的新视角&#xff0c;采用简洁、统一而高效的“目标检测小样本学习…

从哲学角度分析,框架的[无用之用]效果

小树的用途少&#xff0c;人们不理睬它、不砍伐它、才有机会长成有用之巨木&#xff0c;此为「无用」之用﹗老子说过&#xff1a;「人皆知有用之用&#xff0c;而莫知无用之用」&#xff0c;这与框架观念是一致的。 数千年前&#xff0c;老子提出了这「有、无」哲理&#xff0c…

xtrabackup2.4 备份Precona5.6数据库,做增量备份与还原

1、Full backuop&#xff0c;一定要先做: innobackupex --defaults-file/etc/my.cnf --userroot --passwordevlink /home/mysql/backup/2、Incremental backup&#xff0c;可以每隔一小时或者三小时做一次: innobackupex --defaults-file/etc/my.cnf --userroot --passw…

MFC按钮添加提示文字

转载自&#xff1a; http://blog.163.com/guo_linda/blog/static/12377305720101122105030162/ MFC里这个类叫做CToolTipCtrl&#xff0c;具体用法很简单。 1、在类头文件中声明CToolTipCtrl的类对象m_ctrlTT。 2、在初始化函数OnInitDialog()中设置m_ctrlTT。 EnableTool…

Go远超Python,机器学习人才极度稀缺,全球16,655位程序员告诉你这些真相

作者 | 唐小引题图 | HackerEarth 报告出品 | AI科技大本营&#xff08;ID&#xff1a;rgznai100&#xff09;Go 正变得越来越受开发者欢迎。几年前&#xff0c;滴滴的工程师曾告诉我&#xff0c;在滴滴 Go 已经得到了非常广泛的应用&#xff0c;去年&#xff0c;在腾讯内部使用…

WinCE中命令行工具Viewbin简介(查看nk.bin中包含的文件)

Viewbin是微软提供的一个命令行工具&#xff0c;在WinCE5.0和WinCE6.0中&#xff0c;可以在"/WINCE600/PUBLIC/COMMON/OAK/BIN/I386"找到他。Viewbin工具可以用来查看NK.bin文件。它可以从NK.bin中获得这个NK image的大小&#xff0c;运行的起始地址等。还能查看到里…

元素多层嵌套,JS获取问题

如果一段html嵌套过多&#xff0c;在js中获取还是比较麻烦的&#xff0c;我写了几套方案&#xff0c;大家可以参考参考&#xff0c;如果你有好的方法&#xff0c;也分享出来&#xff0c;让我们瞧瞧。 HTML&#xff1a; <!DOCTYPE html> <html lang"en"> …

MFC静态文本控件设置超链接

有时我们需要在窗口上设置一个超链接&#xff0c;比如在Aboutdlg上设置“我的博客”这样的超链接.具体的设置方法如下。 1、首先我们在窗体上添加一个Static文本控件&#xff0c;修改Caption属性&#xff0c;设置成你想要的超链接标题&#xff0c;比如“更多内容欢迎访问小梦的…

百度云「升级战」:王海峰站台,新架构全面AI化,AI和知识中台登场

5月18日&#xff0c;"ABC SUMMIT 2020百度夏季云智峰会"在线上召开。刚刚经历了人事变动的百度云迎来重磅升级&#xff0c;大会以"百度智能云加速产业智能化"为主题&#xff0c;百度智能云全新战略、新架构首次亮相&#xff0c;AI中台、知识中台两大创新平…

Mysql实现非程序控制读写分离

五一假期&#xff0c;有个博友给我发邮件&#xff0c;说我的这篇blog&#xff1a;http://bobwu.blog.51cto.com/2918362/537077 只能通过程序员在程序中实现读写分离&#xff0c;咨询能否实现程序员无察觉的读写分析&#xff0c;呵呵&#xff0c;我明白意思。回答是肯定的&…

MFC系统托盘的实现

通常电脑里边的软件&#xff0c;当你打开后会在电脑最右下角的任务栏上生成一个系统托盘&#xff0c;当你点击最小化或者点击关闭按钮后&#xff0c;若想恢复窗口&#xff0c;可以左键双击或者单机这个系统图标&#xff0c;同时鼠标右键点击&#xff0c;又会有其他的菜单弹出&a…

王海峰发布百度智能云最新架构,推出AI中台和知识中台

5月18日&#xff0c;在百度云智峰会上&#xff0c;百度CTO王海峰发布最新百度智能云架构规划。首先&#xff0c;他分享了百度利用AI、大数据、云计算等技术帮助疫情防控、复工复产的成果&#xff1a;AI多人测温1周检测2700万人次&#xff0c;时空大数据记录人流迁徙24亿人次&am…

Linux虚拟内存优化的方法

首先查看虚拟内存的使用情况&#xff0c;使用命令   # free   查看当前系统的内存使用情况。  一般来说&#xff0c;linux的物理内存几乎是完全used。这个和windows非常大的区别&#xff0c;它的内存管理机制将系统内存充分利用&#xff0c;并非windows无论多大的内存都要…

statpot:使用mongo+bootstrap+highcharts做统计报表

最近做了一个统计项目&#xff0c;这个统计项目大致的需求是统计接口的访问速度。客户端会调用一个接口来记录接口的访问情况&#xff0c;我的需求就需要分析这些数据&#xff0c;然后做出个统计报表。 需求实现 最初的时候想着每天把这些接口访问情况的信息存储到mysql中&…

磁盘文件目录罗列和list控件的使用

开发类似ftp客户端的这种软件&#xff0c;需要对每个磁盘下的文件目录进行罗列并显示。方便文件的上传、下载等。就如同我们打开每个磁盘所显示的那样&#xff0c;罗列了你这个磁盘目录下的所有文件夹和文件。 那我们在自己的程序中如何做到这样呢&#xff1f; 主要用到两个…