2017-08-19 25 views
12

W tym kodzie używam Python 2.7.13, OpenCV 2.4.13 i PyAutoGUI 0.9.36. Celem jest przesunięcie kursora zgodnie z ruchem twarzy, ale ruch kursora jest odwrócony. Na przykład, jeśli moja twarz idzie w prawo, kursor przesuwa się w lewo, a jeśli moja twarz idzie w lewo, kursor przesuwa się w prawo. Chcę również, aby kursor przesuwał się w prawo, w lewo, w górę iw dół na całym ekranie mojego komputera, którego rozmiar to x = 1920, y = 1080.Jak mogę odwrócić ruch kursora w pythonie?

Celem tego programu jest pokazanie, że możliwe jest uzyskanie nowego sposobu uzyskania większej niezależności i dostępu, tak aby osoby z tetraplegią mogły wykonywać proste czynności, które są częścią rutyny milionów osób , takie jak włączanie i wyłączanie światła oraz włączanie i wyłączanie telewizora.

import cv2 
import pyautogui 

faceCascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') 

video_capture = cv2.VideoCapture(0) 

while True: 
    # Capture frame-by-frame 
    ret, frame = video_capture.read() 

    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) 
    faces = faceCascade.detectMultiScale(
     gray, 
     scaleFactor=1.3, 
     minNeighbors=5, 
     minSize=(80, 80), 
     flags=cv2.cv.CV_HAAR_SCALE_IMAGE 
    ) 

    #print 'faces: ', faces 

    # Draw a rectangle around the faces 
    for (x, y, w, h) in faces: 
     cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 0, 255), 3) 

    #width, height = pyautogui.size() 
    #cursorx, cursory = pyautogui.position() 
    #posx = width - cursorx 
    #posy = cursory 
    pyautogui.moveTo(x+w, y+h) 

    # Display the resulting frame 
    #cv2.imshow('Video', frame) 
    rimg = cv2.flip(frame,1) #invert the object frame 
    cv2.imshow("vertical flip", rimg) 

    if cv2.waitKey(1) & 0xFF == ord('q'): 
     break 
# When everything is done, release the capture 
video_capture.release() 
cv2.destroyAllWindows() 
+0

co się stanie, jeśli odwrócisz ramkę natychmiast po jej uzyskaniu. zamiast robić rimg, żeby to pokazać. Również, jeśli zmienisz rozmiar ramki do rozmiaru ekranu, czy nie rozwiąże to innego problemu? – ROAR

+0

Jest jeszcze jedna rzecz, którą możesz zrobić. chociaż myślę, że nadal musisz odwrócić obraz, zanim wykryjesz na nim twarz. Ale nie musisz zmieniać jego rozmiaru (nie sądzę, że nawet przy zmianie rozmiaru możesz dostać się do krawędzi ekranu.) Możesz wykryć, czy twarz znajduje się w środkowej części ramki, a jeśli nie jest odpowiednio przesunięty (co x milisekund). Jeśli twarz znajduje się dalej od środka, spraw, aby mysz poruszała się szybciej w tym kierunku, a jeśli jest bliżej, porusza się wolniej. jeśli środek (ish) zatrzyma ruch myszy. – ROAR

+0

Po pierwsze, czy możesz określić ruch głowy lub ruch mimiki (brwi, oczu itp.)? Sugerowałbym, że ruch głowy byłby wykluczony z programu, aby uniknąć nadmiernego pobudzenia ucha wewnętrznego (żyroskopu ciała) przez nagły ruch obchodzenia, adhezji, skręcania i subdukcji. Czy możesz wygenerować dane śledzenia myszy? Po prostu wydrukuj swoje współrzędne X, Y podczas przesuwania myszy w górę, w dół, w lewo, w prawo i edytuj swój wpis z tymi danymi. – Danilo

Odpowiedz

1

Jeżeli znasz rozmiar ekranu, wystarczy odjąć to, co masz teraz od rozmiaru ekranu, aby uzyskać kursor po przeciwnej stronie. Na przykład:

pyautogui.moveTo(1920 - (x+w), 1080 - (y+h)) 

Jeśli x + w trafiało wam pozycję ekranu 2 (po lewej stronie ekranu), to teraz dostać wam pozycję ekranu 1918 (na prawo od ekranu)

4

to jest fajna rzecz, którą robisz.

Aby naprawić ruch myszy, można odjąć ruchy x, y od rozmiaru ekranu. Ale następnie rozciągnięcie go na cały ekran z pyautogui.moveTo (x, y) byłoby bardzo niedokładne i głośne. Zamiast do gładsza można użyć

pyautogui.moveRel(None, steps) 

Z powiedział, Jeśli używasz twarz kaskadę w pierwszej kolejności, to byłoby bardzo trudno przenieść na twarzy odpowiada ruch myszy. Używanie orientacji twarzy, na przykład pochylania w lewo lub w prawo, byłoby lepsze.

W poniższym kodzie użyłem kaskady oka dla ruchu po lewej stronie prawej. Więc przechylenie twarzy trochę wystarczyłoby do ruchu. Pracowałem nad OpenCV 3.2, więc w razie potrzeby dokonaj niezbędnych zmian w swojej wersji.

KOD

import numpy as np 
import cv2 
import pyautogui 

right = cv2.CascadeClassifier('haarcascade_righteye_2splits.xml') 
left = cv2.CascadeClassifier('haarcascade_lefteye_2splits.xml') 
smile = cv2.CascadeClassifier('haarcascade_smile.xml') 

cam=cv2.VideoCapture(0) 

blank=np.zeros((480,848,3),dtype=np.uint8) # Change this correctly to size of your image frame 
fix=0 

print "press y to set reference box for y motion" #set a reference initially for y motion 

while(cam.isOpened()): 


     ret,img = cam.read() 
     r=0 
     l=0 
     gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 
     r_eye= right.detectMultiScale(gray, 1.9, 9) 
     l_eye= left.detectMultiScale(gray, 1.9, 9) #Change these values according to face distance from screen 

     for (rx,ry,rw,rh) in r_eye: 
       cv2.rectangle(img,(rx,ry),(rx+rw,ry+rh),(255,255,0),2) 
       r_c=(rx+rw/2,ry+rh/2) 
       r=1 

     for (lx,ly,lw,lh) in l_eye:   
       cv2.rectangle(img,(lx,ly),(lx+lw,ly+lh),(0,255,255),2) 
       l_c=(lx+lw/2,ly+lh/2) 
       l=1 

     if(r*l): 

      if(l_c[0]-r_c[0]>50): 
       cv2.line(img,r_c,l_c,(0,0,255),4) 
       mid=((r_c[0]+l_c[0])/2,(r_c[1]+l_c[1])/2) 
       cv2.circle(img,mid,2,(85,25,100),2) 
       if(fix==1):      # Change this part of code according to what you want 
                # for motion along y direction 
        if(mid[1]<one[1]): 
         pyautogui.moveRel(None, -15) 
        if(mid[1]>two[1]): 
         pyautogui.moveRel(None, 15) 

       if(cv2.waitKey(1))== ord('y'): 
         blank=np.zeros_like(img) 
         one=(mid[0]-60,r_c[1]-7) # Change the Value 60,7 to change box dimentions 
         two=(mid[0]+60,l_c[1]+7) # Change the Value 60,7 to change box dimentions 
         cv2.rectangle(blank,one,two,(50,95,100),2) 
         fix=1 


     elif(r) : pyautogui.moveRel(-30, None) # Change the Value and Sign to change speed and direction 

     elif (l): pyautogui.moveRel(30, None) # Change the Value and Sign to change speed and direction 



     img=cv2.bitwise_or(img,blank) 
     cv2.imshow('img',img) 
     if(cv2.waitKey(1))==27:break 

cv2.destroyAllWindows() 

W kodzie, trzeba nacisnąć Y, aby ustawić pole dla odniesienia y ruchu. Po wyjęciu z pudełka, oba oczy będą ruchem.

Możemy dodać kaskadę uśmiechu do kliknięcia myszą, ale na razie jest to niedokładne i powolne. Potrzebujesz wymyślić lepsze opcje, takie jak kliknięcie oczu lub coś takiego.
To jest bardzo prosty kod, aby wszystko działało. Oznaczanie w sieciach neuronowych wyrazów twarzy może być o wiele lepsze, ale znowu szybkość jest czynnikiem.

Powiązane problemy