Как прочитать сырое изображение с помощью PIL? - PullRequest
30 голосов
/ 03 августа 2010

У меня есть необработанное изображение, где каждый пиксель соответствует 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'.Однако, глядя на документацию и поиск в Google, я не смог найти подробностей о том, что на самом деле означает этот аргумент (я считаю, что он связан с цветовым пространством или чем-то в этом роде).Кто-нибудь знает, где я могу найти более подробную справку о функции fromstring () и что означает аргумент mode?

Ответы [ 4 ]

20 голосов
/ 03 августа 2010

Специальная документация на 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 (L с альфа), RGBX (истинный цвет с заполнение) и RGBa (истинный цвет с предварительно умноженная альфа).

10 голосов
/ 03 августа 2010

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.Для Альфы вы добавляете еще один байт к каждому пикселю.Если вы декодируете изображение RGB как RGBA, вы в конечном итоге будете считать пиксель R справа от первого пикселя в качестве альфы, что означает, что вы получите пиксель 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')

И вы увидите, что делают разные режимы - попробуйте его с различными входными изображениями: png с альфа, png без альфа, bmp, gifи JPEGВообще-то, это забавный эксперимент.

5 голосов
/ 03 августа 2010

Если ничего не помогает, вы всегда можете прочитать исходный код.Для PIL загрузка здесь здесь .

Вы никогда не говорили точно, в каком формате были пиксельные данные в 16-битных целых числах без знака, но я бы предположил, что это что-то вроде RRRRRGGGGGGBBBBBB (красный, 6-битный зеленый, 5-битный синий) или RRRRRGGGGGBBBBBA (5-битный красный, 5-битный зеленый, 5-битный синий, 1-битная альфа или прозрачность).Я не видел поддержки этих форматов после очень быстрого просмотра некоторых источников самостоятельно, но точно не могу сказать, так или иначе.

На той же веб-странице, где находятся загрузки PIL, они упоминают, что можно отправлять вопросы в список рассылки Python Image SIG и предоставлять ссылку на него.Это может быть лучше, чем спрашивать здесь.

Надеюсь, это поможет.

4 голосов
/ 14 мая 2015

Это старый вопрос, но он может помочь кому-то в будущем. Одна из проблем исходного фрагмента кода заключается в том, что в 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')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...