Untitled

mail@pastecode.io avatar
unknown
plain_text
6 months ago
3.9 kB
9
Indexable
Never
import cv2
import numpy as np
from pynput.mouse import Button,Controller #Contains Mouse Operations
import wx #WX Lib is used To get the Screen Size Of Monitor

def leftClick():
    mouse = Controller()

    app = wx.App(False)
    (sx,sy) = wx.GetDisplaySize() #sx=screen x co-ordinate ; sy = screen y co-ordinate
    (camx,camy) = (480,320) # Resolution in which Camera will Display

    #numpy range for Red Color
    lower_bound = np.array([130, 90, 109])
    upper_bound = np.array([203, 225, 180])

    cam = cv2.VideoCapture(0)

    #Flags
    cam.set(3, camx)
    cam.set(4, camy)

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

    #For Movement Issues
    mLocOld = np.array([0,0])
    mouseLoc = np.array([0,0])

    #Mouse Damping Method Decide the smoothness of Mouse movement
    #mouseLoc = mLocOld + (targetLoc - mLocOld)/DampingFactor
    #More the Damping Value Smoother will be the Mouse

    Df = 2.3 #Damping Factor Should be > 1

    pinchFlag = 0

    while True:
        ret,img = cam.read()
        #img = cv2.resize(img,(340,220))  ;in case the (camx,camy) instruction work slower use this

        #Convert BGR to HSV
        imgHSV = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)

        #create the Mask
        mask = cv2.inRange(imgHSV,lower_bound,upper_bound)

        #morphology
        maskOpen = cv2.morphologyEx(mask,cv2.MORPH_OPEN,kernelOpen)
        maskClose = cv2.morphologyEx(maskOpen,cv2.MORPH_CLOSE,kernelClose)

        maskFinal = maskClose

        #contour creation
        conts,h = cv2.findContours(maskFinal.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)




        #Logic drawing the Pointer

        #For 2 Objects

        if(len(conts)==2):

            if(pinchFlag==1):
                pinchFlag = 0
                #Release Operation of Mouse
                mouse.release(Button.left)
        
            #detecting the two Objects And making a Rectangle Around It
            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)

            #drawing a Line Between The Two Objects
            cx1 = x1 + w1/2
            cy1 = y1 + h1/2
            cx2 = x2 + w2/2
            cy2 = y2 + h2/2
            #Here you might get an error:integer variable expected so convert cx1,cy1,cx2,cy2 into integer
            cv2.line(img,(int(cx1),int(cy1)),(int(cx2),int(cy2)),(255,0,0),2)

            #Drawing Circle At Center of Line that will act as Pointer
            cx = (cx1+cx2)/2
            cy = (cy1+cy2)/2
            cv2.circle(img,(int(cx),int(cy)),2,(0,255,0),2)
            mouseLoc = mLocOld + ((int(cx),int(cy)) - mLocOld)/Df

            #Inorder to move mouse
            mouse.position = (sx-(mouseLoc[0]*sx/camx),mouseLoc[1]*sy/camy)
            mLocOld = mouseLoc
        




        #For 1 Object

        elif(len(conts)==1):
            if(pinchFlag==0):
                pinchFlag = 1
                #instruction for Left Click
                mouse.press(Button.left)
            x,y,w,h = cv2.boundingRect(conts[0])
            cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
            cx = x + w/2
            cy = y + h/2
            cv2.circle(img,(int(cx),int(cy)),int((w+h)/6),(0,0,255),2)
            mouseLoc = mLocOld + ((int(cx),int(cy)) - mLocOld)/Df
            mouse.position = (sx-(mouseLoc[0]*sx/camx),mouseLoc[1]*sy/camy)
            mLocOld = mouseLoc


        

        #Display Camera
        cv2.imshow('Cam', img)

        k = cv2.waitKey(5) &0xFF
        if k == 27:
            break

    cam.release()

    cv2.destroyAllWindows()

if __name__ == "__main__":
    leftClick()