【问题标题】:Python Script to detect broken images用于检测损坏图像的 Python 脚本
【发布时间】:2018-04-01 22:38:57
【问题描述】:

我编写了一个 python 脚本来检测损坏的图像并计算它们, 我的脚本中的问题是它检测到所有图像并且没有检测到损坏的图像。如何解决这个问题。我参考了:

How to check if a file is a valid image file? 我的代码

我的代码

import os
from os import listdir
from PIL import Image
count=0
for filename in os.listdir('/Users/ajinkyabobade/Desktop/2'):
    if filename.endswith('.JPG'):
     try:
      img=Image.open('/Users/ajinkyabobade/Desktop/2'+filename)
      img.verify()
     except(IOError,SyntaxError)as e:
         print('Bad file  :  '+filename)
         count=count+1
         print(count)

【问题讨论】:

    标签: python image jpeg python-imaging-library python-3.6


    【解决方案1】:

    你正在构建一条糟糕的道路

    img=Image.open('/Users/ajinkyabobade/Desktop/2'+filename)      
    

    请尝试以下操作(通过将 / 添加到目录路径的末尾)

    img=Image.open('/Users/ajinkyabobade/Desktop/2/'+filename)      
    

    img=Image.open(os.path.join('/Users/ajinkyabobade/Desktop/2', filename))
    

    【讨论】:

    • 这有助于我指定路径,但是,我在输出中没有得到任何错误文件。我已将坏文件添加到文件夹 2 以检查(坏文件是指扩展名为 .jpg 但无法在电脑上打开的文件)
    • “打不开”是什么意思?如果我复制一个python文件并在检查时给它一个.jpg扩展名,如果我打印出异常,我会得到“无法识别图像文件”。你可以试试吗?
    • 感谢无法打开 我的意思是“无法打开文件 2-10580.jpg:它可能已损坏或使用了预览无法识别的文件格式。”。我发现了错误:我正在保存扩展名为 .jpg 的文件,但在 python 中,我有 filename.ends('.JPG') (全部大写)。如果您能让我知道如何使用 python 脚本将大写 .JPG 扩展名自动转换为文件夹 2 中的小 .jpg 扩展名,您的解决方案解决了我将不胜感激的问题
    • .JPG 是一个有效的扩展名。您可以使用if filename.upper().endswith('.JPG') 来捕获两者
    • 快速提问如何删除这些损坏的图像?
    【解决方案2】:

    我添加了另一个 SO 答案 here,它扩展了 PIL 解决方案以更好地检测损坏的图像。 我还在我的 Python 脚本 here on GitHub 中实现了这个解决方案。

    我还验证了损坏的文件 (jpg) 通常不是“损坏”的图像,即损坏的图片文件有时仍然是合法的图片文件,原始图像丢失或更改但您仍然可以加载它。

    为了完整起见,我引用了另一个答案:

    您可以使用 Python Pillow(PIL) 模块和大多数图像格式来检查文件是否是有效且完整的图像文件。

    如果您还打算检测损坏的图像,@Nadia Alramli 会正确建议 im.verify() 方法,但这不会检测到所有可能的图像缺陷,例如,im.verify 不会检测截断的图像(大多数查看器通常加载灰色区域)。

    Pillow 也能够检测到这些类型的缺陷,但您必须应用图像处理或图像解码/重新编码或触发检查。最后我建议使用这段代码:

    try:
      im = Image.load(filename)
      im.verify() #I perform also verify, don't know if he sees other types o defects
      im.close() #reload is necessary in my case
      im = Image.load(filename) 
      im.transpose(PIL.Image.FLIP_LEFT_RIGHT)
      im.close()
    except: 
      #manage excetions here
    

    如果出现图像缺陷,此代码将引发异常。 请考虑 im.verify 比执行图像处理快大约 100 倍(我认为翻转是更便宜的转换之一)。 使用此代码,您将以大约 10 MBytes/sec(现代 2.5Ghz x86_64 CPU)验证一组图像。

    对于其他格式psd,xcf,..可以使用Imagemagick包装器Wand,代码如下:

    im = wand.image.Image(filename=filename)
    temp = im.flip;
    im.close()
    

    但是,根据我的实验,Wand 没有检测到截断的图像,我认为它会在没有提示的情况下将缺少的部分加载为灰色区域。

    我认为 Imagemagick 有一个外部命令 identify 可以 完成这项工作,但我还没有找到调用该函数的方法以编程方式,我还没有测试过这条路线。

    我建议始终进行初步检查,检查文件大小不为零(或非常小),这是一个非常便宜的想法:

    statfile = os.stat(filename)
    filesize = statfile.st_size
    if filesize == 0:
      #manage here the 'faulty image' case
    

    【讨论】:

    • PIL 更新版本:在im = Image.open(...) 之后,使用im.load() 代替转置操作。这也捕获了截断的图像异常,并且似乎比执行实际的图像转换更快。
    • 我会检查一下并更新我的脚本以防万一,谢谢!
    【解决方案3】:

    尝试以下方法:它对我来说效果很好。它会识别坏/损坏的图像并将其删除。或者,如果您愿意,您只能打印错误/损坏的文件名并删除最终脚本以删除文件。

    for filename in listdir('/Users/ajinkyabobade/Desktop/2/'):
        if filename.endswith('.JPG'):
            try:
                img = Image.open('/Users/ajinkyabobade/Desktop/2/'+filename)  # open the image file
                img.verify()  # verify that it is, in fact an image
            except (IOError, SyntaxError) as e:
                print(filename)
                os.remove('/Users/ajinkyabobade/Desktop/2/'+filename)
    

    【讨论】:

      【解决方案4】:

      我收到一条错误消息,告诉我Image.load 不可用。 Image.open 似乎有效。

      我也遇到了错误:

      except (IOError, SyntaxError) as e:
      

      我只是将其更改为:

      except:
      

      效果很好。

      【讨论】:

        猜你喜欢
        • 2012-04-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-31
        • 1970-01-01
        相关资源
        最近更新 更多