Python PIL.Image.open()IOError:无法识别图像文件

Python PIL.Image.open()IOError:无法识别图像文件,python,image,python-imaging-library,Python,Image,Python Imaging Library,显然,这在Python中是一个相当常见的问题(请参阅,和),但我无法理解为什么会在这个脚本中发生这种情况,我从中获取了一些信息。我已经附加了导致问题的代码片段,以及最小工作示例(MWE)和错误跟踪。有人能告诉我我做错了什么吗。多谢各位 片段: def captureTestImage(): command = "raspistill -w %s -h %s -t 0 -e bmp -o -" % (100, 75) imageData = StringIO.StringIO()

显然,这在Python中是一个相当常见的问题(请参阅,和),但我无法理解为什么会在这个脚本中发生这种情况,我从中获取了一些信息。我已经附加了导致问题的代码片段,以及最小工作示例(MWE)和错误跟踪。有人能告诉我我做错了什么吗。多谢各位

片段:

def captureTestImage():
    command = "raspistill -w %s -h %s -t 0 -e bmp -o -" % (100, 75)
    imageData = StringIO.StringIO()
    imageData.write(subprocess.check_output(command, shell=True))
    imageData.seek(0)
    im = Image.open(imageData)
    buffer = im.load()
    imageData.close()
    return im, buffer
Traceback (most recent call last):
  File "./test2.py", line 61, in <module>
    image1, buffer1 = captureTestImage()
  File "./test2.py", line 31, in captureTestImage
    im = Image.open(imageData)
  File "/usr/lib/python2.7/dist-packages/PIL/Image.py", line 1980, in open
    raise IOError("cannot identify image file")
IOError: cannot identify image file
#!/usr/bin/env python

import StringIO
import subprocess
import os
import time
from datetime import datetime
from PIL import Image

# Motion detection settings:
# Threshold (how much a pixel has to change by to be marked as "changed")
# Sensitivity (how many changed pixels before capturing an image)
# ForceCapture (whether to force an image to be captured every forceCaptureTime seconds)
threshold = 10
sensitivity = 20
forceCapture = True
forceCaptureTime = 60 * 60 # Once an hour

# File settings
saveWidth = 1280
saveHeight = 960
diskSpaceToReserve = 40 * 1024 * 1024 # Keep 40 mb free on disk

# Capture a small test image (for motion detection)
def captureTestImage():
    command = "raspistill -w %s -h %s -t 0 -e bmp -o -" % (100, 75)
    imageData = StringIO.StringIO()
    imageData.write(subprocess.check_output(command, shell=True))
    imageData.seek(0)
    im = Image.open(imageData)
    buffer = im.load()
    imageData.close()
    return im, buffer

# Save a full size image to disk
def saveImage(width, height, diskSpaceToReserve):
    keepDiskSpaceFree(diskSpaceToReserve)
    time = datetime.now()
    filename = "capture-%04d%02d%02d-%02d%02d%02d.jpg" % (time.year, time.month, time.day, time.hour, time.minute, time.second)
    subprocess.call("raspistill -w 1296 -h 972 -t 0 -e jpg -q 15 -o %s" % filename, shell=True)
    print "Captured %s" % filename

# Keep free space above given level
def keepDiskSpaceFree(bytesToReserve):
    if (getFreeSpace() < bytesToReserve):
        for filename in sorted(os.listdir(".")):
            if filename.startswith("capture") and filename.endswith(".jpg"):
                os.remove(filename)
                print "Deleted %s to avoid filling disk" % filename
                if (getFreeSpace() > bytesToReserve):
                    return

# Get available disk space
def getFreeSpace():
    st = os.statvfs(".")
    du = st.f_bavail * st.f_frsize
    return du

# Get first image
image1, buffer1 = captureTestImage()

# Reset last capture time
lastCapture = time.time()

while (True):

    # Get comparison image
    image2, buffer2 = captureTestImage()

    # Count changed pixels
    changedPixels = 0
    for x in xrange(0, 100):
        for y in xrange(0, 75):
            # Just check green channel as it's the highest quality channel
            pixdiff = abs(buffer1[x,y][1] - buffer2[x,y][1])
            if pixdiff > threshold:
                changedPixels += 1

    # Check force capture
    if forceCapture:
        if time.time() - lastCapture > forceCaptureTime:
            changedPixels = sensitivity + 1

    # Save an image if pixels changed
    if changedPixels > sensitivity:
        lastCapture = time.time()
        saveImage(saveWidth, saveHeight, diskSpaceToReserve)

    # Swap comparison buffers
    image1 = image2
    buffer1 = buffer2
错误跟踪:

def captureTestImage():
    command = "raspistill -w %s -h %s -t 0 -e bmp -o -" % (100, 75)
    imageData = StringIO.StringIO()
    imageData.write(subprocess.check_output(command, shell=True))
    imageData.seek(0)
    im = Image.open(imageData)
    buffer = im.load()
    imageData.close()
    return im, buffer
Traceback (most recent call last):
  File "./test2.py", line 61, in <module>
    image1, buffer1 = captureTestImage()
  File "./test2.py", line 31, in captureTestImage
    im = Image.open(imageData)
  File "/usr/lib/python2.7/dist-packages/PIL/Image.py", line 1980, in open
    raise IOError("cannot identify image file")
IOError: cannot identify image file
#!/usr/bin/env python

import StringIO
import subprocess
import os
import time
from datetime import datetime
from PIL import Image

# Motion detection settings:
# Threshold (how much a pixel has to change by to be marked as "changed")
# Sensitivity (how many changed pixels before capturing an image)
# ForceCapture (whether to force an image to be captured every forceCaptureTime seconds)
threshold = 10
sensitivity = 20
forceCapture = True
forceCaptureTime = 60 * 60 # Once an hour

# File settings
saveWidth = 1280
saveHeight = 960
diskSpaceToReserve = 40 * 1024 * 1024 # Keep 40 mb free on disk

# Capture a small test image (for motion detection)
def captureTestImage():
    command = "raspistill -w %s -h %s -t 0 -e bmp -o -" % (100, 75)
    imageData = StringIO.StringIO()
    imageData.write(subprocess.check_output(command, shell=True))
    imageData.seek(0)
    im = Image.open(imageData)
    buffer = im.load()
    imageData.close()
    return im, buffer

# Save a full size image to disk
def saveImage(width, height, diskSpaceToReserve):
    keepDiskSpaceFree(diskSpaceToReserve)
    time = datetime.now()
    filename = "capture-%04d%02d%02d-%02d%02d%02d.jpg" % (time.year, time.month, time.day, time.hour, time.minute, time.second)
    subprocess.call("raspistill -w 1296 -h 972 -t 0 -e jpg -q 15 -o %s" % filename, shell=True)
    print "Captured %s" % filename

# Keep free space above given level
def keepDiskSpaceFree(bytesToReserve):
    if (getFreeSpace() < bytesToReserve):
        for filename in sorted(os.listdir(".")):
            if filename.startswith("capture") and filename.endswith(".jpg"):
                os.remove(filename)
                print "Deleted %s to avoid filling disk" % filename
                if (getFreeSpace() > bytesToReserve):
                    return

# Get available disk space
def getFreeSpace():
    st = os.statvfs(".")
    du = st.f_bavail * st.f_frsize
    return du

# Get first image
image1, buffer1 = captureTestImage()

# Reset last capture time
lastCapture = time.time()

while (True):

    # Get comparison image
    image2, buffer2 = captureTestImage()

    # Count changed pixels
    changedPixels = 0
    for x in xrange(0, 100):
        for y in xrange(0, 75):
            # Just check green channel as it's the highest quality channel
            pixdiff = abs(buffer1[x,y][1] - buffer2[x,y][1])
            if pixdiff > threshold:
                changedPixels += 1

    # Check force capture
    if forceCapture:
        if time.time() - lastCapture > forceCaptureTime:
            changedPixels = sensitivity + 1

    # Save an image if pixels changed
    if changedPixels > sensitivity:
        lastCapture = time.time()
        saveImage(saveWidth, saveHeight, diskSpaceToReserve)

    # Swap comparison buffers
    image1 = image2
    buffer1 = buffer2
回溯(最近一次呼叫最后一次):
文件“/test2.py”,第61行,在
image1,buffer1=capturestimage()
captureTestImage中第31行的文件“/test2.py”
im=图像。打开(图像数据)
文件“/usr/lib/python2.7/dist packages/PIL/Image.py”,第1980行,打开
raise IOError(“无法识别图像文件”)
IOError:无法识别图像文件
MWE:

def captureTestImage():
    command = "raspistill -w %s -h %s -t 0 -e bmp -o -" % (100, 75)
    imageData = StringIO.StringIO()
    imageData.write(subprocess.check_output(command, shell=True))
    imageData.seek(0)
    im = Image.open(imageData)
    buffer = im.load()
    imageData.close()
    return im, buffer
Traceback (most recent call last):
  File "./test2.py", line 61, in <module>
    image1, buffer1 = captureTestImage()
  File "./test2.py", line 31, in captureTestImage
    im = Image.open(imageData)
  File "/usr/lib/python2.7/dist-packages/PIL/Image.py", line 1980, in open
    raise IOError("cannot identify image file")
IOError: cannot identify image file
#!/usr/bin/env python

import StringIO
import subprocess
import os
import time
from datetime import datetime
from PIL import Image

# Motion detection settings:
# Threshold (how much a pixel has to change by to be marked as "changed")
# Sensitivity (how many changed pixels before capturing an image)
# ForceCapture (whether to force an image to be captured every forceCaptureTime seconds)
threshold = 10
sensitivity = 20
forceCapture = True
forceCaptureTime = 60 * 60 # Once an hour

# File settings
saveWidth = 1280
saveHeight = 960
diskSpaceToReserve = 40 * 1024 * 1024 # Keep 40 mb free on disk

# Capture a small test image (for motion detection)
def captureTestImage():
    command = "raspistill -w %s -h %s -t 0 -e bmp -o -" % (100, 75)
    imageData = StringIO.StringIO()
    imageData.write(subprocess.check_output(command, shell=True))
    imageData.seek(0)
    im = Image.open(imageData)
    buffer = im.load()
    imageData.close()
    return im, buffer

# Save a full size image to disk
def saveImage(width, height, diskSpaceToReserve):
    keepDiskSpaceFree(diskSpaceToReserve)
    time = datetime.now()
    filename = "capture-%04d%02d%02d-%02d%02d%02d.jpg" % (time.year, time.month, time.day, time.hour, time.minute, time.second)
    subprocess.call("raspistill -w 1296 -h 972 -t 0 -e jpg -q 15 -o %s" % filename, shell=True)
    print "Captured %s" % filename

# Keep free space above given level
def keepDiskSpaceFree(bytesToReserve):
    if (getFreeSpace() < bytesToReserve):
        for filename in sorted(os.listdir(".")):
            if filename.startswith("capture") and filename.endswith(".jpg"):
                os.remove(filename)
                print "Deleted %s to avoid filling disk" % filename
                if (getFreeSpace() > bytesToReserve):
                    return

# Get available disk space
def getFreeSpace():
    st = os.statvfs(".")
    du = st.f_bavail * st.f_frsize
    return du

# Get first image
image1, buffer1 = captureTestImage()

# Reset last capture time
lastCapture = time.time()

while (True):

    # Get comparison image
    image2, buffer2 = captureTestImage()

    # Count changed pixels
    changedPixels = 0
    for x in xrange(0, 100):
        for y in xrange(0, 75):
            # Just check green channel as it's the highest quality channel
            pixdiff = abs(buffer1[x,y][1] - buffer2[x,y][1])
            if pixdiff > threshold:
                changedPixels += 1

    # Check force capture
    if forceCapture:
        if time.time() - lastCapture > forceCaptureTime:
            changedPixels = sensitivity + 1

    # Save an image if pixels changed
    if changedPixels > sensitivity:
        lastCapture = time.time()
        saveImage(saveWidth, saveHeight, diskSpaceToReserve)

    # Swap comparison buffers
    image1 = image2
    buffer1 = buffer2
#/usr/bin/env python
导入StringIO
导入子流程
导入操作系统
导入时间
从日期时间导入日期时间
从PIL导入图像
#运动检测设置:
#阈值(像素必须改变多少才能标记为“已更改”)
#灵敏度(拍摄图像前改变了多少像素)
#ForceCapture(是否强制每隔forceCaptureTime秒捕获一个图像)
阈值=10
灵敏度=20
forceCapture=True
forceCaptureTime=60*60#每小时一次
#文件设置
saveWidth=1280
saveHeight=960
diskSpaceToReserve=40*1024*1024#在磁盘上保留40 mb的可用空间
#捕获小测试图像(用于运动检测)
def captureTestImage():
command=“raspistill-w%s-h%s-t0-ebmp-o-”%(100,75)
imageData=StringIO.StringIO()
imageData.write(子进程检查输出(命令,shell=True))
imageData.seek(0)
im=图像。打开(图像数据)
buffer=im.load()
imageData.close()
返回即时消息,缓冲区
#将全尺寸图像保存到磁盘
def saveImage(宽度、高度、磁盘空间存储服务):
keepDiskSpaceFree(diskSpaceToReserve)
time=datetime.now()
filename=“捕获-%04d%02d%02d-%02d%02d%02d.jpg”%(time.year、time.month、time.day、time.hour、time.minute、time.second)
调用(“raspistill-w 1296-h 972-t0-e jpg-q 15-o%s”%filename,shell=True)
打印“捕获的%s”%filename
#将自由空间保持在给定标高以上
def keepDiskSpaceFree(bytesToReserve):
如果(getFreeSpace()bytesToReserve):
返回
#获取可用磁盘空间
def getFreeSpace():
st=os.statvfs(“.”)
du=标准尺寸*标准尺寸
返回du
#获取第一张图像
image1,buffer1=capturestimage()
#重置上次捕获时间
lastCapture=time.time()
虽然(正确):
#获取比较图像
image2,buffer2=capturestimage()
#计数已更改的像素数
changedPixels=0
对于x范围内的x(0,100):
对于X范围内的y(0,75):
#只需检查绿色通道,因为它是最高质量的通道
pixdiff=abs(buffer1[x,y][1]-buffer2[x,y][1])
如果pixdiff>阈值:
changedPixels+=1
#检查强制捕获
如果强制捕获:
如果time.time()-lastCapture>forceCaptureTime:
更改像素=灵敏度+1
#如果像素发生更改,请保存图像
如果更改像素>灵敏度:
lastCapture=time.time()
saveImage(saveWidth、saveHeight、diskSpaceToReserve)
#交换比较缓冲区
图像1=图像2
buffer1=buffer2

天哪,我觉得自己真的很愚蠢,但这根本不是软件问题,而是一个不稳定的Raspi问题。结果表明,相机的正确驱动程序尚未加载,因此相机没有拍照,而是生成了一个错误。只需重新启动即可。

无论是谁否决了这一点,请给出一个原因,说明这是一个经过充分研究、写得很好的问题,+1