Symfoware

Symfowareについての考察blog

Python + OpenCV + pillowで笑い男を顔に上書き

顔認識といえば笑い男だろうということで、
顔として認識できた箇所に笑い男を上書きしてみます。

笑い男の透過画像はこちらからお借りしました。
笑い男マーク




顔認識



おさらいとして、顔として認識できた箇所に矩形を描くサンプルはこちら。


  1. # -*- coding:utf-8 -*-
  2. import numpy
  3. import cv2
  4. cascade_path = '/usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_alt_tree.xml'
  5. image_path = 'sample.jpg'
  6. color = (255, 0, 0) #青
  7. #ファイル読み込み
  8. image = cv2.imread(image_path)
  9. #グレースケール変換
  10. image_gray = cv2.cvtColor(image, cv2.cv.CV_BGR2GRAY)
  11. #カスケード分類器の特徴量を取得する
  12. cascade = cv2.CascadeClassifier(cascade_path)
  13. #物体認識(顔認識)の実行
  14. facerect = cascade.detectMultiScale(
  15.                 image_gray, scaleFactor=1.1, minNeighbors=1, minSize=(1, 1))
  16. if len(facerect) > 0:
  17.     #検出した顔を囲む矩形の作成
  18.     for rect in facerect:
  19.         cv2.rectangle(image, tuple(rect[0:2]),tuple(rect[0:2]+rect[2:4]), color, thickness=2)
  20.     #認識結果の保存
  21.     cv2.imwrite("detected.jpg", image)






認識前と認識後の画像はこうなります。

514_01.jpg

514_02.jpg




別画像の合成



OpenCVだけではちょっとめんどくさそうだったので
顔の抽出:OpenCV
画像の上書き:Pillow
と、用途によりライブラルを分けることにしました。

ここを参考にします。
FreeBSD 10 + Python + pillowで透過pngの合成


ちょっとハマったのが、読み込んだ画像をRGBAモードに変更していないと


ValueError: image has wrong mode



というエラーが発生して、合成に失敗します。
元がjpegだからかな?


雑ですが、こんな感じのコードになりました。


  1. # -*- coding:utf-8 -*-
  2. import numpy
  3. import cv2
  4. cascade_path = '/usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_alt_tree.xml'
  5. image_path = 'sample.jpg'
  6. color = (255, 0, 0) #青
  7. #ファイル読み込み
  8. image = cv2.imread(image_path)
  9. #グレースケール変換
  10. image_gray = cv2.cvtColor(image, cv2.cv.CV_BGR2GRAY)
  11. #カスケード分類器の特徴量を取得する
  12. cascade = cv2.CascadeClassifier(cascade_path)
  13. #物体認識(顔認識)の実行
  14. facerect = cascade.detectMultiScale(
  15.                 image_gray, scaleFactor=1.1, minNeighbors=1, minSize=(1, 1))
  16. """
  17. if len(facerect) > 0:
  18.     #検出した顔を囲む矩形の作成
  19.     for rect in facerect:
  20.         cv2.rectangle(image, tuple(rect[0:2]),tuple(rect[0:2]+rect[2:4]), color, thickness=2)
  21.     #認識結果の保存
  22.     cv2.imwrite("detected.jpg", image)
  23. """
  24. # OpenCVでの結果を元に、PILで笑い男画像を上書き
  25. from PIL import Image
  26. layer1 = Image.open( image_path )
  27. layer2 = Image.open( 'smile.png' )
  28. # 合成のため、RGBAモードに変更
  29. layer1 = layer1.convert('RGBA')
  30. # 同じ大きさの透過キャンパスを用意
  31. c = Image.new('RGBA', layer1.size, (255, 255,255, 0))
  32. # rect[0]:x, rect[1]:y, rect[2]:width, rect[3]:height
  33. for rect in facerect:
  34.     # 上書きする笑い男画像をリサイズ
  35.     resize_img = layer2.resize((rect[2], rect[3]))
  36.     # 用意したキャンパスに上書き
  37.     c.paste(resize_img, (rect[0],rect[1]), resize_img)
  38. # オリジナルとキャンパスを合成して保存
  39. result = Image.alpha_composite(layer1, c)
  40. result.save('result.jpg')




狙い通りです。

514_03.jpg

関連記事

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2014/11/23(日) 18:50:50|
  2. Python
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集
<<Redmine 選択された項目に連動して、他の項目を変更(Custom JS plugin) | ホーム | OpenCV 使用可能なCascadeClassifierの種類と効果>>

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://symfoware.blog68.fc2.com/tb.php/1557-b339c06c
この記事にトラックバックする(FC2ブログユーザー)