見出し画像

盛り殺し~makeUpBreaker~ 盛ってる写真を見分けるAI

はじめに

いまや、化粧をするのと同じくらい、撮影した写真を”盛る”ことが身近になっています。この”盛り写真(自撮り加工)”を判別するためのAIを作成してみました。

今回の作成したAIに、顔の部分を切り出すプログラムを加え、簡単に盛り画像を判定するAIを最後に付けています。※環境のセットアップまでは実施する必要があります。

本AIを搭載したAndroid アプリを作成しました。
良ければ見てみてください。



準備(環境のセットアップ)

画像1

構築環境
Windows 10 Enterprise
Anaconda
Python 3.7.9
CUDA 10.0
TensorFlow 1.14.0

Anaconda

以下URLよりダウンロードし、インストールを実施
https://www.anaconda.com/products/individual

Anaconda Navigatorを起動し、「Environments」⇒「Create」を選択し、
仮想環境を立ち上げる。

立ち上げ実施時のパッケージは「Python 3.7」を選択する。

以下のコマンド実行はすべてAnacondaで作成した環境上から実施します。
Anaconda → Environment → 作成した環境 → ”▶”より「Open Terminal」を選択することでターミナルが起動できます。

CUDA 10.0

以下URLよりダウンロードし、インストールを実施
https://developer.nvidia.com/cuda-toolkit-archive

Tensorflow 1.14

以下を参考にインストール作業を実施
https://www.kkaneko.jp/tools/win/tensorflow114.html

1.Windows で,コマンドプロンプトを管理者として実行.


2.使用する Python のバージョンの確認

python --version

3.pip の更新

python -m pip install -U pip setuptools

4.パッケージのアンインストール操作

python -m pip uninstall -y tensorflow tensorflow-cpu tensorflow-gpu tensorflow_datasets tensorflow-hub keras

5.TensorFlow 1.14 のインストール

python -m pip install -U tensorflow-gpu==1.14 tensorflow_datasets

ここまでで事前準備は完了となります。



教師データの準備

画像2

まずは学習のためのデータをダウンロードし、準備する工程について説明を行います。今回は女性の顔写真加工アプリを通したものかを判定しています。そのため、女性の顔写真を集めることにしました。

Google-image-downloader

Google画像検索の結果をもとに、画像を一括ダウンロードすることができるシステム。本システムを用いて教師データを一括でダウンロードします。

Google Image Downloaderを以下URLを参考にインストールします。
https://qiita.com/taedookim/items/63759e79426514c8a729

1.任意のディレクトリを作成

mkdir bulkImage

2.ディレクトリに移動

cd bulkImage

3.google_image_download のインストール

git clone https://github.com/hardikvasa/google-images-download.git

4.ディレクトリ移動

cd gid-joeclinton/google_images_download

※ディレクトリは変更されている可能性がありますので”dir”コマンドなどで確認してください。

5.google_image_download の実行

python google_images_download.py -k "SNOW加工前後"

※ -k 以降がGoogle画像検索における検索文字になります。適当な文字列を入力し、ダウンロードを行います。
※Google側の制限により、1つのキーワードでダウンロードできる上限は100枚になっております。

今回構築した際は、加工前後が明らかとなるように、加工前・加工後をどちらも掲載した画像をもとに学習を実施しています。

OpenCVを用いた顔画像抽出・水増し

顔写真抽出

先に抽出した画像から顔部分の抽出を実施。本顔抽出にはOpenCVが提供しているカスケード型分類期を用いて実施します。

以下URLを参考にシステム構築
https://newtechnologylifestyle.net/opencv_face_trimingu/

import cv2
import glob

#カスケード型分類器に使用する分類器のデータ(xmlファイル)を読み込み
HAAR_FILE = "<保存場所>haarcascade_frontalface_default.xml"
cascade = cv2.CascadeClassifier(HAAR_FILE)

def facePos(fileName):
   image_picture = fileName    
   #グレースケールに変換する
   img_g = cv2.imread(image_picture,0)
   
   #カスケード型分類器を使用して画像ファイルから顔部分を検出する
   face = cascade.detectMultiScale(img_g)

   return face


def faceCut(fileName, face):
   image_picture = fileName
   img = cv2.imread(image_picture)

   tmpW = 0
   tmpH = 0
   tmpLength = 0
   num = 0
   #顔部分を切り取る
   for x,y,w,h in face:
       face_cut = img[y:y+h, x:x+w]
       cv2.imwrite(fileName[: <フォルダ名長> ] + str(num) + 'Cut' + fileName[<フォルダ名長>:], face_cut)
       num = num + 1

def main():
   for fileName in glob.iglob('<フォルダ名>*.jpg', recursive=True):
       face = 0
       face = facePos(fileName)
       if len(face) <= 0:
           print('顔がありませんでした')
       else:
           faceCut(fileName, face)
       

if __name__ == "__main__":
   main()

抽出した顔画像を、加工前・加工後のものに仕分け、それぞれを別のフォルダに配置します。
※今回は、加工前を”before”、加工後を”after”として保存しました。

顔写真の水増し

また、データ量が少ない場合は、画像を反転・回転させたデータを水増しとして用いることも有用です。あまりに使いすぎると過学習のもととなってしまいますが、自撮り画像は左右の向きが異なるなどはよくあるケースなので、有効に働くことが期待できるいので実施しました。
 ※加工前・加工後各100枚の元データを、左右反転(2倍) × 左右90度回転(3倍)により、6倍のデータ水増しを行っています。

▼参考URL
https://note.nkmk.me/python-opencv-numpy-rotate-flip/




Tensorflowを用いた学習

画像3

事前準備

Tensorflowのソースから以下をダウンロード
https://github.com/tensorflow/hub/blob/master/examples/image_retraining/retrain.py

さらに、ダウンロードしたファイルがあるディレクトリに、"photos"と名付けたフォルダを作成します。そして、photosフォルダ配下に、先に作成した顔写真が入っている"before", "after"のフォルダをその配下に配置します。

※学習したデータを用いて判定をすると、リーケージが発生するため、事前にいくつか判定用の画像を分けておくとよいです。(学習には時間がかかりますので、その間に新規にとってきてもよいです。)

フォルダ配置イメージ ※tensorflowのソースをダウンロードしたフォルダ

retrain.py
photos
 L photos
  L before
   L 001.jpg
   L 002.jpg
   L 003.jpg
   ・・・
  L before
   L 001.jpg
   L 002.jpg
   L 003.jpg
   ・・・

学習の開始

retrain.pyがあるフォルダまで移動し、retrain.pyを起動することで学習が始まります。その際に、--image_dirにて画像が保存されている場所を指定します。

python retrain.py --image_dir photos

学習は全部で4,000ステップあるので20-30分程度待ちます。環境によっては時間がかなり変わる可能性があります。


結果確認準備

学習結果の確認

学習結果ファイルが、/tmp に作成されています。

Windowsの場合は、C:/tmpです。他のドライブにて実行した場合が、他ドライブ上に/tmpフォルダがトップに生成されています。

output_graph.pb と output_labels.txt が生成されていることを確認しておきます。

解析プログラムのダウンロード

label_image.pyをgithubからダウンロードし、適切なディレクトリに配置します。
https://raw.githubusercontent.com/tensorflow/tensorflow/master/tensorflow/examples/label_image/label_image.py

解析の実行

先ほど学習されたデータを、--graphと--labelに指定し、分類したい画像を--imageに指定して、label_image.pyを実行します。
 ※この例では、tmp配下に解析したい画像を入れています

python label_image.py \
--graph=C:/tmp/output_graph.pb --labels=C:/tmp/output_labels.txt \
--input_layer=Placeholder \
--output_layer=final_result \
--image=C:/tmp/test.jpg




AI解析結果

画像4

画像は適当にGoogleで検索したものを用いています。
また、学習には未使用の画像であることを確認しています。
※著作権フリーのものはあまりないのでWebには上げずらいのですが、手元ではかなりいい感じであることを確認しています。

盛り前と判定された画像

画像6

before 0.7520894 after 0.24791065

https://pxhere.com/ja/photo/1623753

盛り後と判定された画像

画像6

after 0.96619016 before 0.033809826

https://www.pxfuel.com/ja/free-photo-ozoyz

Final test accuracy = 95.5%

※蛇足ですが、100枚の元画像ですと、 Final test accuracy = 93.2% となり、回転・反転画像で水増しすることで、約2%精度が上がりました。



まとめ

Tensorflowを用いて、加工アプリにて、加工している写真と加工していない写真を判定することができることを確認しました。
学習元データは100枚程度であったとしても、反転などの水増し法を駆使することで十分な結果が得られることを確認しました。



おまけ

以下はおまけとなります。

今回作成したAIをZIPで固めて保存しております。
.zipファイルを解凍することでAIが利用できます。
※冒頭にも記載しましたが事前準備は必要となります。

簡単な実行ファイルにまとめており、適当な写真の中にある、顔の部分を自動で取得し、解析を実施するようにしております。

もしよろしければ、ご利用下さい。


ここから先は

784字 / 2ファイル

¥ 500

この記事が気に入ったらサポートをしてみませんか?