OpenCVで透明人間
先日,透明人間になって写真や動画を撮影できるAndroidアプリ「Invisible Camera」をリリースしました.OpenCV for Unityで作りました.せっかくなのでOpenCVで透明人間になる方法をメモとして残します.
— 敬也 (@takaya901) 2018年12月24日
なお,下記ソースコードは以下のようにusing staticでクラス名を省略しています.
using static OpenCVForUnity.Imgproc;
using static OpenCVForUnity.Core;
HSV画像に変換
GaussianBlur(webcamMat, blurred, new Size(7, 7), 0);
cvtColor(blurred, hsv, COLOR_RGBA2RGB);
cvtColor(hsv, hsv, COLOR_RGB2HSV);
webcamMatはカメラ映像をMatに変換したものです.OpenCV for Unityでは,WebCamTextureToMatHelperというクラスのGetMat()メソッドを使うとカメラ映像をRGBAのMatとして取得できます.別にRGBでも構いません.
後述のinRangeメソッドが使えるように,入力画像をHSVに変換します.ノイズ除去はお好みで.
COLOR_RGBA2RGBはないのでRGBを経由しています.
肌と髪の後ろにある背景を抽出する
//肌領域が255,それ以外が0のマスクを作成
//Hが0~180で循環しているので,両端とも取り出す
inRange(hsv, SKIN_LOWER1, SKIN_UPPER1, skinMask1);
inRange(hsv, SKIN_LOWER2, SKIN_UPPER2, skinMask2);
//髪(黒)領域が255,それ以外が0のマスクを作成
bitwise_or(skinMask1, skinMask2, skinMask1);
inRange(hsv, HAIR_LOWER, HAIR_UPPER, hairMask);
//肌と髪の領域が255のマスクを作成
bitwise_or(skinMask1, hairMask, skinAndHairMask);
//肌と髪の領域と同じ位置の背景を切り出す
bitwise_and(bg, bg, bgOnSkinAndHair, skinAndHairMask);
bgは背景(Background)のRGBA画像です.
inRangeメソッドで指定した範囲内の画素を255(白),範囲外の画素を0(黒)としたマスクを作成します.範囲は以下のように設定しました.
Scalar SKIN_LOWER1 = new Scalar( 0, 30, 88); //H(0~180)の左側
Scalar SKIN_UPPER1 = new Scalar( 25, 173, 255);
Scalar SKIN_LOWER2 = new Scalar(160, 30, 88); //H(0~180)の右側
Scalar SKIN_UPPER2 = new Scalar(180, 173, 255);
Scalar HAIR_LOWER = new Scalar( 0, 0, 0);
Scalar HAIR_UPPER = new Scalar(255, 150, 90);
bitwise_orは,ざっくり言うと2つのマスクの0でない領域を足し合わせます.
bitwise_andは,本来は2つの画像の両方で0でない領域だけを抽出するメソッドです.上記コードでは同じ画像のandを取っているのでそれだけだとbgがbgOnSkinAndHairにコピーされるだけですが,第4引数にマスク画像を指定することでマスク画像で0でない領域のみ抽出することができます.これはbitwise_orでも同じです.
skinAndHairMaskとbgOnSkinAndHairはそれぞれ以下のような画像になります(毎回撮り直しているので少しずれてますが気にしないでください).
カメラ映像から肌と髪以外の領域を抽出する
bitwise_not(skinAndHairMask, skinAndHairMask);
bitwise_and(webcamMat, webcamMat, withoutSkinAndHair, skinAndHairMask);
skinAndHairMaskを反転してからカメラ映像に適用することで,髪と肌以外の領域を抽出します.反転後のskinAndHairMaskとwithoutSkinAndHairは以下のようになります.
肌と神の領域を背景で置換
bitwise_or(withoutSkinAndHair, bgOnSkinAndHair, invisible);
withoutSkinAndHairの0領域にbgOnSkinAndHairの0でない領域がはめ込まれるイメージです.invisibleは以下のようになります.
Author And Source
この問題について(OpenCVで透明人間), 我々は、より多くの情報をここで見つけました https://qiita.com/takaya901/items/ad6b73e1c5168b794ab7著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .