I'm trying to run the cvzone gesturedetection.py code using OpenCV (version 4.4.0.4). When I run the code, I see my webcam image for 2 seconds and then it closes immediately. I then get an error stating that there are issues with capturing the landmark data. Is it a code error, or are the packages incompatible? I'm running the following code:
from cvzone.PoseModule import PoseDetector
import cv2
detector = PoseDetector()#upBody=True
cap = cv2.VideoCapture(0)
while True:
_, img = cap.read()
img = detector.findPose(img, draw=False)
lmList, bboxInfo = detector.findPosition(img, draw=False)
gesture = ''
if bboxInfo:
angArmL = detector.findAngle(img, 13, 11, 23, draw=False)
angArmR = detector.findAngle(img, 14, 12, 24, draw=False)
crossDistL, img, _ = detector.findDistance(15, 12, img)
crossDistR, img, _ = detector.findDistance(16, 11, img)
if detector.angleCheck(angArmL, 90) and detector.angleCheck(angArmR, 270):
gesture = 'T Pose'
elif detector.angleCheck(angArmL, 170) and detector.angleCheck(angArmR, 180):
gesture = 'UP'
elif crossDistL:
if crossDistL < 70 and crossDistR < 70:
gesture = "Cross"
cv2.putText(img, gesture, (20, 50), cv2.FONT_HERSHEY_PLAIN, 3, (255, 0, 255), 3)
cv2.imshow("Image", img)
cv2.waitKey(1)
I get the following error:
Traceback (most recent call last):
File "Part2/GestureDetection.py", line 15, in <module>
angArmL = detector.findAngle(img, 13, 11, 23, draw=False)
File ".../cvzone/PoseModule.py", line 98, in findAngle
x1, y1 = self.lmList[p1][1:]
The code for the findAngle is
def findAngle(self, img, p1, p2, p3, draw=True):
"""
Finds angle between three points. Inputs index values of landmarks
instead of the actual points.
:param img: Image to draw output on.
:param p1: Point1 - Index of Landmark 1.
:param p2: Point2 - Index of Landmark 2.
:param p3: Point3 - Index of Landmark 3.
:param draw: Flag to draw the output on the image.
:return:
"""
# Get the landmarks
x1, y1 = self.lmList[p1][1:]
x2, y2 = self.lmList[p2][1:]
x3, y3 = self.lmList[p3][1:]
# Calculate the Angle
angle = math.degrees(math.atan2(y3 - y2, x3 - x2) -
math.atan2(y1 - y2, x1 - x2))
if angle < 0:
angle += 360
# Draw
if draw:
cv2.line(img, (x1, y1), (x2, y2), (255, 255, 255), 3)
cv2.line(img, (x3, y3), (x2, y2), (255, 255, 255), 3)
cv2.circle(img, (x1, y1), 10, (0, 0, 255), cv2.FILLED)
cv2.circle(img, (x1, y1), 15, (0, 0, 255), 2)
cv2.circle(img, (x2, y2), 10, (0, 0, 255), cv2.FILLED)
cv2.circle(img, (x2, y2), 15, (0, 0, 255), 2)
cv2.circle(img, (x3, y3), 10, (0, 0, 255), cv2.FILLED)
cv2.circle(img, (x3, y3), 15, (0, 0, 255), 2)
cv2.putText(img, str(int(angle)), (x2 - 50, y2 + 50),
cv2.FONT_HERSHEY_PLAIN, 2, (0, 0, 255), 2)
return angle
I see that lmlist was returning 4 values rather than the expected 3 values in the original code. To reduce the number of values, I specified the number of landmark values for x1,y1, by doing this:
Here are the changes I made to the following two functions in PoseModule.py