顔画像認識(Win)

顔画像認識とは?

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

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

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

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

Back To Top

OpenCVライブラリの利用

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

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

下図はOpenCVに用意されているパターンデータリスト。
後述のOpenCV for Processingと同時に以下の場所にインストールされる。
C:\Users\ユーザ名\Documents\Processing\libraries\opencv_processing\library\cascade-files

Back To Top

ライブラリの活用

特定の機能に関するライブラリや複数の機能を持つライブラリセット等多くのものが存在する。ライブラリは後からインストールするものだけでなく、もともとIDE(ここではProcessing)に含まれているものも存在する。

プログラムを行うことは、これらの様々な機能を持つライブラリをどのように動作させるかを記述することでもある。

ライブラリ自体もプログラムであり、世の中に存在しないライブラリは自分でプログラムするか、存在するライブラリを改造して作成する。

Back To Top

プログラムの動作環境

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

OS: Windows 10 64bit (18363.900)
Processing:バージョン3.5.4
OpenCVライブラリ:OpenCV for Processing 0.5.4 ※インストール必要
ビデオライブラリ:Video 1.0.1 ※インストール必要

Back To Top

ライブラリ(OpenCV、Video)のインストール方法

①OpenCVライブラリのインストール

スケッチメニュー>ライブラリをインポート>ライブラリを追加 をクリックする。

Contribution Managerウィンドウが表示される。

検索窓から「opencv」を検索する。OpenCV for Processingがリストアップされるので、名前をクリックして下図のようにハイライトにする。

ウィンドウ下方に下図が表示されるので、右側のInstallボタンを押す。

下図のようにダウンロードとインストールが自動的に進行する。

インストール後の表示は自動更新されないので、下図のようにライブラリ名をクリックすることでインストール済であることが確認できる。

 

②Videoライブラリのインストール

①と同様に検索窓でvideoを検索する。複数がリストアップされるので「Video | GSStreamer-based video library for Processing」を選択して、右下のInstallボタンをクリックしてインストールを行う。下図はインストール後の画面。

Back To Top

カメラアプリによる撮影(静止画、動画)

OpenCVの実験用に以下の2つのデータを準備する。

  • 自分を撮影した静止画データ(jpg)
  • 動きのある動画データ(mp4)

 

①カメラアプリを起動

「カメラ」で検索起動する。

Windowsに標準搭載されているカメラアプリではスマートフォンアプリのように静止画/動画を撮影することができる。

設定ウィンドウで撮影画質を変更することができる。
撮影した静止画の画像サイズや動画フォーマットはプログラムで読み込む際に必要な情報。

 

②静止画撮影

右側のボタンを押して撮影する。

撮影したJPEGデータは、PC > ピクチャ > カメラロールに保存される。
下図のように半角英数文字でファイル名を変更する。自身の名前でかまわない。
このファイル名はProcessingから指定する必要があるので覚えておくこと。

JPGデータを右クリックしてプロパティウィンドウの詳細タブを確認する。
イメージの大きさに1280 x 720が画像サイズ。Processingで指定する必要があるので覚えておく。

 

③動画撮影

右のボタンをムービーアイコンに切り替えてから動作撮影を行う。解析用として、自身が静止した状態、動いている状態を流れの中で撮影する。

撮影したMP4データは、静止画と同様にPC > ピクチャ > カメラロールに保存される。
下図右のように半角英数文字でファイル名を変更する。自身の名前でかまわない。
このファイル名はProcessingから指定する必要があるので覚えておくこと。

MP4データを右クリックしてプロパティウィンドウの詳細タブを確認する。
ビデオのフレーム幅1280、フレーム高さ720が動作のサイズ。Processingで指定する必要があるので覚えておく。

Back To Top

サンプルスケッチ

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

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

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

Back To Top

BrightnessContrast(明度)

①サンプルスケッチを開く

サンプルウィンドウ > Contributed Libraries > OpenCV for Processing > BrightnessContrast をダブルクリックする。

 

②Runして実行

本サンプルでは、マウスを左右に動かすことで画像の明るさを変更できる。Photoshopでもおなじみの明るさの変更をプログラムでリアルタイムに実行することができる。OpenCVでは画像認識だけでなく、このような基本的な画像処理に関するライブラリも多数含まれる。

 

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

サンプルのスケッチフォルダーを開く。
スケッチメニュー > スケッチフォルダーを開くをクリックする。

PC > ピクチャ > カメラロールの自分の写真データ(下図左)をスケッチフォルダー(下図右)にコピーする。※他の実験でも利用するため

コード7行目の「test.jpg」を自分の写真データのファイル名に変更する。

コード8行目のウィンドウサイズを事前に確認している写真データの画像サイズに変更する。

Runして実行。マウスを左右に動かして動作確認。

コード14行目を以下のように変更して、どのような挙動になるのか実験しながら、変数や数値の意味を理解する。

  • mouseX→mouseY、width→height
  • -255と255の数値を変更

Back To Top

FindEdges(輪郭抽出)

①サンプルスケッチを開く

サンプルウィンドウ > Contributed Libraries > OpenCV for Processing > FindEdges をダブルクリックする。

 

②Runして実行

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

 

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

サンプルのスケッチフォルダーを開く。
スケッチメニュー > スケッチフォルダーを開くをクリックする。

PC > ピクチャ > カメラロールの自分の写真データ(下図左)をスケッチフォルダー(下図右)にコピーする。※他の実験でも利用するため

②コード7行目の「test.jpg」を自分の写真データのファイル名に変更する。

③コード8行目のウィンドウサイズを事前に確認している写真データの画像サイズに変更する。

Runして実行。

Back To Top

FaceDetection(顔画像認識)

①サンプルスケッチを開く

サンプルウィンドウ > Contributed Libraries > OpenCV for Processing > FaceDetection をダブルクリックする。

 

②Runして実行

静止画なのでわかりにくいが、ソース画像から解析処理により顔と判定された部分に緑の矩形線が表示されている。

ソースコードを解説する。

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);//矩形描画
  }
}

 

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

サンプルのスケッチフォルダーを開く。
スケッチメニュー > スケッチフォルダーを開くをクリックする。

PC > ピクチャ > カメラロールの自分の写真データ(下図左)をスケッチフォルダーのdataフォルダ(下図右)にコピーする。※これまでと違いdataフォルダなので注意

コード8行目の「test.jpg」を自分のファイル名に変更する。

コード9行目のウィンドウサイズを画像サイズに合わせる。

Runして実行。

 

④解析部位の変更

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

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

他にも様々な部位のパターンデータが用意されている。下記以外はウェブ上に公開されているリファレンス参照。

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

Back To Top

BackgroundSubstraction(背景差分)

①サンプルスケッチを開く

サンプルウィンドウ > Contributed Libraries > OpenCV for Processing > BackgroundSubstractionをダブルクリックする。

 

②Runして実行

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

 

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

サンプルのスケッチフォルダーを開く。
スケッチメニュー > スケッチフォルダーを開くをクリックする。

PC > ピクチャ > カメラロールの自分の動画MP4データ(下図左)をスケッチフォルダーのdataフォルダ(下図右)にコピーする。

コード8行目のウィンドウサイズコードを動画のサイズに合わせる

コード9行目の「street.mov」を自分の動画データ名に変更する。

コード10行目の解析サイズを動画のサイズに合わせる。

Runして実行。単位時間あたりの動きが激しいときに赤線が増える(動き判定が増加)ことがわかる。

 

※Runがうまくいかない時の対処方法

メディアのファイル名に間違いないのにエラーが起こる場合がある。下図のようにグレーのウィンドウだけ表示される。このような時は一度停止した後にRunを再度行うことで実行できる場合がある。原因不明だが、サイズの大きい映像ファイルの読み込み処理に失敗していることが予想される。

上記方法でも解決しない場合は、ソースコード(20~22行)を以下のように修正することで回避できる。元ネタはココ(https://stackoverflow.com/questions/37662245/processing-opencv-and-ipcapture-library-error-width0-and-height0-cannot-be)。ビデオデータが完全に読み込み完了するまで解析処理しないことで回避していると思われる。

import gab.opencv.*;
import processing.video.*;

Movie video;
OpenCV opencv;

void setup() {
  size(720, 480);
  video = new Movie(this, "street.mov");
  opencv = new OpenCV(this, 720, 480);
  
  opencv.startBackgroundSubtraction(5, 3, 0.5);
  
  video.loop();
  video.play();
}

void draw() {
  image(video, 0, 0);  
  if (video.width > 0 && video.height > 0) {
      opencv.loadImage(video);
  }

  opencv.updateBackground();
  
  opencv.dilate();
  opencv.erode();

  noFill();
  stroke(255, 0, 0);
  strokeWeight(3);
  for (Contour contour : opencv.findContours()) {
    contour.draw();
  }
}

void movieEvent(Movie m) {
  m.read();
}

Back To Top

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

①サンプルスケッチを開く

サンプルウィンドウ > Contributed Libraries > OpenCV for Processing > 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部分を変更する。

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

Back To Top

LiveCamTest改(顔の置き換え実験)

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();
}

スケッチの保存。

ファイル名は任意だが、ここではsketch_facechangeとする。

スケッチフォルダーを開く。

dataフォルダーを作成する。

 

②置換画像の準備

下画像を保存してスケッチフォルダのdataフォルダ内に入れる。

ブラウザ上からドラック&ドロップすることが可能。

 

③Runして実験

複数人でも可能。

Back To Top

オリジナル置換画像での実験

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

AI画伯で作成した画像や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の事例

High-Resolution Neural Face Swapping for Visual Effects, Eurographics Symposium on Rendering (2020)

顔画像ではないが、距離カメラ(2カメラで視差による処理)ではなく、一般的なウェブカメラでも人物動作をここまで解析できるようになっている。
ソースと使い方が公開されているのでやる気になれば利用することが可能。
https://qiita.com/yukihiko_a/items/43d09db5628334789fab?fbclid=IwAR3SgTMZleh47KNcwqNltZPs7h854AbeHNx0WCjrqKiFNjeu5jztU9sAaqk

こちらは、一つのカメラで見えない部分も含めた全周を予測している

Back To Top