PythonのOpenCVを使った目の検出で鼻を囲まないようにする方法

PythonのOpenCVを使って目を検出すると、目以外の鼻の穴も目と検出されてしまいます。そして、検出した場所にcv2.rectangleをすると鼻も四角で囲んでしまうので、鼻を囲まないようにして目だけ囲む方法を動画を使って紹介します。

読み込んで表示した動画はPexelsの動画を使わさせてもらいました。

検出するのに使ったもと動画鼻を囲んでしまっている動画鼻を囲まないようにして目だけ囲んでいる動画をYouTubeで投稿しています。

顔と目を検出するときに使うhaarcascadeファイルのダウンロード方法は↓こちらで紹介しています。
OpenCVを使った顔と目の検出方法 Python

目次

・もと動画

・顔と目を検出するプログラム

・鼻を囲んでしまっている様子

・鼻を囲まないようにするプログラム

・目だけを囲んでいる様子


もと動画

顔と目を検出するのに使ったもと動画になります。

動画の読み込みと表示はこちら↓の投稿で紹介したプログラムを使いました。

Python OpenCVを使った動画の読み込みと表示

顔と目を検出するプログラム

動画の読み込みとdef文で作成した自作関数の呼び出しはこちら→Pythonで動画に写る人を検出する方法の投稿で説明しているので、3~17行目の顔と目を検出して、四角で囲むプログラムの説明をします。

3、4行目は顔と目を検出するためのファイルを読み込んでいます。

6~17行目の自作関数detectfaceは、まず7行目で顔を検出するために読み込んだ画像をグレイ画像にしています。そして、8行目でグレイ画像からface_cascade.detectMultiScale(img_gray)をして顔を検出しています。
※顔と目を検出するときはグレイにした画像を使います。グレイ画像にして、色を少なくすることで処理を行いやすくしています。

10~14行目は検出した顔の座標の数、for文で繰り返す処理をし、検出した顔を四角で囲んでいます。そして、13行目でグレイ画像にした画像から検出した顔を切り取り、そこから14行目のeye_cascade.detectMultiScale(face_gray)をして目を検出しています。

16、17行目は検出した目の座標の数、for文で繰り返す処理をし、検出した目を四角で囲んでいます

最後に28行目のcv2.imshow(‘movie’, frame)で四角で囲んだ画像を表示しています。この処理を20行目で動画から画像にした枚数を1フレームずつ繰り返すことで動画のように表示しています。

上の顔と目を検出するプログラムを実行したのがこちら↓になります。

鼻を囲んでしまっている様子

目以外の鼻も四角で囲んで四角でしまっています。

鼻を囲まないようにするプログラム

鼻を囲まないようにする方法は、顔の上半分の位置で目を検出したら、その部分だけ四角で囲むようにしています。

顔と目を検出するプログラム」から変更したのが16~19行目だけなので、その部分のプログラムを説明します。

16行目はface.shape[0]//2で顔の高さの値を//2で半分にした値を求めています。そして、求めた値を変数half_faceに入れています。

face.shape[0]について、face.shapeはprint(face.shape)で表示すると このプログラムの場合は(262, 262, 3)このような表示になりす。これは(高さ、幅、色の数)を表しています。よって、face.shape[0][0]で高さの値だけを取り出しています。

17~19行目は検出した目の座標の数、for文で繰り返す処理をし、half_face(顔の高さの値を半分にした値)以下の値で目を検出した場合、その場所を四角で囲んでいます。これで、鼻の穴を目と検出したとしても、四角で囲まないようにしています。

画像の高さの座標は上から下にいくに連れて値が大きくなっているので、目の高さの座標は鼻よりも小さいです
だから、if ey <= half_face(eyは目の高さの座標)このような条件にしています。

上の鼻を囲まないようにするプログラムを実行したのがこちら↓になります。

目だけを囲んでいる様子