如何使用PIL读取原始图像?
image
image-processing
python
python-imaging-library
5
0

我有一个原始图像,其中每个像素对应一个16位无符号整数。我正在尝试使用PIL Image.fromstring()函数进行读取,如以下代码所示:

if __name__ == "__main__":
    if (len(sys.argv) != 4):
        print 'Error: missing input argument'
        sys.exit()

    file = open(sys.argv[1], 'rb')
    rawData = file.read()
    file.close()

    imgSize = (int(sys.argv[2]), int(sys.argv[3]))

    # Use the PIL raw decoder to read the data.
    #   - the 'F;16' informs the raw decoder that we are reading a little endian, unsigned integer 16 bit data.
    img = Image.fromstring('L', imgSize, rawData, 'raw', 'F;16')

    im.save('out.png')

PIL文档通知fromstring()函数的第一个参数为'mode'。但是,在查看文档并进行谷歌搜索时,我无法找到有关该参数真正含义的详细信息(我相信它与色彩空间或类似的东西有关)。有谁知道我在哪里可以找到有关fromstring()函数以及mode参数含义的详细参考?

参考资料:
Stack Overflow
收藏
评论
共 4 个回答
高赞 时间 活跃

Image.frombuffer(模式,大小,数据)=>图片

(PIL 1.1.4中的新增功能)。使用标准的“原始”解码器,根据字符串或缓冲区对象中的像素数据创建图像存储器。对于某些模式,图像内存将与原始缓冲区共享内存(这意味着对原始缓冲区对象的更改会反映在图像中)。并非所有模式都可以共享内存。支持的模式包括“ L”,“ RGBX”,“ RGBA”和“ CMYK”。对于其他模式,此函数的行为类似于对fromstring函数的相应调用。

我不确定“ L”代表什么,但“ RGBA”代表红-绿-蓝-阿尔法,所以我假设RGBX等同于RGB(编辑:经过测试,情况并非如此)? CMYK是Cyan-Magenta-Yellow-Kelvin,这是另一种颜色空间。当然,我假设如果您了解PIL,那么您也会了解色彩空间。如果没有,那么维基百科上有一篇很棒的文章。

至于真正的含义(如果还不够的话):每个颜色空间的像素值编码方式都不同。在常规RGB中,每个像素有3个字节-0-254、0-254、0-254。对于Alpha,您向每个像素添加另一个字节。如果将RGB图像解码为RGBA,最终将读取第一个像素右侧的R像素作为Alpha,这意味着将获得G像素作为R值。根据图像的大小,此比例会被放大,但这确实会使您的颜色变得不稳定。同样,尝试将CMYK编码的图像读取为RGB(或RGBA)将使您的图像看起来非常不像预期的那样。例如,尝试使用图像:

i = Image.open('image.png')
imgSize = i.size
rawData = i.tostring()
img = Image.fromstring('L', imgSize, rawData)
img.save('lmode.png')
img = Image.fromstring('RGB', imgSize, rawData)
img.save('rgbmode.png')
img = Image.fromstring('RGBX', imgSize, rawData)
img.save('rgbxmode.jfif')
img = Image.fromstring('RGBA', imgSize, rawData)
img.save('rgbamode.png')
img = Image.fromstring('CMYK', imgSize, rawData)
img.save('rgbamode.tiff')

然后,您将看到不同模式的作用-尝试各种输入图像:带alpha的png,不带alpha的png,bmp,gif和jpeg。实际上,这是一个有趣的实验。

收藏
评论

这是一个古老的问题,但这可能会在将来对某人有所帮助。原始代码段的问题之一是在Image.fromstring('L', imgSize, rawData, 'raw', 'F;16')F;16部分适用于'F'模式。

这对我有用:

image = Image.fromstring('F', imgSize, rawData, 'raw', 'F;16')
image.convert('L').save('out.png')
收藏
评论

如果其他所有方法均失败,则始终可以阅读源代码。对于PIL,可在此处下载。

您从未说过16位无符号整数中的像素数据的格式到底是什么,但是我想它就像是RRRRRRGGGGGGBBBBBB((5位红色,6位绿色,5位蓝色)或RRRRRRGGGGGBBBBBA(5位红色,5位绿色,5位蓝色,1位Alpha或透明度)。我本人快速浏览了一些资源后,没有看到对这些格式的支持,但是不能确定一种方式还是另一种方式。

在下载PIL的同一网页上,他们提到可以将问题发送到Python Image SIG邮件列表并提供链接。这可能比在这里问要好。

希望这可以帮助。

收藏
评论

具体文档位于http://effbot.org/imagingbook/concepts.htm

模式

图像的模式定义图像中像素的类型和深度。当前版本支持以下标准模式:

  • 1(1位像素,黑白,每字节存储一个像素)
  • L(8位像素,黑白)
  • P(8位像素,使用调色板映射到任何其他模式)
  • RGB(3x8位像素,真彩色)
  • RGBA(4x8位像素,带透明蒙版的真彩色)
  • CMYK(4x8位像素,彩色分离)
  • YCbCr(3x8位像素,彩色视频格式)
  • I(32位带符号整数像素)
  • F(32位浮点像素)

PIL还为一些特殊模式提供了有限的支持,包括LA(带有alpha的L),RGBX(带有填充的真彩色)和RGBa(带有预乘alpha的真彩色)。

收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题

关于我们

常见问题

内容许可

联系我们

@2020 AskGo
京ICP备20001863号