OSError: image file is truncated (X bytes not processed)解決方案(無需刪數據)


問題的原因:沒弄懂,畢竟我找到問題圖片查看后,也沒發現啥問題.....

我的當前環境:數據集圖片為jpg格式,圖片的量級有點大,估計問題圖片有點多,所以不能直接刪除或者跳過,所以得找出來,再重新處理后放回原位。

解決方法:讀取文件夾下找到異常圖片,處理異常圖片使之正常。

代碼詳細說明:

1.讀取文件夾找到異常圖片

先從數據集的根目錄進入,一層一層保存文件夾信息,逐個文件夾的圖片進行檢查圖片是否有問題,若存在問題,將圖片重命名,按其一層一層的地址重命名,便於后期修復后移動回原位。為了問題圖片統一處理,尤其是大數據集下,會將所有問題圖片放到根目錄的error文件夾下,error文件夾需要提前創建。

檢查圖片是否有問題的代碼見下,來自參考鏈接1。

1 # 判斷圖片是否正常
2 def is_valid_jpg(jpg_file): 3     # 判斷jpg文件下載是否完整
4     if jpg_file.split('.')[-1].lower() == 'jpg': 5         with open(jpg_file, 'rb') as f: 6             f.seek(-2, 2) 7             return f.read() == b'\xff\xd9'
8     else: 9         return "this file is not jpg"

2.修復異常圖片

對error文件夾下的圖片使用opencv讀取並另存,另存后的圖片應當是沒有問題的,會重新異常檢測,若無問題,將修復后的圖片移動至根目錄的ok文件夾下,該文件夾同樣需要提前手動創建。這樣你就可以看到是否所有圖片都修復成功。修復后的圖片請按照圖片名手動放回原位吧!

以下是修復圖片主要代碼,同樣來自於參考鏈接1。

 1 # 修復問題圖片
 2 def repair_img(root_path):  3     path = os.path.join(root_path, "error")  4     _path = os.path.join(root_path, "ok")  5     for fileName in os.listdir(path):  6         file_path = os.path.join(path, fileName)  7         img = cv2.imread(file_path)  8         new_path = os.path.join(_path, fileName)  9  cv2.imwrite(new_path, img) 10         if is_valid_jpg(new_path):  # 新存儲的圖片沒有之前的問題了
11             print("OK")  # 這里的代碼和完整代碼有些許出入,完整代碼里面執行的是圖片移動到ok的文件夾

至此。

(若您知道以上原理還請在評論區大家一起討論呀:>

完整代碼參考(已帶注釋):

 1 import os  2 import cv2  3 import sys  4 from random import randint  5 import shutil  6 
 7 # 判斷圖片是否正常
 8 def is_valid_jpg(jpg_file):  9     # 判斷jpg文件下載是否完整
10     if jpg_file.split('.')[-1].lower() == 'jpg': 11         with open(jpg_file, 'rb') as f: 12             f.seek(-2, 2) 13             return f.read() == b'\xff\xd9'
14     else: 15         return "this file is not jpg"
16 
17 # 找出文件夾下所有問題圖片,重命名后移動到統一的文件夾,重命名是為了方便后期移動回原位置
18 def filter_jpg(root_path): 19     for package in os.listdir(root_path):  # Cyber
20         if package == 'error':  # 不進入error文件夾,這個文件夾單獨存放問題圖片
21             continue
22         sub1_path = os.path.join(root_path, package) 23         for pack in os.listdir(sub1_path):  # test
24             sub2_path = os.path.join(sub1_path, pack)  # /dataset/cyber/test
25             for direc in os.listdir(sub2_path):  # first
26                 sub3_path = os.path.join(sub2_path, direc)  # /dataset/cyber/test/first
27                 for filename in os.listdir(sub3_path): 28                     file_path = os.path.join(sub3_path, filename) 29                     ans = is_valid_jpg(file_path) 30                     if ans != True:  # 若圖片有問題
31                         newName = package + '_' + pack + '_' + direc + '_' + str(randint(0, 1000)) 32                         src = os.path.join(os.path.abspath(sub3_path), filename) 33                         dst = os.path.join(os.path.abspath(sub3_path), newName + '.jpg') 34                         try: 35                             os.rename(src, dst)  # 重命名
36                             shutil.move(dst, os.path.join(root_path, 'error', newName + '.jpg'))  # 移動圖片
37                         except: 38                             print("falure") 39  sys.exit(0) 40                         print(sub3_path) 41                         print(filename) 42 
43 # 修復問題圖片后,保存至ok文件夾(這個文件夾要提前創建),后面需要手動移動一下修復后的圖片
44 def repair_img(root_path): 45     path = os.path.join(root_path, "error") 46     _path = os.path.join(root_path, "ok") 47     for fileName in os.listdir(path): 48         file_path = os.path.join(path, fileName) 49         img = cv2.imread(file_path) 50         new_path = os.path.join(_path, fileName) 51  cv2.imwrite(new_path, img) 52         if is_valid_jpg(new_path):  # 新存儲的圖片是ok的
53  os.remove(file_path) 54 
55 
56 if __name__ == '__main__': 57     root_path = "./dataset"
58  filter_jpg(root_path) 59     repair_img(root_path)
View Code

 

參考鏈接:

https://www.zhihu.com/question/30372655

https://www.cnblogs.com/haifwu/archive/2020/05/07/12846774.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM