如何使用PIL读取原始图像?

Alc*_*sta 30 python image image-processing python-imaging-library

我有一个原始图像,其中每个像素对应一个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')
Run Code Online (Sandbox Code Playgroud)

PIL文档通知fromstring()函数的第一个参数是'mode'.然而,看文档和谷歌搜索,我无法找到有关该论点真正意义的细节(我相信它与色彩空间或类似的东西有关).有谁知道我在哪里可以找到关于fromstring()函数的更详细的参考以及mode参数的含义?

Kat*_*iel 20

具体文件见http://effbot.org/imagingbook/concepts.htm:

模式

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

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

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


Way*_*ner 10

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

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

我不确定"L"代表什么,但"RGBA"代表Red-Green-Blue-Alpha,所以我认为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')
Run Code Online (Sandbox Code Playgroud)

你会看到不同模式的作用 - 尝试使用各种输入图像:png with alpha,png without alpha,bmp,gif和jpeg.实际上,这是一个有趣的实验.


mar*_*eau 5

如果所有其他方法都失败了,您可以随时阅读源代码.对于PIL,下载在这里.

你从来没有准确地说过16位无符号整数中的像素数据是什么格式,但我猜它有点像RRRRRGGGGGGBBBBBB,(5位红色,6位绿色,5位蓝色)或RRRRRGGGGGBBBBBA(5-位红色,5位绿色,5位蓝色,1位Alpha或透明度).在我自己快速浏览了一些来源之后,我没有看到对这些格式的支持,但是不能肯定地说出这种或那种方式.

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

希望这可以帮助.


mat*_*asg 5

这是一个古老的问题,但这可能会对将来的某人有所帮助。原始代码片段的问题之一是,在 中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')
Run Code Online (Sandbox Code Playgroud)