前提・実現したいこと
ビデオキャプチャから顔のランドマークを検出し、
検出した場合は「face]と表示
そうでなければ[lost]と表示させたい
発生している問題・エラーメッセージ
ランドマークが指定範囲外に外れた場合で条件分岐しているが ランドマークの入力が入らないだけでうまく条件分岐できない。 そこで、ランドマークの検出の有無で条件分岐できるようにしたい
該当のソースコード
python
1import dlib 2from imutils import face_utils 3import cv2 4import numpy as np 5import pandas as pd 6import time 7 8import matplotlib.pyplot as plt 9%matplotlib inline 10 11Land = [] 12TIME = [] 13ut = time.time() 14 15 16# -------------------------------- 17# 1.顔ランドマーク検出の前準備 18# -------------------------------- 19# 顔検出ツールの呼び出し 20face_detector = dlib.get_frontal_face_detector() 21predictor_path = 'shape_predictor_68_face_landmarks.dat' 22face_predictor = dlib.shape_predictor(predictor_path) 23 24 25# -------------------------------- 26# 3.カメラ画像の取得 27# -------------------------------- 28# カメラの指定(適切な引数を渡す) 29cap = cv2.VideoCapture(1) 30 31# カメラ画像の表示 ('q'入力で終了) 32while(True): 33 ret, img = cap.read() 34 35 img_gry = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 36 37 # 顔のランドマーク検出(2.の関数呼び出し) 38 faces = face_detector(img_gry, 1) 39 40 # 顔のランドマーク検出 41 for face in faces: 42 landmark = face_predictor(img_gry, face) 43 landmark = face_utils.shape_to_np(landmark) 44 Land.append(landmark[28]) 45 46 ue = time.time() 47 TIME.append(ue-ut)
----------------------------------------------------------------------------- ここからがうまくいかないポイント ----------------------------------------------------------------------------- #ランドマーク描画 for (x, y) in landmark: right_eye_x, right_eye_y = landmark[36][0],landmark[36][1] cv2.circle(img, (x, y), 3, (0, 0, 255), -1) if 1000 >= right_eye_x >= 0 : cv2.putText(img, 'Movie', (0, 50), cv2.FONT_HERSHEY_PLAIN, 7, (255, 255, 255), 5, cv2.LINE_AA) else: cv2.putText(img, 'LOST', (0, 100), cv2.FONT_HERSHEY_PLAIN, 7, (255, 255, 255), 5, cv2.LINE_AA) cv2.namedWindow('img', cv2.WINDOW_NORMAL) #cv2.putText(img, 'Movie', (0, 50), cv2.FONT_HERSHEY_PLAIN, 5, (255, 255, 255), 2, cv2.LINE_AA) # 結果の表示 resized_img = cv2.resize(img,(500, 300)) cv2.imshow('img', resized_img) # 'q'が入力されるまでループ if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()
解決方法
①len(faces)の出力確認
②len(faces)の出力によって条件分岐するように作成
# -------------------------------- # 3.カメラ画像の取得 # -------------------------------- # カメラの指定(適切な引数を渡す) cap = cv2.VideoCapture(1) # カメラ画像の表示 ('q'入力で終了) while(True): ret, img = cap.read() img_gry = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 顔のランドマーク検出(2.の関数呼び出し) faces = face_detector(img_gry, 1) #ーーーーーーーーーーーーーーーーーーーー# #len(faces)の出力が0,1であることを確認 # #ーーーーーーーーーーーーーーーーーーーー# print(len(faces)) #ーーーーーーーーーーーーーーーーーーーーーーーーーー# #len(faces)が1であればMOVIE,0であればLOSTと表示# #ーーーーーーーーーーーーーーーーーーーー ーーーーー# if len(faces) == 1: cv2.putText(img, 'MOVIE', (0, 100), cv2.FONT_HERSHEY_PLAIN, 7, (255, 255, 255), 5, cv2.LINE_AA) else: cv2.putText(img, 'LOST', (0, 50), cv2.FONT_HERSHEY_PLAIN, 7, (255, 255, 255), 5, cv2.LINE_AA) # 顔のランドマーク検出 for face in faces: landmark = face_predictor(img_gry, face) landmark = face_utils.shape_to_np(landmark) Land.append(landmark[28]) ue = time.time() TIME.append(ue-ut) # ランドマーク描画 for (x, y) in landmark: right_eye_x, right_eye_y = landmark[36][0],landmark[36][1] cv2.circle(img, (x, y), 3, (0, 0, 255), -1) cv2.namedWindow('img', cv2.WINDOW_NORMAL) # 結果の表示 resized_img = cv2.resize(img,(500, 300)) cv2.imshow('img', resized_img) # 'q'が入力されるまでループ if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/05/05 22:15