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

前言

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

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

结果

原图参见作者头像,转换后结果如图
请添加图片描述

原理

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

  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
然后就是图片的像素尽量不要太高,因为电脑的记事本能显示的最大宽度是有限的,所以像素太高的话,就会导致一行的像素,不能够以一行的文字显示出来

附上一张博主的闷骚照片

细节还是挺清楚的吧
请添加图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gsxdcyy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值