Ошибка открытия файла PGM с PIL и SKIMAGE - PullRequest
2 голосов
/ 20 февраля 2020

У меня есть следующий файл изображения:

Изображение

Я использовал PIL и Skimage, чтобы открыть его, но я получаю следующие ошибки

Сначала с PIL (пробовал с опцией Trucate и без нее): Код:

from PIL import Image, ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True
img = Image.open("image_output.pgm")

Erorr:

OSError: cannot identify image file 'image_output.pgm'

И с Skimage:

Код:

from skimage import io
img = io.imread("image_output.pgm")

Ошибка:

OSError: cannot identify image file <_io.BufferedReader name='image_output.pgm'>

Я могу открыть файл с помощью GUI приложений, таких как система просмотра фотографий и Matlab.

Как я могу диагностировать, что не так с изображением? Я сравнил байтовые данные с другими файлами PGM, которые я могу открыть в Python, но не смог определить разницу.

Спасибо.

1 Ответ

3 голосов
/ 20 февраля 2020

Ваш файл P2 тип PGM , что означает, что он находится в ASCII - вы можете просмотреть его в обычном текстовом редакторе. Кажется, ни PIL , ни skimage не хотят это читать, но рады прочитать соответствующий тип P5, который идентичен, за исключением того, что он записан в двоичном формате, а не в ASCII.

Есть несколько вариантов ...


1) Вы можете использовать OpenCV , чтобы прочитать его:

import cv2
im = cv2.imread('a.pgm')

2) Вы можете преобразовать его в P5 с помощью ImageMagick и затем прочитать файл output.pgm с skimage или PIL :

magick input.pgm output.pgm

3) Если вы добавляете OpenCV или ImageMagick в качестве зависимости, то это настоящая боль для вас, возможно самостоятельно прочитать изображение PGM :

#!/usr/bin/env python3

import re
import numpy as np

# Open image file, slurp the lot
with open('input.pgm') as f:
   s = f.read()

# Find anything that looks like numbers
# Technically, there could be comments that should be ignored
l=re.findall(r'[0-9P]+',s)

# List "l" will contain: P5, width, height, 255, pixel1, pixel2, pixel3...
# Technically, if l[3]>255, you should change the type of the Numpy array to uint16, but that is not the case
w, h = int(l[1]), int(l[2])

# Make Numpy image from data
ni = np.array(l[4:],dtype=np.uint8).reshape((h,w))

enter image description here

...