How can I remove the "jitter" of the mouse cursor moving with the help of hand detection?

237 Views Asked by At

There is a project on computer vision in python: an image is captured from a webcam using opencv, then using mediapipe, hands are detected in the frame and using autopy, the mouse cursor moves along with the index finger of the hand. There was a problem: after detecting a hand, the mouse cursor starts to shake violently and move involuntarily, even if the hand is static. I would like to know if there is a way to remove this "jitter" in some way. Check the script below:

import cv2
import autopy
import mediapipe as mp
cap = cv2.VideoCapture(0)
width, height = autopy.screen.size()
hands = mp.solutions.hands.Hands(static_image_mode=False, max_num_hands=1, min_tracking_confidence=0.5,
                                 min_detection_confidence=0.5)
mpDraw = mp.solutions.drawing_utils
f1, f2 = False, False
while True:
    _, img = cap.read()
    img = cv2.flip(img, 1)
    result = hands.process(img)
    if f1 and not f2:
        print('\nHand disappeared')
    if result.multi_hand_landmarks:
        for id_finger, lm in enumerate(result.multi_hand_landmarks[0].landmark):
            h, w, _ = img.shape
            f1 = f2
            f2 = True
            if not f1 and f2:
                print('Hand appeared')
            cx, cy = int(lm.x * w), int(lm.y * h)
            cv2.circle(img, (cx, cy), 3, (255, 0, 255))
            if id_finger == 4:
                cx_2, cy_2 = cx, cy
            if id_finger == 8:
                cv2.circle(img, (cx, cy), 25, (255, 0, 255), cv2.FILLED)
                cx_1, cy_1 = cx, cy
                try:
                    autopy.mouse.move(cx * width / w, cy * height / h)
                    print(cx, cy, sep=' ', end='; ')
                except ValueError:
                    continue
                if ((cx_1 - cx_2) ** 2 + (cy_1 - cy_2) ** 2) ** 0.5 < 50:
                    try:
                        autopy.mouse.click()
                    except ValueError:
                        continue
        mpDraw.draw_landmarks(img, result.multi_hand_landmarks[0], mp.solutions.hands.HAND_CONNECTIONS)
    else:
        f1 = f2
        f2 = False
    cv2.imshow("Hand tracking", img)
    cv2.waitKey(1)
1

There are 1 best solutions below

0
Riccardo Volpe On

Together with the Kalman filter, here you can read a discussion about mediapipe's landmarks jittering, in which the use of the One Euro filter emerges, of which here you can read details of its algorithm, here you can find a demo and here you can find the implementation in different programming languages. In the demo you have the possibility to compare different filters in addition to the two mentioned.