#髪の毛だけ、目だけ自動で分離したい
髪の毛や唇など、狙ったパーツを細かく分離できれば、そこだけ色を変えてメイクアプリがつくれる。
ユーザーに輪郭をなぞってもらってカットするのでは、めんどうくさい。
自動でやりたい。
しかも、髪の毛などはなるべく細かいところまで丁寧に切り取りたい。
しかし、自動で、細かく切り取ることは可能なのだろうか。
#ねらったパーツをとれるフレームワークはなかなかない
機械学習にセマンティックセグメンテーションという分野がある。
画像をオブジェクトごとに細かく分離できる技術だ。
技術向上により、かなり細かく切り取れるようになってきている。
iOSにもセグメンテーションをつかえるフレームワークがある。
しかし、AVFoundationでPortraitMatteがとれるが、全身、スキンや歯は取得できても、髪の毛や目だけは分離できない。
しかも、カメラの撮影時に設定する必要がある。
Visionや機械学習モデルのPersonSegmentationも全身だ。
#機械学習であっという間に解決
さてそこで役に立つのが、face-parsing という顔の部品ごとのマスクを学習したセマンティックセグメンテーションモデルである。
オリジナル・プロジェクト:
これが髪の毛や左右の目、唇や帽子まで、細かく分離してくれる上、精度もなかなか良い。
これをiOSで使えば、メイクアプリも作れそうだ。
ということでiOSように変換したモデルを用意した。
精度も変わらない。
具体的手順
iOS用に変換ずみのface-parsingモデルはCoreML-Modelsからダウンロードできる。
あとは、Visionでリクエストすればモデルを実行できる。
do {
let model = try faceParsing(configuration: MLModelConfiguration()).model
let vnCoreMLModel = try VNCoreMLModel(for: model)
let request = VNCoreMLRequest(model: vnCoreMLModel)
guard let ciImage = CIImage(image: uiImage) else {fatalError("Image failed.")}
let handler = VNImageRequestHandler(ciImage: ciImage, options: [:])
try handler.perform([coreMLRequest])
guard let result = coreMLRequest.results?.first as? VNCoreMLFeatureValueObservation else {fatalError("Inference failed.")}
} catch let error {
print(error)
}
結果は、パーツに対応する数値のピクセルだ。
ピクセルが512*512あって、たとえば、1は肌、2は左眉というる風に対応する数値になっている。
この数値の配列を白黒の画像に直してつかう。
モデルの実行から画像変換、メイクまで、サンプルコードはこちら。
取得したマスク画像で合成すれば、ヘアカラーやメイクができる。
🐣
フリーランスエンジニアです。
お仕事のご相談こちらまで
rockyshikoku@gmail.com
Core MLやARKitを使ったアプリを作っています。
機械学習/AR関連の情報を発信しています。