こちらの記事の続き。
ほとんど、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()