好久没有上简书,最近上来一看发现这篇文章阅读量远超了其他的文章,还有评论提到说在讲技术的时候卖萌不好。哈哈,当时写的时候完全没想过会有人搜到看,只是为自己的作品留个念想,所以文风比较散漫随意。于是这次来小修了一遍,谢谢阅读~

前很长一段时间,时光相册火了一个应用《你的名字》同款滤镜,一时间这种鲜艳靓丽的卡通天空滤镜刷遍了QQ空间朋友圈。

时光相册的效果是这样的。

左:原图,右:滤镜图

他们在新闻采访中说自己和prisma一样用到了深度学习的技术,不过是用在了天空区域提取上。

我初步理解下就是:

1. 使用深度学习提取了天空区域

2. 蒙版替换了预设的卡通天空图片

3. 辅以传统美图滤镜方法美化效果。

天空区域真的需要用深度学习来提取吗?在知乎上逛了,下果然有人和我有相似的疑问。

我觉得深度学习真的很难把控,这是自己做着玩的小东西,所以我就用opencv实现了一个极简版=v=

首先确定编码流程:

1). 实现天空提取检测模块

2). 实现无缝融合模块

3). 实现日系色调滤镜

4). 整合测试及联调

PART1. 天空区域提取

尝试了三种方法,两种是来自论文的,一种是随便写写的,从最终的平均质量来看,还是拍脑袋决定的简单方法A的平均质量更高。

方法A. 阈值分割,蓝色消除

核心思想是将蓝色作为天空进行消除。利用HSV颜色模型做色调分离,首先将原图转换到HSV空间,并进行蓝色部分的选择,然后做个阈值分割,从而使得蓝色可以被分割走。只要我们选取到了合适的H值,那么就可以把蓝色去掉。

下表是颜色对应的HSV的值:

这种方案在天空较均匀,蓝色较明显时表现较好

我的效果(目前用的opencv里的copyto接口,傻乎乎的粘贴了卡通天空图去检测到的区域)所以边界还比较僵硬。

我的天空区域提取代码:首先是cvtColor,给原图从BGR转HSV去,然后把hsv的三个通道split一下

用Inrange分出我们需要的蓝色阈值区域。中值滤波一下消除杂点,让Mask看起来比较完整。跟着一个开操作,再滤波一下。其实这些都是我随便定的,目的就是让提取出的黑白Mask更完整一点,别尽是小杂点,我们只需要保证大致的准确就行。把检测区域存在mask里,做成一个黑白图片。(用来提取天空region的mask),下面是这段文字的顺序代码描述。

B.《sky region detection in a single image for autonomous ground robot navigation》

和其他的方法不同,这个算法可以同时用于灰度图和彩色图。做法是:1、获取图像的梯度信息;2、根据能量函数优化计算【梯度域的最优分割阈值】,估计初始天空区域;3、最后一步后处理是为了细化前期天空区域的检测,比如途中没有天空区域出现,或天空对象伸出地面时。、

这个我实现了,测试时很容易检测出奇奇怪怪的东西。可能是我写的不对,如果最终要求是70%图能看,那么还是A方法好一些。

C.《一种基于灰度阈值的天地背景轮廓线提取方法》

针对天地背景轮廓线具有波动起伏、边缘模糊及轮廓边缘灰度值变化缓慢的特点,采用灰度阈值方法,实现了多种天地背景边缘轮廓提取

天地背景图像通常包括天空区域和地表区域,常见的有天空海面、天空平原、天空山地、天空沙漠等景物图像。在摄录远距离天地背景图像时,背景图像除了噪声增大外,还会因大气湍流等因素影响而产生抖动或起伏,这种现象在背景边缘轮廓附近尤为明显。其结果造成图像轮廓边缘模糊、波动起伏,图像边缘区域灰度值变化呈现连续缓慢变化状态,导致建立在微分理论基础上的传统经典图像边缘检测算法对天地背景图像的边缘轮廓提取失效。

同上,可能是我写的不对,如果最终要求是70%图能看,那么还是草率决定的A方法好一些。

无缝融合

在展示方法A效果的时候,我用copyto函数进行的融合,那融合效果十分僵硬,边缘一看就是抠图贴上去的,这种看起来就很没品并外行的效果,咱们是必须拒绝的。

那么怎么做融合才能无缝?这里我了解的方法中和时光相册效果最像的是一个叫【泊松融合】的方法。seamlessClone这个泊松函数在Opencv2里没有,所以我重新去下opencv3。下来opencv3后,发现报错提示我Numpy跟不上版本,本来装的是Numpy1.9,说要升级到10以上。然后跑去sourceforge里补了一个numpy 1.10.2。当环境配好之后,seamlessClone就自己通了。详细代码是这样的:

其实完全就是调用用seamlessClone这个函数么,前期需要做一些准备工作。找出边缘,给出定位(确定要把卡通图贴在什么位置、按什么比例缩放后再贴)

然后调用seamlessClone,按api上要求的给他传他要的那些参数就Ok了。这里选的融合方式是normal_clone,不清楚原因,只是把选项都试了试这个效果最好。

这个变化真真是超明显的。下面放对比图,左边是没有seamlessclone的,右边是seamlessClone的。可以看左边的树的间隙(好明显的异样感),右边是用seamlessclone之后,瞬间就无痕了。

这样看起来右边就已经挺自然的了。不过还缺了点“动漫感”,为什么呢,因为没有调色。

调色滤镜

其实这玩意卡了我很久,因为压根没在网上看到“教教我怎么做滤镜”这样的教程。一搜一大把都是用着那些很基本的函数弄来弄去,都是些很丑很土气的滤镜效果

那么多美图应用都提供了什么“和风滤镜”,“小清新滤镜”,“午后阳光滤镜”,Blabla…………

有木有人可以告诉我他们都是咋做的?

谢谢大神,虽然完全没有感受到手把手的教(擦泪),但是连猜带蒙的我还是给整出来了。

就让我来手把手的教大家一下(擦泪)。

首先,有一张(被公认很标准的)色卡图,当原始颜色映射表,左图是原始颜色表,右图是对应着某个色彩滤镜“比如和风”的滤镜色卡表。

这两个色卡表说是表,其实就是图片,就是一堆有RGB通道的像素点集。

我说下滤镜的思想:

要给一张图片刷滤镜,遍历它的每个像素点,比如坐标(0,0)的像素点,它的颜色是(123,132,231)先在表1查颜色(123,132,231)对应的色卡表位置(坐标),再去表二查出对位坐标的新的颜色值(RGB)替换掉当前像素点的颜色(RGB)。基本都是自行脑补出来的思路,原始色卡说白了就是一堆数值,一堆有规律的数值。

我们需要跟着输入图的各个像素点上的RGB值,找到它位于原始色卡的坐标。那么就是要找到原始色卡每个点的RGB值和它的坐标的对应关系。这个原石色卡表当然是有规律的,它每个坐标上的RGB数值都是和坐标挂钩的,是有规则的。

经过一段时间的归纳总结我推出来了映射公式:(AB二维是坐标,xyz是三个颜色通道)

A = y/4 + (x/32)*64

B = z/4 + ((x%32)/4)*64

这个公式我验证了完全正确,用网上给出的一个示例色卡,能刷出滤镜色如下。

是不是看起来挺高级?有点美图秀秀的feel了吧!

可能有人想问??右边那个对应新滤镜的色卡是怎么来的?

答:我在网上下载的。(好吧,专业的滤镜制作公司应该会需要艺术家?设计师来做那张色卡)这是艺术范畴了我等程序猿只要知道怎么怎么进行映射,怎么写代码转换风格就可以了。不过,毕竟是冲着实现你的名字同款滤镜的目标做的。那你的名字同款色调也是必须的。

那么我来介绍一下我制作右侧色卡的方法把。。

……

感觉说出来会很丢人。

……

但不失为一个好办法。

【把左侧的原始色卡存到手机里,放到任意一个美图应用里 “刷一下” ,刷哪个滤镜,就出哪个滤镜的色卡。等于是复刻色卡】

如果是盈利性质的这样做肯定是不行的,应该让设计师设计,咱们宅着自己练技术玩,这方法还不错。

下面是我对色卡操作的代码:

整合前三块

最后就是简单的加法,把前三块串起来就Ok了

可以大概看看最终效果,我觉得还挺梦幻的,不过因为天空提取的算法太简单,所以有些图片的天空的表现很辣鸡就是了。。Just for fun!

嘿嘿嘿我要写简书当然是放好看的效果了。至于不好看的,就不展示了

批量测试的结果(100张图):

好看的结果普遍在50%左右,能看(不保证好看)的结果在80%以上。不能看的在15%左右。不能看图就是固定的几张,都是因为天空区域提取出错了(多选/少选)。如果想做成专业应用,在天空区域提取这步肯定不能像我写的方法A这么随意。

以上。

谢谢阅读~

python请输入你的名字_实现《你的名字》同款滤镜,python+opencv相关推荐

  1. 在python中输入圆的半_极客起源 - geekori.com - 问题详情 - python动态圆更新糅合到地图显示里...

    两个程序都能单独运行,但是糅合在一起就出问题了,以下是代码: #-*-coding:utf-8-*- from matplotlib.patches import Circle import matp ...

  2. python请输入一个人的名字_print('曾经有一份真挚的爱情放在我面前,那个人的名字是' + goddess),Python旅程开始的地方!...

    <Python为你打开一扇门>,你已经轻轻地推开了Python世界的大门,你开始凝视这个全新的世界,你用print() 函数敲下了第一行Python代码,你运行了第一个Python写成的人 ...

  3. python请输入星期几的第一个字母来判断_【Python 实例】面向对象 | 请输入一周中某天的名称的第一个字母来判断以下是星期几,如果第一个字母一样则继续判断第二个字母...

    [Python 实例]面向对象 | 请输入一周中某天的名称的第一个字母来判断以下是星期几,如果第一个字母一样则继续判断第二个字母 题目: 请输入一周中某天的名称的第一个字母来判断以下是星期几,如果第一 ...

  4. python请输入一个人的名字_python小练习

    1.字符串拼接 用两个字符串,将他们组合后输出. str1 = input("请输入一个人的名字:") str2 = input("请输入一个国家名字:") p ...

  5. python请输入第一个数请输入第二个数_Python小白学习之路(四)——第一次练习题...

    写在前面: 今天下雪了呢!连着两天都没有更新学习记录. 我没有偷懒呢.做了一天的练习题,昨天学的内容还没总结完,太累了就回去睡觉了 连续一周早起,强大的内心也无法支撑我疲惫的身体 今天早起做了整理.加 ...

  6. 无法嵌入互操作类型 请改用适用的接口_可微编程-自上而下的产品形态 4 Python互操作性...

    原文:Python互操作性 如设计概述文档所述,Python API互操作性是本项目的一个重要需求.虽然Swift被设计为与其他编程语言(及其运行时)集成,但动态语言的本质并不需要支持静态语言所需的深 ...

  7. python异常处理输入不是整数_【Python】异常处理

    异常处理 内容概要 异常的概念 捕获异常 异常的传递 抛出异常 01.异常的概念 程序在运行的时候,遇到错误导致程序停止运行时,这就是异常. 程序停止运行,并且提示错误信息这个动作,我们称为:抛出(r ...

  8. python请输入两个整数m和n_Python 二级模拟操作题(五)

    1.编写程序,从键盘上获得用户连续输入且用逗号分隔的若干个数字(不必以逗号结尾),计算所有输入数字的和并输出 提示代码: n = input() nums = ____①____ s = 0 for ...

  9. Python:请输入一段信息,并计算这串消息的信源熵

    源码: import string import math count=0#用counnt保存不同的符号的个数 print("请输入你想计算信源熵的信息:") n = input( ...

最新文章

  1. Python 办公自动化,一键给PDF文件加密,超方便
  2. 几大最短路径算法比较
  3. How to save your Ethereum Dapp users from paying gas for transactions
  4. 中篇 | 多轮对话机器之话题意图识别
  5. xxx.jar 中没有主清单属性
  6. Linux Shell中各种分号和括号的用法总结
  7. 高效Java第六条消除过期的对象引用无意识的对象保持
  8. 信息学奥赛一本通 提高篇 第六部分 数学基础 相关的真题
  9. [文摘]Java正则表达式详解
  10. php黑名单,php IP黑名单
  11. 大一c语言上机题库及详解答案,二级C语言上机题答案(题库答案).doc
  12. hibernate详细教程(入门到熟练)
  13. Cboard框架搭建及使用
  14. 干货 | 华为内部几近满分的项目管理PPT
  15. 2021 绩效管理必读
  16. Cents7 查看当前版本
  17. urdf转sdf制作模型包
  18. cocos creator3.3.0休闲游戏(云浮消消乐)源码H5+安卓+IOS三端源码
  19. 新年警惕:多数手机银行App存安全隐患
  20. Spring 01 初识 Spring

热门文章

  1. LCA求解的四种模板
  2. 几个冷门字符串算法的学习笔记(最小表示法,exKMP,Lyndon Word)
  3. Deltix Round, Summer 2021 (open for everyone, rated, Div. 1 + Div. 2)
  4. AcWing 1068. 环形石子合并
  5. HDU 6889 Graph Theory Class(CCPC网络赛)
  6. P3273-[SCOI2011]棘手的操作【线段树,并查集】
  7. jzoj5701-[gdoi2018day2]谈笑风生【莫比乌斯反演,二分,最短路】
  8. jzoj5231-序列问题【分治】
  9. 2021牛客暑期多校训练营4 D-Rebuild Tree(prufer序列+树形dp)
  10. 2019-2020 ICPC Asia Hong Kong Regional Contest 补题(部分)