質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
dlib

dlibは、機械学習のC++の画像処理ライブラリの一つ。性能の高い顔の器官検出が簡単にでき、Pythonバインドもあります。オープンソースで無料で使用でき、機械学習以外の様々な機能も搭載されています。

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

2390閲覧

顔のlandmarkの取得の有無で条件分岐したい

shishi_maru440

総合スコア38

dlib

dlibは、機械学習のC++の画像処理ライブラリの一つ。性能の高い顔の器官検出が簡単にでき、Pythonバインドもあります。オープンソースで無料で使用でき、機械学習以外の様々な機能も搭載されています。

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/05/05 12:43

編集2021/05/05 23:02

前提・実現したいこと

ビデオキャプチャから顔のランドマークを検出し、
検出した場合は「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()

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

■うまくいかない原因
ちゃんと走らせていないので何とも言えませんが、これだとたぶんうまくいきません。
if right_eye_x == "":だと、right_eye_xが空文字(""に挟まれている部分=「文字がない」という文字)である必要があるためです。right_eye_xには数字が入るか、そもそも検出できない場合にはこの処理に流れてこない、だったと思います。詳細は以下参照ください。

■うまくいかない原因の詳細
for (x, y) in landmark:がうまくいくのはlandmarkが空っぽではない時、つまりNoneではない時のみです。Noneの時はそもそもForループに入らないためこれでは検出できません。

■対策
やるのであれば、forの前にリストがNoneでないことを確認するかlen(landmark)が0でないことを確認する必要があります。もしくは、顔すら検出されない場合landmarkにすら至りませんので、len(faces)が0でないことを確認する必要があります。


dlibは機械学習ベースで動いていますので、解像度にもよるかもしれませんが精度があまり高くなかったかと思います。それよりも深層学習ベースで動くmediapipeの方が検出率が高かったかと思います(しかも早いですし、dlibと比べて膨大な数の特徴点も採取可能です)。

投稿2021/05/05 13:08

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shishi_maru440

2021/05/05 22:15

アドバイスありがとうございます。 ①len(faces)の出力確認 >0,1でした ②len(faces)の出力によって条件分岐するように作成 ※上記対応で解決することができました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問