顔画像認識

顔画像認識とは?

顔画像認識とはコンピュータビジョンにおけるパターン認識の一種で、顔画像解析、Face Detection、Face Trackingなどとも呼ばれている。カメラ画像(2次元や3次元)を解析することでコンピュータに人間の目のような認識力をもたせることを目的としたコンピュータビジョンに関わる技術である。人工知能を利用した画像認識技術も登場しているがここでは扱わない。

セキュリティシステムやコミュニケーションロボットのユーザ認識だけでなく、デジタルサイネージや感情認識を取り入れたアプリケーションなど、応用範囲が広がっている。

顔認証ゲートによる入国審査も実用化されている。

パスポートをかざすだけで入国審査…「顔認証ゲート」公開 11日から成田空港で本格運用」(産経新聞ニュース,2018.6.8)

Back To Top

OpenCVの利用

本演習ではOpenCVとを利用する。Open CVはコンピュータビジジョン(CV)に関するライブラリセットであり、顔画像認識以外にも様々な画像に関する機能が実装されている。

OpenCVの顔画像認識機能はパターン認識であり、もとになるパターンデータが存在する。顔の要素を抽出したデータがライブラリの中に用意されており、このデータとカメラ画像のマッチングを行うことで顔と認識させる。今回はhaarcascade_frontalface_alt.xmlというデータを用いるが、他にも目や鼻、上半身や下半身といったように、人間の体の様々な部分を認識させることもできる。

下図はOpenCVに用意されているパターンデータリスト。

Back To Top

プログラムの動作環境

本講義ノートで紹介するプログラム(スケッチ)の動作確認は以下の環境で行っている。

OS: macOS Sierra(10.12.6)
Processing:バージョン3.3.5
OpenCVライブラリ:OpenCV for Processing
ビデオライブラリ:Video

OpenCVとVideoライブラリの追加は、スケッチメニュー>ライブラリをインポート>ライブラリを追加から行うことができる。

Back To Top

サンプルスケッチ

ファイルメニュー>サンプルをクリックする。

Contributed Libraries>OpenCV for Processingを開くとたくさんのサンプルが用意されている。
ダブルクリックしてスケッチを開き、Runすることで実験できる。

ただし、これらのサンプルはOpenCVに関する知識を必要とするので、OpenCVによる画像処理入門(講談社)などで学習する必要がある。

Back To Top

Quick Time Playerによる撮影、写真データ保存

※OpenCV実験用に以下の2つを準備する。
・自分が写った静止画データ(jpg)
・動きのある動画データ(mov)

 

①QuickTimePlaeyrを起動

アプリケーションフォルダのQuickTimePlayer.app(下図アイコン)をクリック。

ファイル選択ダイヤログが表示されるがキャンセルする。

 

②動画撮影

ファイルメニューから新規ムービー収録を選択。※写真撮影機能はない

iMacのカメラ映像が表示される。
録画ボタンを押して録画スタート、ストップボタンを押して録画停止。

 

③動画ファイルの保存

ファイルメニュー>書き出し>720p(最大解像度 1280 × 720)もしくは480p( 最大解像度640 × 480)を選択。

ファイル名を入力して保存する。(movファイルのみ)

※接続されたカメラ(アスペクト比)によって解像度は異なるので、書き出されたファイル情報を確認する。例えばiMac(16:9)で480pの場合は640×360となる。

 

④静止画の保存

QuickTimePlayer自体には静止画保存機能はない。

まず、QuickTimePlayerで保存したい位置にスライダーをドラッグして合わせる。

編集メニュー>コピーをクリック(Cmd+C)

アプリケーションフォルダからプレビュー.app(下図アイコン)を起動する。

ファイル選択ダイヤログが表示されるがキャンセルする。

ファイルメニュー>クリップボードから新規作成

ファイルメニュー>保存

ファイル名の入力、フォーマットの選択(ここではjpg)をして保存する。

デフォルトではPNGだが、JPEGヤPDF等も保存できる。

Back To Top

BrightnessContrast(明度)

OpenCVでは画像認識だけでなく、画像処理に関するライブラリも多数含まれる。

本サンプルでは、マウスを左右に動かすことで画像の明るさを変更できる。Photoshopでもおなじみの明るさの変更をプログラムでリアルタイムに実行することができる。

 

<実験> 自分の撮影写真データで実験

①スケッチフォルダーに自分の写真データ(英数ファイル名)を入れる。
②コード7行目の「test.jpg」を自分の写真データのファイル名に変更する。
③コード8行目のウィンドウサイズを写真データの画像サイズに変更する。(Cmd+Iで確認)
④コード14行目のmouseXをmouseYに変更(widthをheightに)したり、-255と255の数値を変更してどのような挙動になるのか確認する。

Back To Top

FindEdges(輪郭抽出)

画像の輪郭抽出を行う。

輪郭抽出には様々なアルゴリズムが存在しており、本サンプルでは、Canny法(右上)、Scharr勾配検出フィルタ(左下)、Sobel勾配検出フィルタ(右下)の比較を行っている。画像認識の前処理として行う場合もある。技術的な説明はココ

 

<実験> 自分の撮影写真データで実験

①スケッチフォルダーに自分の写真データ(英数ファイル名)を入れる。
②コード7行目の「test.jpg」を自分の写真データのファイル名に変更する。
③コード8行目のウィンドウサイズを写真データの画像サイズに変更する。(Cmd+Iで確認)

Back To Top

FaceDetection(顔画像認識)

本演習の本題となる顔画像認識のスケッチ。

以下にソースコードを解説する。

import gab.opencv.*; //OpenCVライブラリの読み込み
import java.awt.Rectangle;

OpenCV opencv; 
Rectangle[] faces;

void setup() {
  opencv = new OpenCV(this, "test.jpg"); //解析対象画像の読み込み
  size(1080, 720); //ウィンドウサイズの指定

  opencv.loadCascade(OpenCV.CASCADE_FRONTALFACE); //パターンデータの読み込み
  faces = opencv.detect(); //顔画像認識処理
}

void draw() {
  image(opencv.getInput(), 0, 0); //入力画像の描画

  noFill(); //塗りなし
  stroke(0, 255, 0); //線の色
  strokeWeight(3); //線の太さ
  for (int i = 0; i < faces.length; i++) { //複数の顔画像にも対応
    rect(faces[i].x, faces[i].y, faces[i].width, faces[i].height);//矩形描画
  }
}

 

<実験> 自分の撮影写真データで実験

①スケッチフォルダーの中のdataフォルダーに写真データ(英数ファイル名)を入れる。
②コード8行目の「test.jpg」を自分のファイル名に変更する。
③コード9行目のウィンドウサイズを画像サイズに合わせる。(画像サイズはCmd+Iで確認)

④以下のように、解析部位を変更してみる。

ここでパターンデータを変更してみよう。
11行目のCASCADE_FRONTALFACE部分を変更する。

opencv.loadCascade(OpenCV.CASCADE_FRONTALFACE);

CASCADE_FRONTALFACE:顔
CASCADE_EYE:目
CASCADE_MOUTH:口
CASCADE_NOSE:鼻

これ以外の設定は、ウェブ上に公開されているリファレンス参照。

下図はCASCADE_MOUTHの例。単純なパターン認識では誤認識が多い。実用ベースのシステムではAIや複数のアルゴリズムを用いて精度の高い解析を行っている。一方、単純なパターン認識でも、背景を一色にする等、撮影条件を限定して利用する方法もある。

Back To Top

BackgroundSubstraction(背景差分)

背景差分では、背景画像と異なる部分の領域を判定する。事前に背景画像データを準備する方法もあるが、サンプル事例では背景データを前フレームから逐次生成しているので背景画像データは必要ない。逆にこの方法では、物体の移動は検知できるが、静止している場合は検知できない。背景差分にも複数の手法が存在するので、目的に適した手法を選択する必要がある。

 

<実験> 自分で撮影した動画データで実験

①スケッチフォルダーに撮影した動画データ(英語ファイル名)を追加する。
②コード9行目の「test.mov」を自分の動画データ名に変更する。
③コード8行目のウィンドウサイズと10行目の解析サイズを動画サイズに合わせる。動画サイズはファイル情報(Cmd+I、右クリックで情報を見る)で確認。

Back To Top

LiveCamTest(顔画像認識ビデオ版)

Runして実験してみよう。

FaceDetectionスケッチと異なり、カメラからの入力によって動的な顔画像認識を行う。

以下にソースコードを解説する。

import gab.opencv.*; //OpenCVライブラリの読み込み
import processing.video.*; //Videoライブラリの読み込み
import java.awt.*;

Capture video;
OpenCV opencv;

void setup() {
  size(640, 480);
  video = new Capture(this, 640/2, 480/2); //Videoの初期化 1/2しているのは処理を軽くするため
  opencv = new OpenCV(this, 640/2, 480/2); //OpenCVの初期化
  opencv.loadCascade(OpenCV.CASCADE_FRONTALFACE); //パターンデータの読み込み

  video.start(); //Videoの開始
}

void draw() {
  scale(2); //初期化の時点で1/2サイズになっているので2倍に拡大
  opencv.loadImage(video); //VideoをOpenCVに入力

  image(video, 0, 0 ); //Videoの描画

  noFill(); //塗りなし
  stroke(0, 255, 0); //線の色
  strokeWeight(3); //線の太さ
  Rectangle[] faces = opencv.detect(); //顔画像認識処理
  println(faces.length); //顔の数デバッグ

  for (int i = 0; i < faces.length; i++) { //複数の顔の対応
    println(faces[i].x + "," + faces[i].y); //顔の座標デバッグ
    rect(faces[i].x, faces[i].y, faces[i].width, faces[i].height); //矩形描画
  }
}

void captureEvent(Capture c) { //Videoキャプチャー処理
  c.read();
}

FaceDetectionと同様にパターンデータを変更してみよう。
12行目のCASCADE_FRONTALFACE部分を変更する。

opencv.loadCascade(OpenCV.CASCADE_FRONTALFACE);

CASCADE_FRONTALFACE:顔
CASCADE_EYE:目
CASCADE_MOUTH:口
CASCADE_NOSE:鼻
CASCADE_UPPERBODY:上半身
CASCADE_LOWERBODY:下半身
CASCADE_FULLBODY:全身
CASCADE_CLOCK:時計

Back To Top

顔の置き換え実験

LiveCamTestのスケッチを改造して、顔を画像で置き換えるプログラムを作成した。

 

①スケッチの準備

以下のコードを空のスケッチにコピー&ペーストして、スケッチを保存する。

import gab.opencv.*; //OpenCVライブラリの読み込み
import processing.video.*; //Videoライブラリの読み込み
import java.awt.*;

Capture video;
OpenCV opencv;
PImage img;
float size = 1.5; //置換画像サイズ

void setup() {
  size(640, 480);
  video = new Capture(this, 640/2, 480/2); //Videoの初期化 1/2しているのは処理を軽くするため
  opencv = new OpenCV(this, 640/2, 480/2); //OpenCVの初期化
  opencv.loadCascade(OpenCV.CASCADE_FRONTALFACE); //パターンデータの読み込み
  img = loadImage("face.png"); //置換画像の指定 スケッチフォルダ内のdataフォルダ内に配置
  video.start(); //Videoの開始
}

void draw() {
  imageMode (CORNER);
  scale(2); //初期化の時点で1/2サイズになっているので2倍に拡大
  opencv.loadImage(video); //VideoをOpenCVに入力
  image(video, 0, 0 ); //Videoの描画
  Rectangle[] faces = opencv.detect(); //顔画像認識処理

  //置換画像の表示
  imageMode (CENTER);      
  for (int i=0; i < faces.length; i++) { //顔の数だけ繰り返す
      image(img, faces[i].x + faces[i].width /2, faces[i].y + faces[i].height /2, faces[i].width * size, faces[i].width * size * img.height/img.width );
  }
}

void captureEvent(Capture c) { //Videoキャプチャー処理
  c.read();
}

 

②置換画像の準備

スケッチメニュー>スケッチフォルダを開く。
下画像を保存してスケッチフォルダのdataフォルダ内に入れる。Macであればブラウザ上からドラック&ドロップすることが可能。

※dataフォルダの名前を間違えないように

 

③実験

スケッチをRunして、顔が画像に置き換わっているか試してみよう。

Back To Top

置換画像の制作

前述のface.pngをPhotoshopで編集して、オリジナルの置換画像を試してみよう!

Pixabayのような著作権フリーの画像を利用してもいい。

Back To Top

デジタルサイネージへの応用事例

しくみデザインでは、この顔画像認識を使って様々なデジタルサイネージを提案している。

Back To Top

より高度な顔画像認識技術

FaceTrackerは、Jason Saragih氏の研究成果であるDeformable Model Fitting by Regularized Landmark Mean-Shiftを実装したもので、顔の特徴点を追跡する技術。Kyle McDonald氏がopenFrameworksのアドオンofxFaceTrackerとして公開している。

Face Substitution from Kyle McDonald on Vimeo.

下映像は最新の表情解析技術と画像処理技術を組み合わせたもの。このような技術は映画やアニメーションキャラクターの表情コントロールに使われていたが、より細かい動きが再現可能になったことで、一見すると本物だと感じる域に達しつつある。高精細な表現がリアルタイム動作可能になれば、VR技術と融合することで映画『サロゲート』のような世界が登場するだろう。

Makeup simulatorの事例

Back To Top