前提・実現したいこと
openCVで動画を読み込み解析をしているが、時間がかかる。
そこで、動画を表示せず、短時間で解析できるようにしたい。
制約条件:時系列でデータを取得しているので、動画データと
時間軸は合わせたい。
動画が60minなら解析したデータ長も60minであること。
該当のソースコード
python
1import cv2 as cv 2import numpy as np 3import math 4import mediapipe as mp 5import dlib 6import matplotlib.pyplot as plt 7import copy 8import time 9from imutils import face_utils 10from scipy.spatial import distance 11 12TIME = [] 13Blink_TIME = [] 14MARK = [] 15Blink = [] 16YAW = [] 17ROLL = [] 18PITCH = [] 19 20 21st = time.time() 22 23def calc_eye(eye): 24 p2_p6 = distance.euclidean(eye[1], eye[5]) 25 p3_p5 = distance.euclidean(eye[2], eye[4]) 26 p1_p4 = distance.euclidean(eye[0], eye[3]) 27 EAR = (p2_p6 + p3_p5)/(2.0*p1_p4) 28 return(round(EAR, 3))
###課題となっている箇所
def main(): ############################################################### cap = cv.VideoCapture("/Users/a440/movie_analysis.mp4") ret, image = cap.read() cap.set(cv.CAP_PROP_FRAME_WIDTH, 1000) cap.set(cv.CAP_PROP_FRAME_HEIGHT, 800) # モデルロード ############################################################# mp_face_mesh = mp.solutions.face_mesh face_mesh = mp_face_mesh.FaceMesh( max_num_faces=1, min_detection_confidence=0.5, min_tracking_confidence=0.5, ) ############################################################ # Main # ############################################################ while True: # カメラキャプチャ ##################################################### ret, image = cap.read() if not ret: break #image = cv.flip(image, 1) # ミラー表示 debug_image = copy.deepcopy(image)
# 検出実施 ############################################################# image = cv.cvtColor(image, cv.COLOR_BGR2RGB) results = face_mesh.process(image) # 描画 ################################################################ if results.multi_face_landmarks is not None: for face_landmarks in results.multi_face_landmarks: # 描画 debug_image = draw_landmarks(debug_image, face_landmarks) cv.putText(debug_image, 'FACE DETICTION', (0, 50), cv.FONT_HERSHEY_TRIPLEX, 1, (255, 255, 255), 1, cv.LINE_AA) else: cv.putText(debug_image, 'FACE LOST', (0, 50), cv.FONT_HERSHEY_TRIPLEX, 1, (0, 0, 255), 1, cv.LINE_AA) # キー処理(ESC:終了) ################################################# key = cv.waitKey(1) if key == 27: # ESC break # 画面反映 ############################################################# cv.imshow('MediaPipe Face Mesh Demo', debug_image) cap.release() cv.destroyAllWindows() def draw_landmarks(image, landmarks): image_width, image_height = image.shape[1], image.shape[0] landmark_point = [] for index, landmark in enumerate(landmarks.landmark): if landmark.visibility < 0 or landmark.presence < 0: continue landmark_x = min(int(landmark.x * image_width), image_width - 1) landmark_y = min(int(landmark.y * image_height), image_height - 1) landmark_point.append((landmark_x, landmark_y)) cv.circle(image, (landmark_x, landmark_y), 1, (0, 255, 0), 1) ################################################### #顔の向きの推定 ################################################### #推定に使用するランドマークの選定 ####################### image_points = np.array([ tuple(landmark_point[1]),#鼻頭 tuple(landmark_point[107]), tuple(landmark_point[336]), tuple(landmark_point[133]), tuple(landmark_point[362]), tuple(landmark_point[102]), tuple(landmark_point[331]), tuple(landmark_point[61]), tuple(landmark_point[291]), tuple(landmark_point[17]), tuple(landmark_point[152]), ],dtype='double') if len(landmark_point) > 0: (cv.FONT_HERSHEY_PLAIN, 0.7, (0, 0, 255), 2) model_points = np.array([ (0.0,0.0,0.0), # 30 (-30.0,-125.0,-30.0), # 21 (30.0,-125.0,-30.0), # 22 (-60.0,-70.0,-60.0), # 39 (60.0,-70.0,-60.0), # 42 (-40.0,40.0,-50.0), # 31 (40.0,40.0,-50.0), # 35 (-70.0,130.0,-100.0), # 48 (70.0,130.0,-100.0), # 54 (0.0,158.0,-10.0), # 57 (0.0,250.0,-50.0) # 8 ]) size = image.shape focal_length = size[1] center = (size[1] // 2, size[0] // 2) #顔の中心座標 #カメラ行列コード camera_matrix = np.array([ [focal_length, 0, center[0]], [0, focal_length, center[1]], [0, 0, 1] ], dtype='double') #歪み係数ベクトルコード dist_coeffs = np.zeros((4, 1)) (success, rotation_vector, translation_vector) = cv.solvePnP(model_points, image_points, camera_matrix, dist_coeffs, flags=cv.SOLVEPNP_ITERATIVE) #回転行列とヤコビアン (rotation_matrix, jacobian) = cv.Rodrigues(rotation_vector) mat = np.hstack((rotation_matrix, translation_vector)) #yaw,pitch,rollの取り出し(原点からみた3軸に対する角度) (_, _, _, _, _, _, eulerAngles) = cv.decomposeProjectionMatrix(mat) yaw = eulerAngles[1] pitch = eulerAngles[0] roll = eulerAngles[2] #yaw,roll,pitchを保存 YAW.append(yaw) ROLL.append(roll) PITCH.append(pitch) #ランドマークの座標をMARKに追加 MARK.append(landmark_point[10]) #ランドマーク 取得時間 dt = time.time() #スタートからの経過時間 dt = dt - st #時間をTIMEに追加 TIME.append(dt) print("yaw",int(yaw),"pitch",int(pitch),"roll",int(roll))#頭部姿勢データの取り出し cv.putText(image, 'yaw : ' + str(int(yaw))+"deg", (0, 250), cv.FONT_HERSHEY_TRIPLEX, 1, (0, 225, 255), 1, cv.LINE_AA) cv.putText(image, 'pitch : ' + str(int(pitch))+"deg", (0, 300), cv.FONT_HERSHEY_TRIPLEX, 1, (0,225, 255), 1, cv.LINE_AA) cv.putText(image, 'roll : ' + str(int(roll))+"deg", (0, 350), cv.FONT_HERSHEY_TRIPLEX, 1, (0, 225, 255),1 ,cv.LINE_AA ) (nose_end_point2D, _) = cv.projectPoints(np.array([(0.0, 0.0, 500.0)]), rotation_vector,\ translation_vector, camera_matrix, dist_coeffs) #計算に使用した点のプロット/顔方向のベクトルの表示 for p in image_points: cv.drawMarker(image, (int(p[0]), int(p[1])), (0, 0, 255), markerSize=8,markerType=cv.MARKER_DIAMOND, thickness=1) p1 = (int(image_points[0][0]), int(image_points[0][1])) p2 = (int(nose_end_point2D[0][0][0]), int(nose_end_point2D[0][0][1])) cv.arrowedLine(image, p1, p2, (0, 225, 225), 2) #瞬きの検知############################################################ #左目 left_eye = ( landmark_point[362], landmark_point[385], landmark_point[387], landmark_point[263], landmark_point[373], landmark_point[380]) left_eye_ear = calc_eye(left_eye) #右目 right_eye = (landmark_point[33], landmark_point[160], landmark_point[158], landmark_point[133], landmark_point[153], landmark_point[144] ) right_eye_ear = calc_eye(right_eye) if left_eye_ear < 0.24 and right_eye_ear < 0.24: if left_eye_ear > 0.2 and right_eye_ear > 0.2: Blink.append(1) dt2 = time.time() #スタートからの経過時間 dt2 = dt2 - st #時間をTIMEに追加 Blink_TIME.append(dt2) cv.putText(image, 'closeEye!!', (0, 100), cv.FONT_HERSHEY_TRIPLEX, 1, (0, 0, 255), 1, cv.LINE_AA) else: cv.putText(image, 'openEye!!', (0, 100), cv.FONT_HERSHEY_TRIPLEX, 1, (225, 225, 255), 1, cv.LINE_AA) print(right_eye_ear) return image if __name__ == '__main__': main()
回答1件
あなたの回答
tips
プレビュー