問題的原因:沒弄懂,畢竟我找到問題圖片查看后,也沒發現啥問題.....
我的當前環境:數據集圖片為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)
參考鏈接:
https://www.zhihu.com/question/30372655
https://www.cnblogs.com/haifwu/archive/2020/05/07/12846774.html