pythonでOpencvやdlibを使って顔を切り取るプログラムを作成しているのですが、下記プログラムの戻り値箇所でエラー起こってしまいます。
自分で調べても見ても解決方法が見つかりませんでした。画像のPathもあっています。
python
1def fitting_rotated_image(img, angle): 2 # 画像の縦、横のサイズを取得する 3 height, width = img.shape[:2] 4 # 画像の中心値を取得 5 center = (int(width/2), int(height/2)) 6 # 度からラジアンに変換(deg to rad) 7 radians = np.deg2rad(angle) 8 # 回転の変換行列 9 M = cv2.getRotationMatrix2D(center, angle, 1.0) 10 11 new_width = int(abs(np.sin(radians) * height) + abs(np.cos(radians) * width)) 12 new_height = int(abs(np.sin(radians) * width) + abs(np.cos(radians) * height)) 13 14 M[0,2] += int((new_width-width)/2) 15 M[1,2] += int((new_height-height)/2) 16 17 # アファイン変換した画像を返す(ここでエラーが発生sa) 18 return cv2.warpAffine(img, M, (new_width, new_height))
Traceback (most recent call last): File "dlib_face_cut.py", line 82, in <module> rotated_im = fitting_rotated_image(face_im, angle) File "dlib_face_cut.py", line 26, in fitting_rotated_image return cv2.warpAffine(img, M, (new_width, new_height)) cv2.error: OpenCV(4.2.0) C:\projects\opencv-python\opencv\modules\imgproc\src\imgwarp.cpp:2594: error: (-215:Assertion failed) src.cols > 0 && src.rows > 0 in function 'cv::warpAffine'
ディレクトリ内に10万枚近くの画像が入っているのですが、必ず1270枚目でエラーが出ます。(画像に不備があるのかと思い、1270枚目の画像を取り除き実行してみても結果は同じ)
理由がわかる方、教えていただけたら幸いです。宜しくお願い致します。
追加事項
programの全体を載せます。宜しくお願い致します。
python
1import cv2 2import numpy as np 3import math 4import dlib 5import os 6import glob 7import time 8 9def fitting_rotated_image(img, angle): 10 # 画像の縦、横のサイズを取得する 11 height, width = img.shape[:2] 12 # 画像の中心値を取得 13 center = (int(width/2), int(height/2)) 14 # 度からラジアンに変換(deg to rad) 15 radians = np.deg2rad(angle) 16 # 回転の変換行列 17 M = cv2.getRotationMatrix2D(center, angle, 1.0) 18 19 new_width = int(abs(np.sin(radians) * height) + abs(np.cos(radians) * width)) 20 new_height = int(abs(np.sin(radians) * width) + abs(np.cos(radians) * height)) 21 22 M[0,2] += int((new_width-width)/2) 23 M[1,2] += int((new_height-height)/2) 24 25 # アファイン変換した画像を返す 26 return cv2.warpAffine(img, M, (new_width, new_height)) 27 28start = time.time() 29 30# 顔の位置を取得する 31detector = dlib.get_frontal_face_detector() 32# 顔の68箇所の位置の座標を取得する 33predictor = dlib.shape_predictor('./shape_predictor_68_face_landmarks.dat') 34 35# ディレクトリ内の画像を指定 36image_list = glob.glob('./~/*') 37count = 1 38pro_time = 0 39# 新しいディレクトリを作成 40os.makedirs('~', exist_ok = True) 41# for文で一枚ずつ処理していく 42for image in image_list: 43 pro_start = time.time() 44 pro_time += 1 45 print("Processint Time :", pro_time) 46 # 処理する画像を指定 47 im = cv2.imread(image, cv2.IMREAD_COLOR) 48 49 # 画像が見つからない場合 50 if im is None: 51 print("count:", count, '画像が見つかりません') 52 #exit() 53 continue 54 55 rects = detector(im, 1) 56 57 if len(rects) == 0: 58 print("count:", count, '顔が抽出されませんでした') 59 #exit() 60 continue 61 62 for index, rect in enumerate(rects): 63 64 # 顔だけ切り出す 65 rectWidth = rect.width() 66 rectHeight = rect.height() 67 rectCenter = rect.center() 68 x_start = rectCenter.x - rectWidth 69 x_end = x_start + rectWidth * 2 70 y_start = rectCenter.y - rectHeight 71 y_end = y_start + rectHeight * 2 72 face_im = im[y_start:y_end, x_start:x_end] 73 74 # 顔の角度を修正 75 points = [] 76 for point in predictor(im, rect).parts(): 77 points.append([int(point.x), int(point.y)]) 78 79 x_diff = points[45][0] - points[36][0] 80 y_diff = points[45][1] - points[36][1] 81 angle = math.degrees(math.atan2(y_diff, x_diff)) 82 rotated_im = fitting_rotated_image(face_im, angle) 83 84 # 回転後の画像で顔検出して画像保存 85 rotated_rects = detector(rotated_im, 1) 86 if len(rotated_rects) == 0: 87 print("count:", count, '顔が抽出されませんでした') 88 continue 89 90 else: 91 rotated_rect = rotated_rects[0] 92 x_start = rotated_rect.left() 93 x_end = rotated_rect.right() 94 y_start = rotated_rect.top() 95 y_end = rotated_rect.bottom() 96 cropped_im = rotated_im[y_start:y_end, x_start:x_end] 97 98 cv2.imwrite('./~.jpg'.format(count), cropped_im) 99 pro_finish = time.time() 100 101 print("count", count, "finish.") 102 print("Processing Time:", pro_finish - pro_start, "sec") 103 104 count += 1 105 106 print("\n") 107 108finish = time.time() 109 110print("All Processing Time:", finish - start, "sec") 111print(count, "face")