Created
October 18, 2010 21:27
-
-
Save mizchi/633103 to your computer and use it in GitHub Desktop.
鼻を追従してマウスが動くよ
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/opt/local/bin/python | |
| # -*- encoding:utf-8 -*- | |
| """ | |
| require: PyObjC opencv | |
| This program based on OpenCV sample, facedetect.py. | |
| 対象には haarcascade_mcs_nose を使っている。 鼻は他のオブジェクトと誤認しにくい | |
| """ | |
| import sys | |
| import cv | |
| from optparse import OptionParser | |
| import objc | |
| from AppKit import NSScreen | |
| from time import sleep | |
| """ | |
| 学習器サンプル | |
| haarcascade_eye.xml haarcascade_lefteye_2splits.xml haarcascade_mcs_righteye.xml | |
| haarcascade_eye_tree_eyeglasses.xml haarcascade_lowerbody.xml haarcascade_mcs_upperbody.xml | |
| haarcascade_frontalface_alt.xml haarcascade_mcs_eyepair_big.xml haarcascade_profileface.xml | |
| haarcascade_frontalface_alt2.xml haarcascade_mcs_eyepair_small.xml haarcascade_righteye_2splits.xml | |
| haarcascade_frontalface_alt_tree.xml haarcascade_mcs_lefteye.xml haarcascade_upperbody.xml | |
| haarcascade_frontalface_default.xml haarcascade_mcs_mouth.xml | |
| haarcascade_fullbody.xml haarcascade_mcs_nose.xml | |
| """ | |
| haardir = "/opt/local/share/opencv/haarcascades/" | |
| fpath = haardir +"haarcascade_mcs_nose.xml" | |
| min_size = ( 20, 20) | |
| image_scale = 2 | |
| haar_scale = 1.2 | |
| min_neighbors = 2 | |
| haar_flags = 0 | |
| SCREEN_W, SCREEN_H = NSScreen.mainScreen().frame()[1] | |
| class Mouse(object): | |
| def __init__(self): | |
| self.bndl = objc.loadBundle('CoreGraphics', globals(), '/System/Library/Frameworks/ApplicationServices.framework') | |
| def move(self, x, y): | |
| #bndl = objc.loadBundle('CoreGraphics', globals(), '/System/Library/Frameworks/ApplicationServices.framework') | |
| objc.loadBundleFunctions(self.bndl, globals(), [('CGWarpMouseCursorPosition', 'v{CGPoint=dd}')]) | |
| CGWarpMouseCursorPosition((x, y)) | |
| def click(self, x, y, ev_type=1): | |
| #bndl = objc.loadBundle('CoreGraphics', globals(), '/System/Library/Frameworks/ApplicationServices.framework') | |
| objc.loadBundleFunctions(self.bndl, globals(), [('CGPostMouseEvent', 'v{CGPoint=dd}III')]) | |
| CGPostMouseEvent((x, y), 1, ev_type, 1) | |
| CGPostMouseEvent((x, y), 1, ev_type, 0) | |
| mouse = Mouse() | |
| def detect_and_draw(img, cascade): | |
| # allocate temporary images | |
| gray = cv.CreateImage((img.width,img.height), 8, 1) | |
| small_img = cv.CreateImage((cv.Round(img.width / image_scale), | |
| cv.Round (img.height / image_scale)), 8, 1) | |
| # convert color input image to grayscale | |
| cv.CvtColor(img, gray, cv.CV_BGR2GRAY) | |
| # scale input image for faster processing | |
| cv.Resize(gray, small_img, cv.CV_INTER_LINEAR) | |
| cv.EqualizeHist(small_img, small_img) | |
| if(cascade): | |
| t = cv.GetTickCount() | |
| faces = cv.HaarDetectObjects(small_img, cascade, cv.CreateMemStorage(0), | |
| haar_scale, min_neighbors, haar_flags, min_size) | |
| t = cv.GetTickCount() - t | |
| if faces: | |
| for ((x, y, w, h), n) in faces: | |
| # the input to cv.HaarDetectObjects was resized, so scale the | |
| # bounding box of each face and convert it to two CvPoints | |
| pt1 = (int(x * image_scale), int(y * image_scale)) | |
| pt2 = (int((x + w) * image_scale), int((y + h) * image_scale)) | |
| cv.Rectangle(img, pt1, pt2, cv.RGB( 255, 255, 0), 3, 8, 0) | |
| print "objects: ", x + w / 2 ,y + h / 2 | |
| mouse.move( | |
| SCREEN_W/2 + 10*( 150 - (x+w/2)) , | |
| SCREEN_H/2 - 10*( 150 - (y+h/2)) ) | |
| print "detection time = %gms " % (t/(cv.GetTickFrequency()*1000.)) | |
| cv.ShowImage("result", img) | |
| if __name__ == '__main__': | |
| 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 = fpath) | |
| (options, args) = parser.parse_args() | |
| cascade = cv.Load(fpath)# cascading file の指定 | |
| input_name = "1" | |
| capture = cv.CreateCameraCapture(int(input_name)) | |
| cv.NamedWindow("result", 1) | |
| if capture: | |
| frame_copy = None | |
| while True: | |
| frame = cv.QueryFrame(capture) | |
| if not frame: | |
| cv.WaitKey(0) | |
| break | |
| if not frame_copy: | |
| frame_copy = cv.CreateImage((frame.width,frame.height), | |
| cv.IPL_DEPTH_8U, frame.nChannels) | |
| if frame.origin == cv.IPL_ORIGIN_TL: | |
| cv.Copy(frame, frame_copy) | |
| else: | |
| cv.Flip(frame, frame_copy, 0) | |
| detect_and_draw(frame_copy, cascade) | |
| if cv.WaitKey(10) >= 0: | |
| break | |
| else: | |
| image = cv.LoadImage(input_name, 1) | |
| detect_and_draw(image, cascade) | |
| cv.WaitKey(0) | |
| cv.DestroyWindow("result") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment