【问题标题】:Convert each pixel from a image to a letter PIL将图像中的每个像素转换为字母 PIL
【发布时间】:2021-03-20 08:06:11
【问题描述】:

我有一个由黑白像素 (16x16 img) 组成的文件“map.jpg”,我想在文本文件中将白色像素转换为 0,将黑色像素转换为 1。我有这个:

from PIL import Image
import os

mapImg = Image.open('map.png')

with open('map.txt', 'a+') as map:
    for y in range(16):
        for x in range(16):
            pix = mapImg.getpixel((x, y))
            if x == 15:
                map.write('\n')
            else:
                if pix == (255, 255, 255):
                    map.write('0')
                else:
                    map.write('1')

但是不知道为什么我的txt文件里的结果是这样的:

000000000
0011000000
0111110000
0100000110
0010011100
0101010
0111100
000010101000
001110000
00011000000
0000100000
0011000
0000010000
00000000
000000000
000000000

这不是“map.jpg”文件的样子。

编辑:感谢 Random Davis,问题解决了!只需要更改图像格式,因为 jpeg 将 img 压缩到太多或其他东西,谢谢!

【问题讨论】:

  • 嗯?为什么map.jpg 没有出现在您的代码中?
  • 啊,是的,我的错,我在帖子上删除了它
  • @MarkSetchell 他们没有显示mapImg 的定义位置,所以肯定是使用map.jpg 的位置。

标签: python python-imaging-library jpeg


【解决方案1】:

除了 jpg 文件使用有损压缩这一事实之外,正如另一个答案所描述的,无损压缩的图像文件(例如 png)还可以包含所有不同的 RGB 颜色组合(例如不同的灰色调)。如果您只对黑白之间的区别感兴趣,您可以例如计算平均 RGB 值¹并使用阈值(如果平均值 ≥ 128,则写入 0,否则写入 1)。这也适用于有损压缩的 jpg 文件,因为压缩算法通常不会过多地改变像素,以至于明亮的像素会突然变暗。

你最后的if 语句可以写成如下:

pix_avg_rgb = sum(pix) / 3
if pix_avg_rgb >= 128:
    map.write('0')
else:
    map.write('1')

¹ 由于 RGB 颜色空间与感知亮度之间的非线性,平均 RGB 值与像素的感知亮度不完全匹配,但这超出了本问题的范围。

【讨论】:

    【解决方案2】:

    如果您的图像是jpg,那么它会被有损压缩,这意味着所有像素不一定都是全黑或全白的。您需要一个真正只有这两种颜色的无损来源,否则像素将被错误分类。

    【讨论】:

    • PNG 是一种很好的无损格式。当然,您的原始图像必须是 PNG,将已经有损压缩的 JPG 转换为 PNG 不会改变任何内容,因为损坏已经造成。
    • 好的,谢谢!你拯救了我的一天:)
    • @Scaffus。如果您知道像素值保证为其中一个,则可以只检查 > 127 或
    猜你喜欢
    • 1970-01-01
    • 2015-12-31
    • 1970-01-01
    • 2016-05-29
    • 1970-01-01
    • 1970-01-01
    • 2013-08-31
    • 2016-01-11
    • 2016-12-04
    相关资源
    最近更新 更多