问题
I have following Image file:
Image
I used PIL and Skimage to open it but I get following errors
First with PIL (tried with and without trucate option): Code:
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'
And with Skimage:
Code:
from skimage import io
img = io.imread("image_output.pgm")
Error:
OSError: cannot identify image file <_io.BufferedReader name='image_output.pgm'>
I can open the file with GUI applications like system photo viewer and Matlab.
How can I diagnose what is wrong with image? I compared the byte data with other PGM files which I can open in Python, but could not identify the difference.
Thanks.
回答1:
Your file is P2
type PGM, which means it is in ASCII - you can view it in a normal text editor. It seems neither PIL, nor skimage want to read that, but are happy to read the corresponding P5
type which is identical except it is written in binary, rather than ASCII.
There are a few options...
1) You could use OpenCV to read it:
import cv2
im = cv2.imread('a.pgm')
2) You could convert it to P5
with ImageMagick and then read the output.pgm
file with skimage or PIL:
magick input.pgm output.pgm
3) If adding OpenCV, or ImageMagick as a dependency is a real pain for you, it is possible to read a PGM image yourself:
#!/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))
来源:https://stackoverflow.com/questions/60309764/error-opening-pgm-file-with-pil-and-skimage