Skip to content

Commit

Permalink
Create Virtualpointer.py
Browse files Browse the repository at this point in the history
  • Loading branch information
yashpatel458 authored Feb 11, 2021
0 parents commit c86cb7d
Showing 1 changed file with 117 additions and 0 deletions.
117 changes: 117 additions & 0 deletions Virtualpointer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import cv2
import numpy as np
from pynput.mouse import Button ,Controller
import wx
mouse=Controller()

app=wx.App(False)
(sx,sy)=wx.GetDisplaySize()
(camx,camy)=(320,240)
cap=cv2.VideoCapture(0)

#range for HSV (green color)
lowerBound=np.array([33,70,30])
upperBound=np.array([102,255,255])

#Kerenel
kernelOpen=np.ones((5,5))
kernelClose=np.ones((20,20))

mLocOld=np.array([0,0])
mouseLoc=np.array([0,0])

DampingFactor=2 #Damping factor must be greater than 1

pinchFlag=0
openx,openy,openw,openh=(0,0,0,0)

while True:

_,img=cap.read()

img=cv2.resize(img,(340,240))
imgHSV=cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
mask=cv2.inRange(imgHSV,lowerBound,upperBound)

#using morphology to erase noise as maximum as possible
maskOpen=cv2.morphologyEx(mask,cv2.MORPH_OPEN,kernelOpen)
maskClose=cv2.morphologyEx(maskOpen,cv2.MORPH_CLOSE,kernelClose)
maskFinal=maskClose

_,conts,_=cv2.findContours(maskFinal,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)

# Once 2 objects are detected the center of there distance will be the reference on controlling the mouse
if(len(conts)==2):

#if the button is pressed we need to release it first
if(pinchFlag==1):
pinchFlag=0
mouse.release(Button.left)

#drawing the rectagle around both objects
x1,y1,w1,h1=cv2.boundingRect(conts[0])
x2,y2,w2,h2=cv2.boundingRect(conts[1])
cv2.rectangle(img,(x1,y1),(x1+w1,y1+h1),(255,0,0),2)
cv2.rectangle(img,(x2,y2),(x2+w2,y2+h2),(255,0,0),2)

#the line between the center of the previous rectangles
cx1=int(x1+w1/2)
cy1=int(y1+h1/2)
cx2=int(x2+w2/2)
cy2=int(y2+h2/2)
cv2.line(img,(cx1,cy1),(cx2,cy2),(255,0,0),2)

#the center of that line (reference point)
cx=int((cx1+cx2)/2)
cy=int((cy1+cy2)/2)
cv2.circle(img,(cx,cy),2,(0,0,255),2)

#adding the damping factor so that the movement of the mouse is smoother
mouseLoc=mLocOld+((cx,cy)-mLocOld)/DampingFactor
mouse.position=(sx-int((mouseLoc[0]*sx)/camx),int((mouseLoc[1]*sy)/camy))
while mouse.position!=(sx-int((mouseLoc[0]*sx)/camx),int((mouseLoc[1]*sy)/camy)):
pass

#setting the old location to the current mouse location
mLocOld=mouseLoc

#these variables were added so that we get the outer rectangle that combines both objects
openx,openy,openw,openh=cv2.boundingRect(np.array([[[x1,y1],[x1+w1,y1+h1],[x2,y2],[x2+w2,y2+h2]]]))

#when there's only when object detected it will act as a left click mouse
elif(len(conts)==1):
x,y,w,h=cv2.boundingRect(conts[0])

# we check first and we allow the press fct if it's not pressed yet
#we did that to avoid the continues pressing
if(pinchFlag==0):

if(abs((w*h-openw*openh)*100/(w*h))<30): #the difference between th combined rectangle for both object and the
pinchFlag=1 #the outer rectangle is not more than 30%
mouse.press(Button.left)
openx,openy,openw,openh=(0,0,0,0)

#this else was added so that if there's only one object detected it will not act as a mouse
else:
#getting rectangle coordinates and drawing it
x,y,w,h=cv2.boundingRect(conts[0])
cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)

#getting the center of the circle that will be inside the outer rectangle
cx=int(x+w/2)
cy=int(y+h/2)
cv2.circle(img,(cx,cy),int((w+h)/4),(0,0,255),2) #drawing that circle
mouseLoc=mLocOld+((cx,cy)-mLocOld)/DampingFactor
mouse.position=(sx-int((mouseLoc[0]*sx)/camx),int((mouseLoc[1]*sy)/camy))
while mouse.position!=(sx-int((mouseLoc[0]*sx)/camx),int((mouseLoc[1]*sy)/camy)):
pass
mLocOld=mouseLoc



#showing the results
cv2.imshow("(By 19DCS103 & 19DCS106)",img)
cv2.waitKey(5)



0 comments on commit c86cb7d

Please sign in to comment.