質問: BeautyPlusというアプリがあって、その中で動画に美肌にみえるフィルターをかける機能があります。 これの実現方法を思案しているのですが、なにか良いアイデアがあればご教授頂きたいです。 より具体的に説明すると、肌認識、もしくは顔認識を駆使して、カメラに写っている人間の顔の皮膚の部分のみ、シミやシワを目立たなくしたいです。この工程には、1肌認識、顔認識をする。2シミやシワを目立たなくする。があると思います。ここで、1で抽出した範囲に対して、GLSLで2の処理を行う方法を知りたいです。よろしくお願いします。 また、当方画像処理にあまり詳しくなく、ブラーをかけたり、輝度を上げるくらいしか、美肌にする方法を思いつきません。この他にどんな加工をしたらシミやシワを目立たなくすることができるかも教えて頂けると助かります。 GPUImage(もしくはGLSL)を使った肌認識の方法もご存知の方がいたら教えて頂けると助かります。 ※現在は、GPUImageを使ってバイラテラルブラーフィルターと輝度を上げたものを美肌フィルターとして使っているのですが、バイラテラルブラーを使ってBeautyPlusと同じレベルでのシミの除去を行おうとすると、絵がのっぺりして、解像度が低くなったような映像になってしまいます。なので、他になにか特別な手法があるのかな?と考えています。
回答: App Storeの画像を見ただけですが、シミの除去は「バイラテラルフィルター」だと思われます。また赤ら顔を抑えるための色調補正もかかっていますが、色空間やトーンカーブのパラメーターは分かりません。 追記・バイラテラルフィルターの仕組み ================== コメントに関連してバイラテラルフィルター他のぼかし処理ついて記しておきます。 まず一番単純なぼかしフィルターとしては**3×3平滑化**が挙げられます。これは * 画像のすべての画素の色をその画素の周囲9ピクセルの平均値で置き換える。 というアルゴリズムです。ここでの「平均値」は「1/9を掛けた値の合計」と言い換えられますが、この「1/9」をピクセルごとに別の値に変えたり、あるいは範囲を5×5や7×7に拡張すると別のフィルターが作れるわけです。このような処理を「畳み込み」と呼び、使用する係数を「カーネル」と称しますが、その中で一番メジャーなものが**ガウシアンフィルター**で、 * 距離の2乗の指数に反比例する重み(ガウス分布)を係数とする、 ※`e^(-r^2/2σ^2)` つまり**中心に近い画素を重視する平滑化処理**です。 前置きが長くなりましたが、バイラテラルフィルターは * 「距離」と「中心画素との輝度差」のそれぞれでガウシアンの係数を計算し、それを掛け合わせて重みとする 処理になります。なので調整できるパラメーターとしては距離、輝度のσとなります。またバイラテラルフィルターは複数回連続で適用すると効果が強まるので、回数がパラメーターとなっている場合もあります。 というわけでGPUImageの`distanceNormalizationFactor`は上の式の`σ`だと思われ、遠くの画素をどれだけ重視するかを示しています。しかしGPUImageの実装では、「平均の計算対象となっている画素が9個しかない」ように思われます。この実装で微調整ができるのかは疑わしい、というのがコメントの意図です。 追記・アルファブレンド =========== 上記のとおり、バイラテラルフィルターは「似た色の画素を重視して平均をとる」処理です。なので適用すると陰影が全体的に弱まり、輪郭周辺で急に色が変わるという傾向になります。 なので顎周辺でバイラテラルフィルター適用結果と元の画像を滑らかに切り替える、つまり適用画像に透明度(アルファ)を設定して元画像に重ねてやれば違和感が抑えられるかもしれません。やってみないと何とも言えませんが。