问题描述



可能有很多吃瓜群众不知道这事儿的魔幻程度,这里专门解释一下这个ASCII-Generator的技术含量,业余python爱好者,大家看个乐子不要深究。
做ASCII字符画的形式有很多种,其中通过量化图像然后用不同“浓度”的字符来代替黑白对比度的这种方式,根据Wikipedia的说法[1],是1960年代就有的事儿:

具体流程其实猜也能猜的到:图像是像素构成的,我把图像转成黑白的,分成若干小块,每个小块的像素亮度求个平均值,亮度高的,用点(.)啦或者冒号啦(:)这种比较“淡”的字符表示,这样白色背景上显得亮;反之,用M啦N啦#啦这种看起来比较“浓”的字符来表示,白色背景上显得黑,这就把图像转成一堆文字了。
正因如此,对于ASCII-Generator的图片转文字那个img2img.py(先不看color那个,因为color就多一步算平均颜色,还是算平均),其核心就这几行代码[2]:
image = cv2.imread(opt.input) # 打开图片
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 转成灰度利用OpenCV(cv2)库,两行代码把图片文件打开转成黑白图。
line = "".join([char_list[min(int(np.mean(image[int(i * cell_height):min(int((i + 1) * cell_height), height),
int(j * cell_width):min(int((j + 1) * cell_width),
width)]) / 255 * num_chars), num_chars - 1)]这段看起来有点长,实际上就是利用Numpy(np)库的mean(平均)方法求image对应“一块”亮度的平均值,然后从预先设置好的字符列表里挑出对应的写进去。
其余的部分那就是规定几行几列怎么处理命令行输入怎么写文件存盘的非“算法”部分了。
也就是说,真真正正的“核心”代码,就是cv2.cvtColor转黑白,和np.mean求平均。
两句。
而且是非常原始的,不涉及更“高级”的“插值算法”的,纯粹的几个像素求平均。
人生苦短,快用Python!
实际上原作者也说了,做这个项目,用这种方式写出来,基本上也就是为了当Python教程用的[3]:

这还是比较复杂,要用不同字符替换的。如果连字符都不用替换(都用O),黑白都不用转,直接把颜色信息求个平均带过去……
就是,这事儿对于任何一个学过Python的人来说,基本是非常没有技术含量的,但却是整个视频里最核心的技术。就这个Python作业级别的脚本(核心“算法”两行),还需要找个现成的脚本删掉原作者信息。你觉得这不够魔幻的时候,这还是个主打“技术”的视频博主做的商单。
就像一个“大厨”,用超市买的火锅底料,给你下了一碗超市买的机器挂面,然后说这是他给你做的私房面——因为是他架锅开火烧的水,所以说这话没毛病,但一个“大厨”做这种事儿……更进一步的话,道歉文说的是审稿没审出来,也就是说脚本不是他写的,视频里这么核心的代码,一个本科CS专业分分钟能写出来的,他不自己写,是不喜欢吗……
我之前是用ffmpeg转图片大小,然后pillow转黑白的,核心代码也是两行,出视频没人看。我从一个问题酸到另一个问题了。我酸死了。