1. 程式人生 > 其它 >OSError: image file is truncated (X bytes not processed)解決方案(無需刪資料)

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