Python 如何将最相似的Unicode字符返回到图像的某个部分?

Python 如何将最相似的Unicode字符返回到图像的某个部分?,python,image,image-processing,unicode,ascii,Python,Image,Image Processing,Unicode,Ascii,我用Python制作了一个简单的转换器,将图像转换为ASCII。现在,它使用了各种深浅的黑色字符,因此它可以工作,但在低分辨率下很难辨认:例如,谷歌徽标显示为: .. .;. .@ a; .. .; . .. a. @ ...;. aa .a.▒. ▒.;. ;.;; a. ▒ @a .;.. .; ..... . ..;;; ; ;.. .a.

我用Python制作了一个简单的转换器,将图像转换为ASCII。现在,它使用了各种深浅的黑色字符,因此它可以工作,但在低分辨率下很难辨认:例如,谷歌徽标显示为:

  ..  .;.                  .@      
 a;       .. .;     . .. a. @ ...;.
 aa    .a.▒.  ▒.;.  ;.;; a. ▒ @a   
  .;.. .; .....  .    ..;;; ;  ;.. 
                     .a. .;        
这几乎无法理解。是否有一种方法可以将每个部分与Unicode字符的子集进行比较,并返回最相似的字符,这样它就可以返回如下内容:

  ./--.\.                  /▒      
 a;       ./-.;  /  \ ./ \\ ▒ ./━\.
 aa    -a.▒.  ▒.|.  |.;▒  ┃ ▒ ▒-~┘ 
  \;.. /| \\_//  \ /  .\;;; ▒ \\.- 
                     .pp--▒  
  • 为要使用的每个字符生成一个图像,使用您将要使用的字体。您可能会使用固定宽度的字体,这样可以创建一个大图像,然后将其拆分。这可能与在编辑器中键入字符并进行屏幕捕获一样简单
  • 对于输入图像的每个面片,将面片与所有角色图像进行比较。我会从面片和角色中提取相应的像素,并将差值平方,然后将它们相加-总和最小的角色是与面片最匹配的角色
  • 您可以通过对角色图像、输入图像或两者进行模糊来改善结果。通过增加输入图像的对比度,也可以获得更好的结果

    提高结果质量和速度的另一个想法是计算每个角色的平均黑暗度,只尝试匹配与补丁的黑暗度几乎相同的角色。

    当你说

    将每个部分与Unicode的子集进行比较

    这并不十分清楚,因为有不止一种方法可以做到这一点。我会把比较降低到像素级。在灰度图像中,每个像素都有一个灰度值。假设你想用一个合适的字符替换每个像素,这个字符如何与像素匹配?如果你从很远的地方看一个角色,你只会看到一个灰色的斑点。如果现在用字符替换像素,则应选择与该像素灰度值最相似的字符

    在单间距字体中,每个字符使用相同的空间量。如果你现在取这个矩形的空间,在上面画一个字符,你可以计算出平均灰度值。此平均灰度值不超过矩形与整个矩形相比的白色面积。空间的灰度值为1。也许美元符号是你能找到的最黑的字符之一

    下面是我要做的:

  • 获取一组字符,无论您是仅使用ascii码还是uni码。计算每个字符的白色量。很明显,对于不同的字体,这可能会有所不同,但您必须使用单间距字体
  • 现在有了一个列表,它将每个字符映射到一个灰度值。现在应该将灰度值重新缩放到目标灰度值间隔。当您有一个8位图像时,最亮的字符(空格)应该对应于255,最暗的字符应该对应于灰度0
  • 现在,重新缩放输入图像,使其不太大,因为即使使用非常小的字体,一行也可能无法获得2000个字符
  • 将每个像素替换为灰度最接近其自身灰度的字符
  • 在Mathematica中,这只是几行代码。在python中,它可能会稍微长一点,但也应该可以

    使用这种方法,当你从远处看文本时,你会得到非常惊人的结果,当你走近文本时,你会看到它都是由字符组成的


    更新 当你想要创建一个与原稿大小相同的图像时,方法并没有太大的不同,但正如马克已经指出的,即使在这里,你也可以为你使用的每个字母创建一个光栅图像。 我真的看不到一个更快的方法来比较你的图像块和一封信,以决定哪一个是最合适的

    可能有一个提示:如果您使用这种方法,字母将在图像中可见,因为当您使用例如12pt字体时,每个字母的图像大小至少为10x15左右。当您现在转换一个1000x1500的图像时,它不是那么小,您只使用100x100个字母。 因此,不使用图像本身而使用图像渐变可能是值得考虑的。这可能会提供更好的图像,因为这样会选择一个字母,它很好地跟随边缘。 仅使用渐变,谷歌徽标看起来并不那么糟糕


    这是一个旧线程,但我最好在这里添加我的解决方案。您可以使用盲文字符获得像素完美表示。像这样:

    
    ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
    ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
    ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⡿⡻⡫⡫⡣⣣⢣⢇⢧⢫⢻⣿⣿⣿⣿
    ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⡟⡟⣝⣜⠼⠼⢚⢚⢚⠓⠷⣧⣇⠧⡳⡱⣻⣿⣿⣿
    ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⡟⣏⡧⠧⠓⠍⡂⡂⠅⠌⠄⠄⠄⡁⠢⡈⣷⡹⡸⣪⣿⣿⣿⣿
    ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢿⠿⢿⢿⢿⢟⢏⡧⠗⡙⡐⡐⣌⢬⣒⣖⣼⣼⣸⢸⢐⢁⠂⡐⢰⡏⣎⢮⣾⣿⣿⣿⣿
    ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣽⣾⣶⣿⢿?