Jump to content

Idk way the code dosent work i am a begener(python opencv)

Symbolls

so the code has this error

 

Traceback (most recent call last):
  File "D:\Opencv tests\HandVolume.py", line 31, in <module>
    img = detector.findHands(0,img)
  File "D:\Opencv tests\HandTrackingModule.py", line 21, in findHands
    self.results = self.hands.process(imgRGB)
AttributeError: 'int' object has no attribute 'hands'
[ WARN:0] global D:\a\opencv-python\opencv-python\opencv\modules\videoio\src\cap_msmf.cpp (438) `anonymous-namespace'::SourceReaderCB::~SourceReaderCB terminating async callback

 

idk i have tryd playng arround with the code trying to fix it but it dont work so i was hoping someoane will help me i dont know what to write to fix it

 

the code is in the latest version of python and i am using pycharm and py charm dosent know whats wrong the code has 2 part the main part and a secondary part that is a module for the first the files are down below but i will leave the code visible

 

Thx for your thime in advace

 

import cv2
import time
import numpy as np
import HandTrackingModule as htm
import math
from ctypes import cast, POINTER
from comtypes import CLSCTX_ALL
from pycaw.pycaw import AudioUtilities, IAudioEndpointVolume
################################
wCam, hCam = 640, 480
################################
cap = cv2.VideoCapture(0)
cap.set(3, wCam)
cap.set(4, hCam)
pTime = 0
detector = htm.handDetector#(detectionCon = 0.7)
devices = AudioUtilities.GetSpeakers()
interface = devices.Activate(
    IAudioEndpointVolume._iid_, CLSCTX_ALL, None)
volume = cast(interface, POINTER(IAudioEndpointVolume))
# volume.GetMute()
# volume.GetMasterVolumeLevel()
volRange = volume.GetVolumeRange()
minVol = volRange[0]
maxVol = volRange[1]
vol = 0
volBar = 400
volPer = 0
while True:
    success, img = cap.read()
    img = detector.findHands(0,img)
    lmList = detector.findPosition(img, draw=False)
    if len(lmList) != 0:
        # print(lmList[4], lmList[8])
        x1, y1 = lmList[4][1], lmList[4][2]
        x2, y2 = lmList[8][1], lmList[8][2]
        cx, cy = (x1 + x2) // 2, (y1 + y2) // 2
        cv2.circle(img, (x1, y1), 15, (255, 0, 255), cv2.FILLED)
        cv2.circle(img, (x2, y2), 15, (255, 0, 255), cv2.FILLED)
        cv2.line(img, (x1, y1), (x2, y2), (255, 0, 255), 3)
        cv2.circle(img, (cx, cy), 15, (255, 0, 255), cv2.FILLED)
        length = math.hypot(x2 - x1, y2 - y1)
        print(length)
        # Hand range 50 - 300
        # Volume Range -65 - 0
        vol = np.interp(length, [50, 300], [minVol, maxVol])
        volBar = np.interp(length, [50, 300], [400, 150])
        volPer = np.interp(length, [50, 300], [0, 100])
        print(int(length), vol)
        volume.SetMasterVolumeLevel(vol, None)
        if length < 50:
            cv2.circle(img, (cx, cy), 15, (0, 255, 0), cv2.FILLED)
    cv2.rectangle(img, (50, 150), (85, 400), (255, 0, 0), 3)
    cv2.rectangle(img, (50, int(volBar)), (85, 400), (255, 0, 0), cv2.FILLED)
    cv2.putText(img, f'{int(volPer)} %', (40, 450), cv2.FONT_HERSHEY_COMPLEX,
                1, (255, 0, 0), 3)
    cTime = time.time()
    fps = 1 / (cTime - pTime)
    pTime = cTime
    cv2.putText(img, f'FPS: {int(fps)}', (40, 50), cv2.FONT_HERSHEY_COMPLEX, 1, (255, 0, 0), 3)
    cv2.imshow("Img", img)
    cv2.waitKey(1)
import cv2
import mediapipe as mp
import time
import math


class handDetector():
    def __init__(self, mode=False, maxHands=2, detectionCon=0.5, trackCon=0.5):
        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
        self.tipIds = [4, 8, 12, 16, 20]

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

        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):
        xList = []
        yList = []
        bbox = []
        self.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)
                xList.append(cx)
                yList.append(cy)
                # print(id, cx, cy)
                self.lmList.append([id, cx, cy])
        if draw:
            cv2.circle(img, (cx, cy), 5, (255, 0, 255), cv2.FILLED)
            xmin, xmax = min(xList), max(xList)
            ymin, ymax = min(yList), max(yList)
            bbox = xmin, ymin, xmax, ymax

        if draw:
            cv2.rectangle(img, (bbox(0), -20, bbox(1), -20),
                          (bbox[2] + 20, bbox[3] + 20), (0, 255, 0), 2)

        return self.lmList, bbox

    def fingersUp(self):
        fingers = []
        # Thumb
        if self.lmList[self.tipIds[0]][1] > self.lmList[self.tipIds[0]][1]:
            fingers.append(1)
        else:
            fingers.append(0)
        # 4 Fingers
        for id in range(1, 5):
            if self.lmList[self.tipIds[id]][2] < self.lmList[self.tipIds[id]][2]:
                fingers.append(1)
            else:
                fingers.append(0)
        return fingers

    def findDistance(self, p1, p2, img, draw=True):

        x1, y1 = self.lmList[p1][1], self.lmList[p1][2]
        x2, y2 = self.lmList[p2][1], self.lmList[p2][2]
        cx, cy = (x1 + x2) // 2, (y1 + y2) // 2

        if draw:
            cv2.circle(img, (x1, y1), 15, (255, 0, 255), cv2.FILLED)
            cv2.circle(img, (x2, y2), 15, (255, 0, 255), cv2.FILLED)
            cv2.line(img, (x1, y1), (x2, y2), (255, 0, 255), 3)
            cv2.circle(img, (cx, cy), 15, (255, 0, 255), cv2.FILLED)
            length = math.hypot(x2 - x1, y2 - y1)

        return length, img, [x1, y1, x2, y2, cx, cy]


def main():
    pTime = 0
    cap = cv2.VideoCapture(0)
    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()

 

 

HandTrackingModule.py HandVolume.py

Link to comment
Share on other sites

Link to post
Share on other sites

In this line:

detector = htm.handDetector#(detectionCon = 0.7)

don't you mean your own class that you put at the bottom, that is remove the "htm." bit?

 

Also you need parentheses when instantiating a class, so at least it should be like

detector = htm.handDetector()

 

[Edit] Didn't realise they were two different files. OP you might want to try make it clearer that there are two different bits of code, now they are back to back in the post.

Crystal: CPU: i7 7700K | Motherboard: Asus ROG Strix Z270F | RAM: GSkill 16 GB@3200MHz | GPU: Nvidia GTX 1080 Ti FE | Case: Corsair Crystal 570X (black) | PSU: EVGA Supernova G2 1000W | Monitor: Asus VG248QE 24"

Laptop: Dell XPS 13 9370 | CPU: i5 10510U | RAM: 16 GB

Server: CPU: i5 4690k | RAM: 16 GB | Case: Corsair Graphite 760T White | Storage: 19 TB

Link to comment
Share on other sites

Link to post
Share on other sites

    img = detector.findHands(0,img)

what's the 0 for here? the function only expects an image as an argument and optionally a boolean, definitely not an integer:

    def findHands(self, img, draw=True):

 

Don't ask to ask, just ask... please 🤨

sudo chmod -R 000 /*

Link to comment
Share on other sites

Link to post
Share on other sites

3 hours ago, Sauron said:
    img = detector.findHands(0,img)

what's the 0 for here? the function only expects an image as an argument and optionally a boolean, definitely not an integer:

    def findHands(self, img, draw=True):

 

i dont know its not my original code so idk i was falowing a tutorial but the guy in the video got it to work but to me after i copyd the code it wasant

Link to comment
Share on other sites

Link to post
Share on other sites

20 minutes ago, Symbolls said:

i dont know its not my original code so idk i was falowing a tutorial but the guy in the video got it to work but to me after i copyd the code it wasant

Don't just copy and paste code without understanding what it does if you're looking to learn. Also if you manually copied the code from a video chances are you made a mistake somewhere.

Don't ask to ask, just ask... please 🤨

sudo chmod -R 000 /*

Link to comment
Share on other sites

Link to post
Share on other sites

As I mentioned above, your problem is at least this line:

detector = htm.handDetector#(detectionCon = 0.7)

The bit you commented out had characters crucial to the functionality of the code. You need parentheses when instantiating the class:

# This is wrong in your case:
detector = htm.handDetector

# This is correct in your case:
detector = htm.handDetector()

 

Here's a snippet that demonstrates what is happening when not using parentheses:

class TestClass():
        def __init__(self, mode=False, maxHands=2):
                print('self is', self)
                print('mode is', mode)
                print('maxHands is', maxHands)

        def otherFunction(self, img, draw=True):
                print('self is', self)
                print('img is', img)
                print('draw is', draw)

print('Calling with parentheses:')
y = TestClass()
print('Type of y is: ', type(y))
y.otherFunction(0, [1, 2, 3])

print('Calling without parentheses:')
x = TestClass
print('Type of x is: ', type(x))
x.otherFunction(0, [1, 2, 3])

The output is as follows:

Calling with parentheses:
self is <__main__.TestClass object at 0x7f91b5f73748>
mode is False
maxHands is 2
Type of y is:  <class '__main__.TestClass'>
self is <__main__.TestClass object at 0x7f91b5f73748>
img is 0
draw is [1, 2, 3]

Calling without parentheses:
Type of x is:  <class 'type'>
self is 0
img is [1, 2, 3]
draw is True

When you instantiate it, the __init__ function runs first, which is why you see mode and maxHands being printed, and importantly self is a reference to the class instance. Inspecting the type of y, you see it is an instance of TestClass.

 

When you do not use parentheses you are not instantiating the class, but simple creating a reference to that class object. The first sign is that you see that __init__ never runs. Inspecting the type of x, you see it is not an instance of TestClass, but simply a type object, namely the class object itself.

 

What is happening, is that because you do not instantiate it, but simply use the class object itself, the call detector.findHands(0,img) equivalent to detector.findHands(self=0, img=img, draw=True) and there lies what results into the interpreter throwing AttributeError: 'int' object has no attribute 'hands'. self is expected to be the class instance itself (hence the name self), but you give it an integer.

 

Besides that, as @Sauron says, I don't see why you would need to pass an integer to it at all, unless that is some weird way around the stuff described above in their Python version. In that case I would consider it obscure and bad practise (but that's just speculating).

Crystal: CPU: i7 7700K | Motherboard: Asus ROG Strix Z270F | RAM: GSkill 16 GB@3200MHz | GPU: Nvidia GTX 1080 Ti FE | Case: Corsair Crystal 570X (black) | PSU: EVGA Supernova G2 1000W | Monitor: Asus VG248QE 24"

Laptop: Dell XPS 13 9370 | CPU: i5 10510U | RAM: 16 GB

Server: CPU: i5 4690k | RAM: 16 GB | Case: Corsair Graphite 760T White | Storage: 19 TB

Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×