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