惯例闲聊
今天是腊月二十九(写这篇文章的时候已是年三十的凌晨了),先给诸位拜个早年。
(资料图片)
这几天无事(有事也不干了),便难得有些事情搞搞自己喜欢的事情。今日听音乐的时候又不知第几次听到了这首歌。但这次,当我看到它的封面时,我突如灵光一闪:我想试试能不能将这种风格应用到其他图片上。
简单搜了一下,似乎绝大多数教程都是用PS实现的,还真没有使用代码做这项任务的(想想也是,用PS做又快又好,敲什么代码)。反正今日无事,还能水一篇文章,岂不美哉,就随便研究了一下。
不过最终效果并不算好,只能是图一乐。
那么以下是正文。
任务分析
这项任务其实可以分为三步:预处理、边缘提取、计算颜色。依次完成这几个步骤就好。那么就大概说一下这三步的过程吧(图像处理在不懂原理的时候确实非常枯燥)
1. 预处理
通常来说,预处理在任何一种图像处理的流程中都是必不可少的,根据最终目标不同,预处理的步骤也会有所不同。由于后面的流程比较简单(以及我懒),这一步只进行了图像降噪,使用的是高斯低通滤波器。
低通滤波器,就是只让频率低于阈值的信号通过的设备。使用高斯低通滤波器可以对图像进行平滑处理,此外还能有效降噪。对这个任务来说,平滑的意义大于降噪。因为若不进行平滑处理,最终结果中往往有较多细小的像素,类似噪点,使得整张图看起来比较杂乱,不符合主观审美。
代码中的“GLPF”函数就是高斯低通滤波器,它的第二个参数值是截止频率,降低它会提高降噪效果,但也有可能会丢失图片信息。
2. 边缘提取
边缘提取就是提取出图片中的轮廓,动画作品在这方面有着天然的优势,因为动画、漫画的色彩层次不如实拍照片那么丰富,能看出明显的色块;此外,由于动画作品通常都有描线,就更容易提取边缘了。
在Matlab代码中提供了Canny算子检测和光栅扫描跟踪两种方式,Python代码中只用了Canny算子一种,推荐使用Canny算子检测方法。
Python代码中使用的是CV2的库函数“CV2.Canny”,参数含义请自行查询修改(其实我也没查不知道什么意思)。Matlab代码中将两个相关参数写在了Canny_edge_detect函数内部,修改不太方便。
3. 计算颜色
这是相对简单的一步,我们要通过函数来模拟原图中的渐变色。我本人色感是很差的,两种颜色混起来是什么颜色这种问题完全不懂。但是好在我知道大多数彩色图像都是RGB三通道(或者再加个alpha通道)的,我可以分别查看R、G、B三个通道的色值变化趋势,分别构建三个函数。Matlab在可视化方面做的很好,就使用Matlab观察了。
上述图片中,颜色越冷表示色值越低,越暖表示色值越高,当某个像素为白色时,它的每个通道的色值都是255即最大值,所以才能看到大面积的黄色(最暖)。
单从上面的截图看不太出来变化趋势,但其实这里画的是三维图,颜色和Z轴是对应的,我通过查看Z轴的高度确定了大致的趋势,然后构建了一组差不多的函数,如下所示。
其中(x,y)表示像素坐标,width为矩阵横向元素数,height为矩阵纵向元素数,[]表示下取整。随后遍历像素,在属于边缘线的像素点上,根据上述函数计算该像素的颜色即可。
处理结果
这是部分处理结果,比较推荐处理动画和漫画的截图,因为他们通常色彩层次比较少且鲜明,效果会更好。
emmm,确实最终效果也不太行....但也只能先这样了。
下载地址
提供Matlab代码(实时编辑器文件/.m脚本)和Python代码(Jupyter/.py脚本)两个版本。
链接:https://pan.quark.cn/s/1cfeb737ea19
提取码:ybyW
今天又是划水的一天呢。