主にプログラミングに関して。Python, .NET Framework(C#), JavaScript, その他いくらか。
記事にあるサンプルやコードは要検証。使用に際しては責任を負いかねます

スポンサーサイト

                
tags:
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

デスクトップ画像で顔認識

                
faces.jpg



OpenCVの顔認識を試してみて思った、面倒だ。いちいちプロンプトからカメラ指定したり、インプット画像を入力せねばならん。デスクトップに映ってるものを解析してそのまま表示すればいいじゃん。

というわけでデスクトップ画像で顔認識をするスクリプトを書いた。GTKやらcairoやらいくつか追加でモジュールを入れたけど、必要コンポーネントをバンドルしてしまえばこっちのが手軽で強力なデモにならんだろか(cascadeファイルを換えれば、顔以外にも様々な認識ができます)。

これを走らせるにはVisual C++のランタイムが必要。”Visual C++ 2008 再頒布可能パッケージ”でググってMSのサイトで落としてインストール。これを入れても動かなかったら


exeファイル化したもの→https://docs.google.com/leaf?id=0B4KnQ0osdBGyMjAwZGIwNDUtYmEzMS00OWY1LTliZmEtNTNjMzhhMzVmNjg2&hl=en

応用例→http://elicon.blog57.fc2.com/blog-entry-16.html





#-*- coding: utf-8 -*-

import math
import cairo
import gtk
from gtk import gdk
import gobject
import sys
import cv
from optparse import OptionParser
import pygtk
##from pyopencv import *
import time

global locate
global sigHandler
##global x
##x=[]
locate=[]

min_size = (20, 20)
image_scale = 2
haar_scale = 1.2
min_neighbors = 2
haar_flags = 0
nChannels=3
parser = OptionParser(usage = "usage: %prog [options] [filename|camera_index]")
parser.add_option("-c", "--cascade", action="store", dest="cascade", type="str", help="Haar cascade file, default %default", default = "../data/haarcascades/haarcascade_frontalface_alt.xml")
(options, args) = parser.parse_args()
##cascade = cv.Load(r'C:\OpenCV2.1\data\haarcascades\haarcascade_frontalface_alt.xml')
cascade = cv.Load('haarcascade.xml')
root = gtk.gdk.get_default_root_window()
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, gtk.gdk.screen_width(), gtk.gdk.screen_height())
ctx = cairo.Context(surface)
ctx.rectangle(0, 0, gtk.gdk.screen_width(), gtk.gdk.screen_height())
ctx.set_source_rgb(1, 0, 0)
ctx.fill()
surface.write_to_png('sample.png')

##cascadeName = "minhtri_frontalface.xml"
##cascade = CascadeClassifier()
##if not cascade.load( cascadeName ):
## print("ERROR: Could not load classifier cascade")
## print("Usage: facedetect [--cascade=\"\"]\n" \
## " [--nested-cascade[=\"nested_cascade_path\"]]\n" \
## " [--scale[=\n" \
## " [filename|camera_index]\n")
##scale=1.0
##colors = ( CV_RGB(0,0,255),
## CV_RGB(0,128,255),
## CV_RGB(0,255,255),
## CV_RGB(0,255,0),
## CV_RGB(255,128,0),
## CV_RGB(255,255,0),
## CV_RGB(255,0,0),
## CV_RGB(255,0,255))

def area2face(x,y,width,height):
t = time.time()
## pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, width, height)
## pixbuf.get_from_drawable(root, gtk.gdk.colormap_get_system(), x, y, 0, 0, width, height)
## mat=interfaces.cvCreateMatFromGtkPixbuf(pixbuf)
## cv_im = cv.CreateImageHeader((mat.cols,mat.rows),cv.IPL_DEPTH_8U,3)
## cv.SetData(cv_im, mat.ndarray.tostring(), 3*mat.cols)
pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, width, height)
pixbuf.get_from_drawable(gtk.gdk.get_default_root_window(), gtk.gdk.colormap_get_system(), x, y, 0, 0, width, height)
step=pixbuf.get_rowstride()
cv_im = cv.CreateImageHeader((width,height),cv.IPL_DEPTH_8U,3)
cv.SetData(cv_im, pixbuf.get_pixels(), step)
cv.CvtColor(cv_im,cv_im,cv.CV_BGR2RGB)
gray = cv.CreateImage((cv_im.width,cv_im.height), 8, 1)
small_img = cv.CreateImage((cv.Round(cv_im.width / 2),
cv.Round (cv_im.height / 2)), 8, 1)

cv.CvtColor(cv_im, gray, cv.CV_BGR2GRAY)

cv.Resize(gray, small_img, cv.CV_INTER_LINEAR)
cv.EqualizeHist(small_img, small_img)

##t = cv.GetTickCount()
faces = cv.HaarDetectObjects(small_img, cascade, cv.CreateMemStorage(0),
1.2,2, 0, (20, 20))
##t = cv.GetTickCount() - t
##print "detection time = %gms" % (t/(cv.GetTickFrequency()*1000.))
pos={}
k=0
if faces:
for ((x, y, w, h), n) in faces:
pt1 = (int(x * 2), int(y * 2))
pt2 = (int((x + w) * 2), int((y + h) * 2))
pos[k]=(pt1,pt2)
k += 1
else:
pos=False
processtime=time.time()-t
return pos,processtime

def detect(x,y,width,height):
i = 0
t = 0.0

gray = Mat()
pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, width, height)
pixbuf.get_from_drawable(root, gtk.gdk.colormap_get_system(), x, y, 0, 0, width, height)
mat=cvCreateMatFromGtkPixbuf(pixbuf)
smallImg = Mat( Size(round(mat.cols/scale), round(mat.rows/scale)), CV_8UC1 )
cvtColor( mat, gray, CV_RGB2GRAY )
resize( gray, smallImg, smallImg.size(), 0, 0, INTER_LINEAR )
equalizeHist( smallImg, smallImg )

t = getTickCount()
faces = cascade.detectMultiScale( smallImg,
1.1, 2, 0
#|CascadeClassifier.FIND_BIGGEST_OBJECT
#|CascadeClassifier.DO_ROUGH_SEARCH
|CascadeClassifier.SCALE_IMAGE
,
Size(30, 30) )
print faces
t = getTickCount() - t
print( "detection time = %lf ms\n" % (t/(getTickFrequency()*1000.)) )
pos={}
k=0
if faces:
for (x, y, w, h) in faces:
pt1 = (int(x * 2), int(y * 2))
pt2 = (int((x + w) * 2), int((y + h) * 2))
pos[k]=(pt1,pt2)
k += 1
else:
pos=False
processtime=time.time()-t
return pos,processtime


class ShapedWindow(gtk.Window):
def __init__(self):
gtk.Window.__init__(self)
self.hoge=0
self.set_position(gtk.WIN_POS_CENTER)
self.move(1, 0)
self.set_decorated(False)
self.set_keep_above(True)
self.set_events(self.get_events() | gtk.gdk.BUTTON_PRESS_MASK)
self.connect("button_press_event", self.first)

img = gtk.Image()
img.set_from_file('sample.png')
self.add(img)
self.set_resizable(False)

def first(self, win, allocation):
print self.hoge

#一回目のマウスクリックの座標取得
if self.hoge<1:
locate.append(gtk.gdk.display_get_default().get_pointer()[1:3])
print locate

#二回目のマウスクリックの座標取得、解析ウィンドウの位置決め
elif self.hoge==1:
locate.append(gtk.gdk.display_get_default().get_pointer()[1:3])
print locate
x,y=[locate[0][0],locate[1][0]],[locate[0][1],locate[1][1]]
x.sort()
y.sort()
self.x,self.y = x[0],y[0]
self.width,self.height=x[1]-x[0],y[1]-y[0]
if self.width%4:
self.width += (4-self.width%4)
print self.width
if (self.width<100) & (self.height<100):
print 'too small'
gtk.main_quit()
return False

timesum=0
for k in range(5):
faces,processtime=area2face(self.x,self.y, self.width,self.height)
timesum += processtime
ave=timesum/5+0.1
print 'ave %f' % ave
if ave<0.16:
cycle=166
elif 0.16 < ave < 0.33:
cycle=333
else:
cycle=ave*1000+500
print cycle

gobject.timeout_add(int(cycle), self.timeout)

elif self.hoge>1:
gtk.main_quit()
return False
self.hoge += 1

def timeout(self):
faces,processtime=area2face(self.x,self.y, self.width,self.height)

#ウィンドウシェイプに使うsurface
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, self.width,self.height)
ctx = cairo.Context(surface)
ctx.rectangle(0, 0, 50, 50)
ctx.rectangle(self.width-50, 0, self.width, 50)
ctx.rectangle(0, self.height-50, 50, self.height)
ctx.rectangle(self.width-50, self.height-50, self.width, self.height)
ctx.set_source_rgb(1, 1, 1)
ctx.fill()
if faces:
for k in faces:
ctx.move_to(faces[k][0][0],faces[k][0][1])
ctx.line_to(faces[k][1][0],faces[k][0][1])
ctx.line_to(faces[k][1][0],faces[k][1][1])
ctx.line_to(faces[k][0][0],faces[k][1][1])
ctx.line_to(faces[k][0][0],faces[k][0][1])
ctx.set_line_width(5)
ctx.stroke()

bitmap = gtk.gdk.Pixmap(None, self.width, self.height,1)
ca = bitmap.cairo_create()
ca.set_source_surface(surface)
ca.set_operator(cairo.OPERATOR_OVER)
ca.paint()

#マスクでウィンドウをシェイプ
win.shape_combine_mask(bitmap, self.x, self.y)
return True

def close_application(self, widget, event, data=None):
gtk.main_quit()
return False

if __name__ == '__main__':
win = ShapedWindow()
win.show_all()

gtk.main()
本ブログのOpenCVまとめ
OpenCV
            

コメントの投稿

非公開コメント

プロフィール

Matoba

Author:Matoba

最新記事
リンク
作ったものなど
月別アーカイブ
カテゴリ
タグリスト

検索フォーム
Amazon
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。