Yüz takibiyle fare oynatmaca
Hep merak etmişimdir, işimiz insan-bilgisayar etkileşimi ama bilgisayar bizle etkileşiyor, biz onunla nasıl etkileşeceğiz diye. GNU/Linux kullanıyorsanız 15 dakikada bilgisayarınızı Azınlık Raporu’ndaki muhteşem etkileşim sahnesinin çoook minimal haline getirebilir ve küçük Tom Cruise’u oynayabilirsiniz.
İhtiyacımız olan paketler: python, opencv (halihazırda python kodları geliyor) ve xdotool
Tarif:
- Üstteki paketleri sisteminize kurun. Ben Ubuntu kullandığım için
apt-get
ile kurdum, depoda mevcuttular. - Sonra alttaki koddaki gerekli yerleri değiştirip eğlenin (değiştirmeniz gerekebilecek yerlerde !!! var).
Kod özetle şunu yapıyor: Opencv kullanarak yüzünüzü buluyor. Ardından bulduğu konuma göre farenin (imlecin) yerini güncelliyor. Kafanızı sağa sola hareket ettirdikçe fare oynuyor. Hani blobby oyunu vardı, fareyle oynanabilen voleybol oyunu. Eğer yurtta kaldıysanız belki bilirsiniz, efsane yurt oyunlarındandır. İşte öyle bir oyunu bu şekilde oynamanın önü açık. Yurtta işiniz gücünüz yoksa kodu geliştirip kafanızla topa vuruyormuşçasına blobby oynayabilirsiniz.
#!/usr/bin/env python # -*- coding: utf-8 -*- """Yüz takibi ile fare oynatmaca İsmail Arı, 2008 Not: Çıkmak için bir tuşa basın""" import os import sys from opencv.cv import * from opencv.highgui import * # Opencv'nin yüklü olduğu klasörde haarcascades_bişeybişey.xml tarzı dosyalar olacak. # Bunlar yüz modelleri dosyaları. Onlardan ben karşıdan olanı kullanıyorum ama istediğinizi seçip deneyebilirsiniz. cascade_name = "modellerin_oldugu_klasor/haarcascade_frontalface_alt.xml" # !!! # Haar tabanlı yüz bulma için parametreler hakkında: # http://opencv.willowgarage.com/documentation/python/pattern_recognition.html?highlight=cvhaardetectobjects#HaarDetectObjects # varsayılan değerler şöyleydi: scale_factor=1.1, min_neighbors=3, flags=0, min_size=(0, 0) # !!! min_size = cvSize(20, 20) scale_factor = 1.2 min_neighbors = 3 haar_flags = CV_HAAR_DO_CANNY_PRUNING # Global değişkenler cascade = None storage = cvCreateMemStorage(0) input_name = 0 # ilk kamera def detect_and_draw( img ): gray = cvCreateImage( cvSize(img.width,img.height), 8, 1 ); small_img = cvCreateImage( cvSize( cvRound (img.width/scale_factor), cvRound (img.height/scale_factor)), 8, 1 ); cvCvtColor( img, gray, CV_BGR2GRAY ); cvResize( gray, small_img, CV_INTER_LINEAR ); cvEqualizeHist( small_img, small_img ); cvClearMemStorage( storage ); if( cascade ): t = cvGetTickCount(); faces = cvHaarDetectObjects( small_img, cascade, storage, scale_factor, min_neighbors, haar_flags, min_size ); t = cvGetTickCount() - t; print "Bulma zamani = %gms" % (t/(cvGetTickFrequency()*1000.)) if faces: for r in faces: pt1 = cvPoint( int(r.x*scale_factor), int(r.y*scale_factor)) pt2 = cvPoint( int((r.x+r.width)*scale_factor), int((r.y+r.height)*scale_factor) ) cvRectangle( img, pt1, pt2, CV_RGB(255,0,0), 3, 8, 0 ) cx = (pt1.x + pt2.x) / 2 cy = (pt1.y + pt2.y) / 2 os.system("xdotool mousemove " + str(2*cx) + " " + str(2*cy)) # xdotool'a koordinatları gönderelim cvShowImage( "Sonuc", img ); if __name__ == '__main__': cascade = cvLoadHaarClassifierCascade( cascade_name, cvSize(1,1) ) if not cascade: print "HATA: xml dosyasini dogru verdiginize emin misiniz?" sys.exit(-1) capture = cvCreateCameraCapture( int(input_name) ) cvNamedWindow( "Sonuc", 1 ) frame_copy = None while True: frame = cvQueryFrame( capture ) if( not frame ): break; if( not frame_copy ): frame_copy = cvCreateImage( cvSize(frame.width,frame.height), IPL_DEPTH_8U, frame.nChannels ) cvFlip( frame, frame_copy, 1 ) # Buna gerek olmayabilir, benim kamerada gerek oldu detect_and_draw( frame_copy ) if( cvWaitKey( 10 ) >= 0 ): break; cvDestroyWindow("Sonuc")
Dediğim gibi bu çook minimal bir etkileşim gösterimidir. Fareyi nasıl kontrol edebiliriz diye meraktan denemiştim. Eğlencesine yani. O sebeple kod farklı yerlerden kopyala-yapıştır, değiştir-dene tarzı oldu ve normalde yazılması gereken temiz, güzel kod standartından çok uzak.