python将真实图像转为文字照片

文章目录

  • 前言
  • 结果
  • 原理
  • 操作
    • 导入使用的模块
    • 二值化
    • 汉字笔画排序
    • 得到.txt文件
  • 完整代码
  • 其他
  • 附上一张博主的闷骚照片

前言

这是一个使用python做的玩具代码,个人觉得挺有意思的,是根据b站的一个up的视频的原理讲解实现的
原视频是这个

【自制开源】520写个小程序用女朋友的名字把她画出来,女朋友:“这是个动物吗?”

结果

原图参见作者头像,转换后结果如图
python将真实图像转为文字照片_第1张图片

原理

那根据视频里面的原理,是这样的

  1. 将彩色图片二值化,就是转为黑白照片
  2. 将黑白照片里的像素使用文字替换,深色的用笔画多的文字替换,浅色的用笔画少的文字替换

操作

导入使用的模块

from PIL import Image
import numpy as np
from chinese_stroke_sorting import sort_by_stroke
import math
  1. PIL用于将图片二值化
  2. numpy中的asarray可以将图片转为一个矩阵
  3. chinese_stroke_sorting可以将汉字根据笔画数进行排序
  4. math里使用一些数字处理函数

二值化

def image_binarization(self):
	old_img = Image.open(self.filename)
	new_img = old_img.convert('L')
	return new_img

经过这个函数,可以得到一个二值化的图片,每一个像素,都是0-255的一个值

汉字笔画排序

word_arr = ['不', '夜', '熬', '要']
word_arr = sort_by_stroke(self.word_arr)

之后的word_arr就是一个根据汉字排序的列表了

得到.txt文件

根据原理,我们遍历整个图像矩阵,依照给的word_arr长度来平均分配汉字,什么意思呢?以['不', '夜', '熬', '要']这个为例,像素矩阵的值是0-63的就是"不",64-127的就是"夜",128-191的就是"熬",192-255的就是"要"。

所以函数就是这样

    def to_txt(self):
        word_arr = sort_by_stroke(self.word_arr)
        interval = 256 / len(word_arr)
        with open(self.filename.split('.')[0] + '.txt', 'w', encoding='utf-8') as f:
            try:
                for line in self.img_arr:
                    for px in line:
                        r = math.floor(px / interval)
                        f.write(word_arr[r])
                    else:
                        f.write('\n')
            except IndexError as e:
                print(e)

完整代码

from PIL import Image
import numpy as np
from chinese_stroke_sorting import sort_by_stroke
import math


class IMG_to_TXT:
    def __init__(self, filename, word_arr=None):
        if word_arr is None:
            word_arr = ['不', '夜', '熬', '要']
        self.filename = filename
        self.img_arr = None
        self.word_arr = word_arr

    def image_binarization(self):
        old_img = Image.open(self.filename)
        new_img = old_img.convert('L')
        return new_img

    def to_txt(self):
        word_arr = sort_by_stroke(self.word_arr)
        interval = 256 / len(word_arr)
        with open(self.filename.split('.')[0] + '.txt', 'w', encoding='utf-8') as f:
            try:
                for line in self.img_arr:
                    for px in line:
                        r = math.floor(px / interval)
                        f.write(word_arr[r])
                    else:
                        f.write('\n')
            except IndexError as e:
                print(e)

    def __call__(self, *args, **kwargs):
        new_img = self.image_binarization()
        self.img_arr = np.asarray(new_img)
        self.to_txt()
        
if __name__ == '__main__':
    i_t_txt = IMG_to_TXT(filename='cgy.png', word_arr=['一', '亿', '已', '艺', '以', '衣', '异', '怡',
                                                       '宜', '咦', '姨', '益', '移', '意'])
    i_t_txt()

其他

如果想要图片更精细一点的话,可以自定义word_arr
然后就是图片的像素尽量不要太高,因为电脑的记事本能显示的最大宽度是有限的,所以像素太高的话,就会导致一行的像素,不能够以一行的文字显示出来

附上一张博主的闷骚照片

细节还是挺清楚的吧

你可能感兴趣的:(python,开发语言)