然后在这个时代,会编程的人越来越多(尤其是 MATLAB,Python 等非常适合图像处理的脚本语言),类似的教程更是数不胜数。甚至可以说,在 2018 年还剩一个多月就要结束的时候还要搞一个这种基于 Python 的字符画生成教学,实在是太丢人了,也几乎没有什么意义。
笔者最早接触生成字符画的代码,可能是源自这个 B 站视频(刚打开时候的音乐不太妙)。UP 主在 Vim 中写下一行又一行的 C++ 代码,看得那年刚上大学的我如痴如醉。
第二,要搞清楚所选字符的宽和高的关系。这里我经过简单测试,得出高大概是宽的 1.865 倍。(不同的屏幕 PPI,不同的字号,都可能会导致宽高比发生变动,因此最好在一开始就固定一个字号,如八号字)
第四,还有一件小事,那就是这样的算法可能并不适合所有图片。我们设计这样的字符列表,是因为一般图片的直方图能够充满整个色域。但是有的时候,存在偏亮或者偏暗的图片,那时候再套用相同的算法,效果图可能就不那么理想了。就比如我的头像这张图(出自《古剑奇谭三》):
这里做的改进是直方图均衡化(histogram equalization),目的是让图片的直方图尽可能地平整(因为图片的像素点的亮度是离散的,无法做到真正的平整),覆盖尽量宽的亮度,从而提高图片的对比度。就头像图而言,相应的直方图如下:
另外,因为直方图均衡化只适用于单通道图片(如灰度图)。如果想要对彩色的图片进行直方图均衡化小儿收惊符,正确的做法并不是单独对 R、G、B 三个通道分别进行均衡化(比如某张图片红色很亮,蓝色通道很暗,那么分别进行均衡化势必使输出图片的色调发生明显变化),而应该是只对图片的亮度进行调整。
具体而言,可以先将图片转为 HSV (Hue 色相,Saturation 饱和度,V 明度),然后只针对 V 施加均衡化,最后再重新变回 RGB 空间。也有说将图片转为 YCbCr,然后对 Y 通道进行操作的。但从实际效果而言,转为 HSV 似乎更能让人接受一些。
这里可以多说几句。MATLAB 在较新的版本中,histeq 函数已经可以接受 RGB 三通道图片了,但是具体操作细节不明。尝试了上述转为 HSV 和 YCbCr 再均衡化的方法(效果见下图 HSV 和 YCbCr),效果均与直接 histeq (效果见下图 histeq)存在一定差别。
另外,MATLAB 还有一个函数名为 adapthisteq。与对整体直接进行均衡化不同,这个方法将图片划分为多个矩形区域(Tile),针对每个区域进行均衡化操作,再借助双线性插值(Bilinear Interpolation)将各个区域连接起来。效果明显比 histeq 更加能够让人接受(因为避免了对比度过高的现象)。然而这个方法不适用于三通道图片(笔者使用版本为 2018b,目前尚不支持)。因此,我尝试了先转为 HSV,再单独对 V 进行 adapthisteq 的方法(效果见下图 adapthisteq),发现效果很好。我也尝试了先转为 YCbCr 的方法,但是效果与下图 YCbCr 有些类似,均有点泛白,不如 HSV 好,故不做展示(主要是六张图正好,多一张图不好摆放……)。
至于分别对 RGB 进行操作(见下图 RGB),效果似乎也能忍,但是这一定不是最正确的方法。
只是黑白,似乎不能满足人民日益增长的审美需求。因此,我们可以用类似的思路,给不同的字符以不同的颜色。也因此,我们就不能再输出 .txt 文件了。取而代之,我们可以采用 Python 的 Pillow 库,直接将文字打印到图片上,再进行输出。至于为什么不用 OpenCV,是因为 OpenCV 的 cv2.putText 方法不支持自定义字体(只能使用默认的 Hershey 系列文字,效果不理想)。
这里我们就不必使用之前设计的字符列表了,因为字符的颜色已经包含了亮度信息,没有必要再根据亮度选择不同的字符了。所以我们也不需要量化图片了。这次我们采用随机的大写字母。
这是为什么呢?其实原因很简单,因为每一个字符的笔画只占整个字符面积的一小部分,所以“离远了看”,所有字符对于整个图片的亮度和颜色的贡献非常有限(背景色更占优势)。那么对策总不能是严格计算每一个字符的笔画所占比例小儿多少岁,然后进行调整吧?
这样计算代价实在是太大,而且未必能够换来令人期待的效果,因此笔者并没有进行相关的尝试(其实有兴趣的朋友可以试试,在黑色背景上打印白色字符,然后从输出图片的像素级别对笔画的占比进行计算)。我们可以借助图像编辑软件(如 Win 10 自带的「照片」,只需要右键需要调整的图片,选择“使用照片编辑”即可)。
那这样好了,我们采用一种懒省事儿的方式,背景叠加一张非常模糊的、亮度略有降低的原图好了。这里我们使用尺寸为 25x25 的高斯模糊(Gaussian blur),亮度调节为原图的 70%。效果如下:
看到这里,是不是觉得其实字符画也不过如此。只要有了思路,会一门编程语言,就可以做出上述的效果了?没错,就是这样。
诚然,本文的标题是“从入门到不屑”。但是我们嫌弃的,仅仅是因为经过一番思考之后,轻松地就实现了上面的效果,发现这其中其实并没有什么很深奥的不可战胜的知识,而不是去嫌弃做这些事情的人。第一个发明字符画的人注定是了不起的;而每一个独立写代码实现出这一效果的人,也同样是了不起的。每一个这样的人,都打开了图像处理的大门,拥有不可估量的未来。
版权声明:本文为 “小儿收惊网,小儿辟邪小儿化煞宝宝平安符小化化病小儿夜啼符小儿聪慧符” 原创文章,转载请附上原文出处链接及本声明;
留言与评论(共有 条评论) |