ポスタリゼーションとCannyのエッジ検出アルゴリズムの組み合わせでイラストから下絵の作成に挑戦
いらすとやの画像を借りて試してみました。
1.Gaussianオペレータを適用することによりエッジをぼかす
2.Sobelオペレータを適用し画像を微分する
3.微分画像を繊細化する
4.繊細化した結果の連結性を上げるために、2つの閾値を用いた2値化を行う
と複雑な手順が必要ですが、opencvなら関数一個で処理できます。
image = cv2.Canny(image,0,0,3)
Cannyアルゴリズムをそのままイラストに適応するとうまく行きませんでした。 これはイラストやのイラストは肌や副部分にフェルト生地のような質感を感じさせる着色がなされているためだと思います。 また、イラストやの画像は問題ありませんが、ネットで拾ってきた野良画像は結構ノイズが乗っていることが多いのでそちらの影響も受けてしまいます。
例えば私のアイコン画像でそのまま試すと以下のようになりました。
このフェルトのような質感をポスタリゼーションで均一化すればうまく行くのではないかと思い試してみました。
結果、posterlizationとdenoiseをCannyアルゴリズムの前に実施するとうまく行きました。
# denoiseのためのフォーマット変換 img_src = cv2.cvtColor(img_src,cv2.COLOR_GRAY2BGR) # denoise img_src = cv2.fastNlMeansDenoisingColored(img_src,None,10,10,7,21) # ルックアップテーブルの生成 look_up_table = np.ones((256, 1), dtype = 'uint8' ) * 0 for i in range(256): if i <= 0: look_up_table[i][0] = 0 elif i < 32: look_up_table[i][0] = 32 elif i < 64: look_up_table[i][0] = 64 elif i < 96: look_up_table[i][0] = 96 elif i < 128: look_up_table[i][0] = 128 elif i < 160: look_up_table[i][0] = 160 elif i < 192: look_up_table[i][0] = 192 elif i < 224: look_up_table[i][0] = 224 else: look_up_table[i][0] = 255 #postrization実行 img_src = cv2.LUT(img_src, look_up_table) #Canny img_dst = cv2.Canny(img_src,0,0,3) #bit反転 img_dst = cv2.bitwise_not(img_dst)
ですがこのプログラムは私のアイコン画像に対してはうまく動きませんでした。
なぜでしょうか。理由はポスタリゼーションで腕と背景の色が同一化されてしまったためです。 ポスタリゼーションの度合いを変えることで、こちらの画像もうまくエッジ検出できました。
ですがこのエッジ検出にはまだまだ課題があります。飛び出し坊やくんの
- 手と顔
- 手とズボン
の境界が検出できていません。この件に関しましてはまた後日描きたいと思います。
ちなみに今回のエントリのようなエッジ検出は画像の性質を見てうまく動くようなポスタリゼーションを実施する必要があります。