※これはこの記事のスピンオフ的なものです。
はじめに
昨今の情報が行き交う世界、人のプライバシーというものが重要視されている世の中になっているのはいうまでもありません。こんな時代だからこそ、きちんとプライバシーを守ってくれるものが必要だ…
そう思った私は、こんなことを考えました。
写真に目線を付けれるようにすれば良いのでは…?
ということで、作ってみました。
(正直、何も考えずに作りました。)
目線を入れるために
目線を入れるためには、まずは目と顔を認識する必要があることに私は気づいてしまいました。そこで、OpenCVのデータ内の顔を認識するライブラリと目を認識するライブラリを使うことにしました。
詳しいことはよくわかりませんが、なんだか顔を認識するコードだけは降ってきたので、それをちょちょっといじって目を認識するプログラムは完成しました。
(降ってきたライブラリはここから御覧ください。)
それを使って作成した写真がこちら。顔を四角、目を丸でプロットしています。
完全に子供が写真に写った孔という孔に赤ペンで大穴開けてるみたいな写真になりました。
ただ、この写真には問題があり、鼻や口、さらには二重顎についても目として認識していることが分かります。これではプライバシーを守ることができない…!
そこで、私は顔の特徴を考えました。おそらくですが、よほど脳みそが大きくなければ目は顔の半分よりも上にあるはず。なので、顔の四角内でもさらに半分よりも上にある点のみを目として認識させることにしました。
ここまですることによって、顔と目の関係性は書くことができたので、目線の四角のサイズを横幅は顔の四角に準拠、縦は目として認識した全ての場所の中での一番上の部分と一番下の部分を採用するようにしました。
プログラム
これで書いたプログラムが下のプログラムです。
import cv2
import matplotlib.pyplot as plt
image_name = input("File Name?")
src=cv2.imread(image_name)
image_gray=cv2.cvtColor(src,cv2.COLOR_BGR2GRAY) #グレイスケール化
color=(0,0,255) #かこむやつ(赤)
color_c=(255,0,0) #打つやつ(点,青)
cascade = cv2.CascadeClassifier("haarcascade_frontalface_alt2.xml") #学習データの取り込み
# eye_right = cv2.CascadeClassifier("haarcascade_righteye_2splits.xml")#右目データ
# eye_left = cv2.CascadeClassifier("haarcascade_lefteye_2splits.xml")#左目データ
eyecascade = cv2.CascadeClassifier("haarcascade_eye.xml")#目データ
#なんとかする呪文
facerect = cascade.detectMultiScale(image_gray, scaleFactor=1.1, minNeighbors=1, minSize=(50,50))
# reyerect = eye_right.detectMultiScale(image_gray, scaleFactor=1.1, minNeighbors=1, minSize=(30,30))
# leyerect = eye_left.detectMultiScale(image_gray, scaleFactor=1.1, minNeighbors=1, minSize=(30,30))
eyerect = eyecascade.detectMultiScale(image_gray, scaleFactor=1.1, minNeighbors=1, minSize=(30,30))
max_width = 0
upper_heigh = 99999
lower_heigh = 0
max_rect = [0,0,0,0]
if len(facerect) > 0:#横幅決めるやつ
for rect in facerect:
#print(rect[0:4])
if rect[2] > max_width:
max_width = rect[2] - rect[0]
max_rect = rect[0:4]
if len(eyerect) > 0:#縦幅決めるやつ
for rect in eyerect:
#print(rect[0:4])
if max_rect[0] < rect[0] and max_rect[0] + max_rect[2] > rect[0] + rect[2] and max_rect[1] < rect[1] and max_rect[1] + max_rect[3] /2 > rect[1] + rect[3]/2:
if upper_heigh >rect[1]:
upper_heigh = rect[1]
elif lower_heigh < rect[1] + rect[3]:
lower_heigh = rect[1] + rect[3]
rect[0:4] = [max_rect[0],upper_heigh,max_rect[2],lower_heigh - upper_heigh]#目線入れちゃうやつ
cv2.rectangle(src,tuple(rect[0:2]),tuple(rect[0:2]+rect[2:4]),(0,0,0),thickness = -10)
print(rect[0:4])
cv2.imwrite(image_name+"_result_eye.jpg",src)#保存するやつ
cv2.destroyAllWindows() #メモリの開放的な感じ
なんか試行錯誤の跡があるが気にするな!
結果
ということで、先程の写真を処理するとこんな感じになりました。
いい感じ!
最高!
ということで、なんと世界のプライバシーを守ることができました。
今回のプログラムの問題点
と、言っても実は1写真につきひとりのプライバシーしか守れない仕様になっているので、某有名ブロガーの方のブログ(しかも最初の正面写真)ぐらいでしか実用性は無いかと思います。悲しいね!
(ぶっちゃけ全部の顔に対して検証して、該当する目がなければ目線を入れずに次の顔って感じでできるような気もしますが…)
あと、正答率は私の確認した感じだと70%前後ぐらいでした。そこの精度に関しても改良の余地があるかも知れない…
というか、OpenCV使わずに別のライブラリを使えばいけそうだなーとか思いますが…
ということで、また気が向いたら大人数のプライバシーを守るぞ!
(最後までおふざけについていただいてありがとうございました。)
※補足:今回の画像に関しては全てぱくたそさんから拝借した画像を使用しています。