この記事は OpenCV Advent Calender 20日目の記事です。
こんにちは。Webバックエンドエンジニアと、フォントクリエイターを名乗っております @irimo と申します。
今回は OpenCV アドカレに初参加させていただき、緊張しております。
昨日は @ki_230 さんの記事でした。
OpenCV.jsを利用したリアルタイムビデオ処理!
なんでもできそうですが、ネタが浮かばない... でも、いろいろアイデア出ししてみたいところです。
TL;DR
今回は「顔検出」と「ちいかわ」がテーマです。
顔写真をちいかわちゃんにするのがゴールになります。
このマツコ・デラックスさん(参照元)の写真を顔検出させて加工すると、
こうなりました。
最近はOpenCV以外の顔検出のライブラリが充実しており、OpenCV縛りだとこれが限界になります。
顔検出ではあまり OpenCV はメジャーじゃないのかと思います。
商用ツールの顔認識は、自前で実装(修正)してるのだとわかりました。
口の検出は残念ながらありません。そのため、今回は適当に貼りました。
(別のライブラリでリベンジしたいところ)
やった
- 輪郭、目 の検出
- 画像の回転・合成
- 回転率を合わせる
- 貼り付け位置が不自然にならないように調節
宿題
- 輪郭画像の透明部分が変になっている
- 口の検出がないとはいえ、場所が適当になっている
顔検出について
OpenCVには「顔検出」の機能があります。
人間を読み込ませると、顔のパーツを四角形で返してくれるものです。
今回は一人が映っている写真の「顔の輪郭」「目」の検出をしました。
目の検出の教師データは「右目」「左目」と分かれているバージョンもありますが、厳密でないみたいなので「目」の教師データを使用しました。
この「目」の検出は、一人の写真なのになぜか目が3つ以上検知されます。判定のつきやすいものから検出していますので、前2つの四角を取得すれば、二つの目が検出できます。
ちなみに、「右目」は2つ、「左目」も2つ検出されます。こちらも一番前の四角を適用すると良いです。
class square_reco:
img_gray = ""
xml_path = ""
xml_base_dir = "/usr/local/lib/python3.7/site-packages/cv2/data/"
def __init__(self, img_gray, xml_filename):
self.img_gray = img_gray
self.xml_path = self.xml_base_dir + xml_filename
def reco(self):
classifier = cv2.CascadeClassifier(self.xml_path)
targets = classifier.detectMultiScale(self.img_gray)
return targets
class face_reco(square_reco):
xml_face = "haarcascade_frontalface_default.xml"
def __init__(self, img_gray):
print("face_reco init")
super().__init__(img_gray, self.xml_face)
class eyes_reco(square_reco):
filename = "haarcascade_eye.xml"
def __init__(self, img_gray):
print("eyes_reco init")
super().__init__(img_gray, self.filename)
law_path = "./images/idol/001.jpg"
img_origin = cv2.imread(law_path)
img_gray = cv2.cvtColor(img_origin, cv2.COLOR_BGR2GRAY)
face = face_reco(img_gray)
# targets は、二次元の配列(4要素 x, y, width, height)* 検出された分
targets = face.reco()
回転について
こちらを参考に、透明部分のある画像を回転させました。
パーツの拡大率について
元パーツの比率度外視で、顔検出で検出された四角にそのままパーツをあてはめると、パーツの形が変わり、縮小率も違って不自然な画像になります。
ですので、一番縮小率の低い「輪郭パーツ」の縮小率に全てのパーツの縮小率を合わせました。
縮小率を考えていない画像と、考えた画像を比べました。不自然さが少しとれたと思います。回転させていない状態です。
顔と目の比率が違う
おわりに
もっと「あなたに似たちいかわ」になるようにしたかったですが、顔のこだわりが少ないという性格ですので、あまり凝れませんでした。申し訳ありません。
改めて顔の仕事してる方々に敬意を示します。ですが、軽く挑戦できて面白かったです。
今回のリポジトリはこちらです。
明日の担当は @Kazuhito さんです!