GIMPで顔認識(Python経由でOpenCV)

こちらの記事の続き。

ほとんど、GIMPとOpenCVのサンプルコードのひきうつしですが。。。

あらかじめ、CVtypes.pyに、前述の記事のパッチをあてておく必要があります。

OpenCVサンプルコード内 haarcascadesフォルダを中身のxmlファイルごとGIMPプラグインフォルダにコピー。
以下のコードをcvfacedetect.pyという名前で、GIMPプラグインフォルダ(GIMP24\lib\gimp\2.0\plug-ins)に保存、GIMP次回起動時に認識される、はずです。

認識されていれば、GIMPで画像を開き、フィルターの中にOpenCVという階層が出来ます。その中のcvfacedetectを選ぶと、フィルタを実行します。

人物の顔が丸く選択されたら成功です。
実行自体は短いのですが、起動までに「か~な~り~」時間がかかるので実用性には欠けます。あくまでOpenCVを使ってみるサンプルコード、ということで。

卒業アルバムなど集合写真でやってみると、意外に引っかからない人が居たりして楽しかったり(汗


#!/usr/bin/env python
from gimpfu import *
from CVtypes  import cv

import sys
import os
import time

gettext.install("gimp20-python", gimp.locale_directory, unicode=True)

# Global Variables
cascade = None
pth=os.path.abspath(os.path.dirname(sys.argv[0]))
cascade_name = pth+"./haarcascades/haarcascade_frontalface_alt.xml"

def cvfacedetect(img,layer):
    img.undo_group_start()
    cascade = cv.LoadHaarClassifierCascade( cascade_name, cv.Size(1,1) )
    if not cascade : return
    storage = cv.CreateMemStorage(0)
    gimp.progress_init("cvFaceDetect")
    gimp.progress_update(0.5) #percnt 0 ->1.0
    min_size = cv.Size(20,20)
    image_scale = 1.3
    haar_scale = 1.2
    min_neighbors = 2
    haar_flags = 0
    ox,oy=layer.offsets
    x0,y0=0,0
    w,h=x1,y1=layer.width,layer.height
    p0=layer.get_pixel_rgn(x0,y0,w,h)
    src_img = cv.CreateImage( cv.Size( w,h), 8, p0.bpp )
    sstr=cv.ImageAsString(src_img)
    stp=src_img.contents.widthStep
    stp2=w*p0.bpp
    idx0=0
    for y in xrange(y0,y1):
        idx1=idx0+stp2
        sstr[idx0:idx1]=p0[x0:x1,y:y+1]
        idx0+=stp  
    if p0.bpp==1 :
        gray = src_img
    else :
        gray = cv.CreateImage( cv.Size(w,h), 8, 1 )   
        cv.CvtColor( src_img, gray, [cv.RGB2GRAY,cv.RGBA2GRAY][p0.bpp-3] )
    small_img = cv.CreateImage( cv.Size( int(round (w/image_scale)),
			 int(round (h/image_scale))), 8, 1 )
    cv.Resize( gray, small_img, cv.INTER_LINEAR )
    cv.EqualizeHist( small_img, small_img )
    cv.ClearMemStorage( storage )
    faces=[]
    if( cascade ):
        faces = cv.HaarDetectObjects( small_img, cascade, storage,
                        haar_scale, min_neighbors, haar_flags, min_size )
    if faces:
        for r in faces:
            sx0 =  ox+int(r.x*image_scale);   sy0=oy+int(r.y*image_scale)
            sw =  int(r.width*image_scale); sh=int(r.height*image_scale)
            gimp.pdb.gimp_ellipse_select(img,sx0,sy0,sw,sh,CHANNEL_OP_ADD,True,False,0)    
    if gray!=src_img:
        cv.ReleaseImage(gray)
    cv.ReleaseImage(small_img)
    cv.ReleaseImage(src_img)
    layer.visible=True
    gimp.displays_flush()
    img.undo_group_end()
register(
    "python-fu-cvfacedetect",
    N_("CvFaceDetect OpenCV"),
    "Select Faces .",
    "BoxHeadRoom",
    "BoxHeadroom.com",
    "2007",
    N_("_CvFaceDetect..."),
    "RGB*, GRAY*",
    [
        (PF_IMAGE, "image",       "Input image", None),
        (PF_DRAWABLE, "drawable", "Input drawable", None),
    ],
    [],
    cvfacedetect,
    
    menu="<image>/Filters/OpenCV",
    domain=("gimp20-python", gimp.locale_directory)
    )

main()

コメントを残す

メールアドレスが公開されることはありません。