Search code examples
pythonopencvtypeerrormediapipe

How do I fix this python hand tracking with mediapipe and open-cv error?


So I am following this tutorial:Tutorial I cannot seem to get the HandTrackingModule working. The HandTrackingMin works fine. The difference is that I put all the code in a function and run it in the Module but in the min i just run it. The error is:

Traceback (most recent call last):
  File "C:\Users\danes\AppData\Roaming\JetBrains\PyCharm2023.1\scratches\scratch_2.py", line 122, in <module>
    main()
  File "C:\Users\danes\AppData\Roaming\JetBrains\PyCharm2023.1\scratches\scratch_2.py", line 102, in main
    detector = handDetector()
  File "C:\Users\danes\AppData\Roaming\JetBrains\PyCharm2023.1\scratches\scratch_2.py", line 22, in __init__
    self.hands = self.mpHands.Hands(self.mode, self.maxHands,
  File "C:\Users\danes\PycharmProjects\pythonProject\venv\lib\site-packages\mediapipe\python\solutions\hands.py", line 114, in __init__
    super().__init__(
  File "C:\Users\danes\PycharmProjects\pythonProject\venv\lib\site-packages\mediapipe\python\solution_base.py", line 289, in __init__
    self._input_side_packets = {
  File "C:\Users\danes\PycharmProjects\pythonProject\venv\lib\site-packages\mediapipe\python\solution_base.py", line 290, in <dictcomp>
    name: self._make_packet(self._side_input_type_info[name], data)
  File "C:\Users\danes\PycharmProjects\pythonProject\venv\lib\site-packages\mediapipe\python\solution_base.py", line 592, in _make_packet
    return getattr(packet_creator, 'create_' + packet_data_type.value)(data)
TypeError: create_int(): incompatible function arguments. The following argument types are supported:
    1. (arg0: int) -> mediapipe.python._framework_bindings.packet.Packet

Invoked with: 0.5

Process finished with exit code 1

Does anyone recognize this error?

I tried many different things. I even ended up copying and pasting tutorial code to see if it would work and I still get the same error.

Edit: here is the code

import cv2
import mediapipe as mp
import time


class handDetector():
    def __init__(self, mode=False, hand_complexity=1, maxHands=2, detectionCon=0.5, trackCon=0.5):
        self.handcom = hand_complexity
        self.mode = mode
        self.maxHands = maxHands
        self.detectionCon = detectionCon
        self.trackCon = trackCon

        self.mpHands = mp.solutions.hands
        self.hands = self.mpHands.Hands(self.mode, self.maxHands,
                                        self.detectionCon, self.trackCon)
        self.mpDraw = mp.solutions.drawing_utils

    def findHands(self, img, draw=True):
        imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        self.results = self.hands.process(imgRGB)
        # print(results.multi_hand_landmarks)

        if self.results.multi_hand_landmarks:
            for handLms in self.results.multi_hand_landmarks:
                if draw:
                    self.mpDraw.draw_landmarks(img, handLms,
                                               self.mpHands.HAND_CONNECTIONS)
        return img

    def findPosition(self, img, handNo=0, draw=True):

        lmList = []
        if self.results.multi_hand_landmarks:
            myHand = self.results.multi_hand_landmarks[handNo]
            for id, lm in enumerate(myHand.landmark):
                # print(id, lm)
                h, w, c = img.shape
                cx, cy = int(lm.x * w), int(lm.y * h)
                # print(id, cx, cy)
                lmList.append([id, cx, cy])
                if draw:
                    cv2.circle(img, (cx, cy), 15, (255, 0, 255), cv2.FILLED)

        return lmList


def main():
    pTime = 0
    cTime = 0
    cap = cv2.VideoCapture(1)
    detector = handDetector()
    while True:
        success, img = cap.read()
        img = detector.findHands(img)
        lmList = detector.findPosition(img)
        if len(lmList) != 0:
            print(lmList[4])

        cTime = time.time()
        fps = 1 / (cTime - pTime)
        pTime = cTime

        cv2.putText(img, str(int(fps)), (10, 70), cv2.FONT_HERSHEY_PLAIN, 3,
                    (255, 0, 255), 3)

        cv2.imshow("Image", img)
        cv2.waitKey(1)


if __name__ == "__main__":
    main()

Solution

  • It's a duplicate of [SO]: Type error: create_bool(): incompatible function arguments. Need some advice on this one (@CristiFati's answer), but I'm going to elaborate.

    According to [GitHub]: google/mediapipe - (v0.10.3) mediapipe/mediapipe/python/solutions/hands.py (latest at answer time, same on master branch), Hands initializer (around line #89) is:

      def __init__(self,
                   static_image_mode=False,
                   max_num_hands=2,
                   model_complexity=1,
                   min_detection_confidence=0.5,
                   min_tracking_confidence=0.5):
    

    The arguments you pass don't match expected ones (missing model_complexity) making it treat what you pass as min_detection_confidence as if it actually was model_complexity.

    To avoid running into this kind of error, use keyword arguments when initializing Hands (and in general). In your code, instead of calling the initializer as you currently do:

    self.hands = self.mpHands.Hands(self.mode, self.maxHands,
                                    self.detectionCon, self.trackCon)
    

    call it like this:

    self.hands = self.mpHands.Hands(
        static_image_mode=self.mode,
        max_num_hands=self.maxHands,
        model_complexity=self.handcom,  # @TODO - cfati: might also add missing argument
        min_detection_confidence=self.detectionCon,
        min_tracking_confidence=self.trackCon)