Python, cvzone - why do i get this ValueError? - python

I am trying to zoom into a picture with usage of two hands (gesture controled image zoom), but when trying to use two hands I get this error but I don't know why. When making my program I followed this tutorial: https://www.youtube.com/watch?v=VPaFV3QBsEw&t=675s. It's strange because the program worked for him.
This is the error I get:
hands, img = detector.findHands(img)
ValueError: too many values to unpack (expected 2)
This is my code:
import cv2
from cvzone.HandTrackingModule import HandDetector
cap = cv2.VideoCapture(0)
cap.set(3, 1280)
cap.set(4, 720)
detector = HandDetector(detectionCon=0.7)
startDist = None
scale = 0
cx, cy = 500,500
while True:
success, img = cap.read()
hands, img = detector.findHands(img)
img1 = cv2.imread("kung_fu_panda.png")
if len(hands) == 2:
if detector.fingersUp(hands[0]) == [1, 1, 0, 0, 0] and \
detector.fingersUp(hands[1]) == [1, 1, 0, 0, 0]:
lmList1 = hands[0]["lmList"]
lmList2 = hands[1]["lmList"]
# point 8 is the tip of the index finger
if startDist is None:
length, info, img = detector.findDistance(hands[0]["center"], hands[1]["center"], img)
startDist = length
length, info, img = detector.findDistance(hands[0]["center"], hands[1]["center"], img)
scale = int((length - startDist) // 2)
cx, cy = info[4:]
print(scale)
else:
startDist = None
try:
h1, w1, _= img1.shape
newH, newW = ((h1+scale)//2)*2, ((w1+scale)//2)*2
img1 = cv2.resize(img1, (newW,newH))
img[cy-newH//2:cy+ newH//2, cx-newW//2:cx+ newW//2] = img1
except:
pass
cv2.imshow("Image", img)
cv2.waitKey(1)

cvzone library keeps updating their library every time. As you can see at the beginning of the video, when he imports the cvzone package he uses cvzone version 1.5.0.
I tried your code with other versions and got an error similar to yours but with version 1.5.0 your code worked great.
you can use my answer here to change the version of your cvzone library in your project to 1.5.0.

Related

Face detection using retinaface code error

I am new to python. Currently I am working on a project to detect face using retinaface and opencv. I am using the retinafacewrapper from the retinaface git. Below is my code and I tried to run the code on an .mov video file and i got this error TypeError: detect_face() missing 1 required positional argument: 'img'. I need some help on this. Thank you.
from retinaface import RetinaFace
import cv2
def build_model():
from retinaface import RetinaFace
face_detector = RetinaFace.build_model()
return face_detector
def detect_face(face_detector, img , align = True):
from retinaface import RetinaFace
from retinaface.commons import postprocess
#---------------------------------
resp = []
# The BGR2RGB conversion will be done in the preprocessing step of retinaface.
# img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) #retinaface expects RGB but OpenCV read BGR
"""
face = None
img_region = [0, 0, img.shape[0], img.shape[1]] #Really?
faces = RetinaFace.extract_faces(img_rgb, model = face_detector, align = align)
if len(faces) > 0:
face = faces[0][:, :, ::-1]
return face, img_region
"""
#--------------------------
obj = RetinaFace.detect_faces(img, model = face_detector, threshold = 0.9)
if type(obj) == dict:
for key in obj:
identity = obj[key]
facial_area = identity["facial_area"]
y = facial_area[1]
h = facial_area[3] - y
x = facial_area[0]
w = facial_area[2] - x
img_region = [x, y, w, h]
#detected_face = img[int(y):int(y+h), int(x):int(x+w)] #opencv
detected_face = img[facial_area[1]: facial_area[3], facial_area[0]: facial_area[2]]
if align:
landmarks = identity["landmarks"]
left_eye = landmarks["left_eye"]
right_eye = landmarks["right_eye"]
nose = landmarks["nose"]
#mouth_right = landmarks["mouth_right"]
#mouth_left = landmarks["mouth_left"]
detected_face = postprocess.alignment_procedure(detected_face, right_eye, left_eye, nose)
resp.append((detected_face, img_region))
return resp
path = "database/images/org_3fc67bdc820dc3c1_1647514190000.mov"
cap = cv2.VideoCapture(path)
# Video
while True:
ret, img = cap.read()
img = cv2.resize(img,(640,360))
img = detect_face(img)
cv2.imshow('Face detector', img)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
Download/Clone this repo and run pose_detection_retinaface.py file. This is the complete code for using retinaface for face detection.

OpenCV python: ValueError: too many values to unpack , img

I am writing an opencv project which is a fingers distance finder and making an image(its complicated to explain but I try my best.
When i run the script, I get this error 👇
Traceback (most recent call last):
File "D:/P4rakash_Python_Projects/Python Projects/adding things/python.py", line 16, in <module>
hands, img2 = detector.findHands(img)
ValueError: too many values to unpack (expected 2)
[ WARN:0] global D:\a\opencv-python\opencv-python\opencv\modules\videoio\src\cap_msmf.cpp (438) `anonymous-namespace'::SourceReaderCB::~SourceReaderCB terminating async callback
I dont understand this error if someone fix this and answer me I can get the hang off it.
this is the full code
from cv2 import cv2
from cvzone.HandTrackingModule import HandDetector
cap = cv2.VideoCapture(0)
cap.set(3, 1280)
cap.set(4, 720)
detector = HandDetector(detectionCon=0.8)
startDist = None
scale = 0.
cx, cy = 500, 500
while True:
Success, img = cap.read()
hands, img = detector.findHands(img)
img1 = cv2.imread("kisspng-computer-icons-code-coupon-font-computer-coding-5b4cbf4c6bb012.9457556415317563644411.png")
if len(hands) == 2:
# print(detector.fingersUp(hands[0]), detector.fingersUp(hands[1]))
if detector.fingersUp(hands[0]) == [1, 1, 0, 0, 0] and detector.fingersUp(hands[1]) == [1, 1, 0, 0, 0]:
# print("ZOOMMING GESTUREs")
lmList1 = hands[0]["lmList"]
lmList2 = hands[1]["lmList"]
# Point 8 is teh tip of the finger
if startDist is None:
length, info, img = detector.findDistance(lmList1[8], lmList2[8], img)
startDist = length
length, info, img = detector.findDistance(lmList1[8], lmList2[8], img)
scale = int((length - startDist) // 2)
cx, cy = info[4:]
# print(scale)
else:
startDist = None
try:
h1, w1, _ = img1.shape
newH, newW = ((h1 + scale) // 2) * 2, ((w1 + scale) // 2) * 2
img1 = cv2.resize(img1, (newW, newH))
img[cy - newH // 2:cy + newH // 2, cx - newW // 2:cx + newW // 2] = img1
except:
pass
img = cv2.flip(img, 1)
cv2.imshow("Hollow.os", img)
cv2.waitKey(1)
when I do this code there is a warning coming called Unexpected argument
help is mostly what I want now
That's because findhands returns only 1 value, not 2.
The right syntax would be
img2 = detector.findHands(img)
Turns out I been using a 1.4.1 cvzone library to make the findposition to work then I changed it back. And this works just fine
Change your cvzone library version to 1.5.6 so the code will work.
please check your cvzone version because if this error comes for you then change it to the latest version it works fine now
cvzone version needs to be upgraded. The following steps can be followed,
check the current cvzone version
pip freeze
Upgrade the version
pip install cvzone -U
For my case, previous=> cvzone==1.4.1 then
Successfully uninstalled cvzone-1.4.1
Successfully installed cvzone-1.5.6
If we print for example lmList1[8]:
print(lmList1[8]) # It will give us 3 values not 2
In the findDistance:
x1, y1 = p1 # This is wrong
x1, y1, z1 = p # It should be like this
x1, y1, z1 = p1
x2, y2, z2 = p2
Another solution, is you can keep the findDistance as it is and change the line of code into:
length, info, img = detector.findDistance(lmList1[8][:2], lmList2[8][:2], img)
This will take only the first 2 values x1, y1 and x2,y2.

a am getting an OpenCV Error in python... and my code is given below?? Please resolve it fast.Thnks in advance

plese solve this guys,
when i am running this code it is giving me an unaccepted error =
""OpenCV Error: Assertion failed (ssize.width > 0 && ssize.height > 0) in resize, file /build/opencv-L2vuMj/opencv-3.2.0+dfsg/modules/imgproc/src/imgwarp.cpp, line 3492""
Code:
import numpy as np
import dlib
import cv2
import face_recognition
import os
path = 'images'
image = []
classNames = []
myList = os.listdir(path)
for cl in myList:
curImg = cv2.imread(f'{path}/{cl}')
image.append(curImg)
classNames.append(os.path.splitext(cl)[0])
# print(classNames)
def findEncodings(image):
encodeList = []
for img in image:
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
encode = face_recognition.face_encodings(img)[0]
encodeList.append(encode)
return encodeList
encodeListKnown = findEncodings(image)
print(len("Encoding Complete"))
cap = cv2.VideoCapture()
# print(cap)
while True:
success, img = cap.read()
imgS = cv2.resize(img, (0,0), None, 0.25, 0.25)
imgS = cv2.cvtColor(imgS, cv2.COLOR_BGR2RGB)
facesCurFrames = face_recognition.face_locations(imgS)
encodesCurFrames = face_recognition.face_encodings(imgS,
facesCurFrames)
for encodeFace,faceLoc in zip(encodesCurFrames,
facesCurFrames):
matches =
face_recognition.compare_faces(encodeListKnown,encodeFace)
faceDis =
face_recognition.face_distance(encodeListKnown,encodeFace)
print(faceDis)
(0, 0) is not a valid (width, height) tuple for resizing an image. It looks like you wanted to resize the image by scaling, in which case you can pass None instead of the size tuple:
imgS = cv2.resize(img, None, fx=0.25, fy=0.25)
will scale the image by 0.25 in both dimensions.

OpenCv imread error while trying it in real-time

code:
import face_recognition as fr
import os
import cv2
import face_recognition
import numpy as np
from time import sleep
def get_encoded_faces():
encoded = {}
for dirpath, dnames, fname in os.walk("./faces"):
for f in fname:
if f.endswith(".jpg") or f.endswith(".png"):
face = fr.load_image_file("faces/" + f)
encoding = fr.face_encodings(face)[0]
encoded[f.split(".")[0]] = encoding
return encoded, fname
def unknown_image_encoded(img):
face = fr.load_image_file("faces/" + img)
encoding = fr.face_encodings(face)[0]
return encoding
def classify_face(im):
faces, fname = get_encoded_faces()
faces_encoded = list(faces.values())
known_face_names = list(faces.keys())
img = cv2.imread(im, 1)
face_locations = face_recognition.face_locations(img)
unknown_face_encodings = face_recognition.face_encodings(img, face_locations)
face_names = []
for face_encoding in unknown_face_encodings:
matches = face_recognition.compare_faces(faces_encoded, face_encoding)
name = "Unknown"
face_distances = face_recognition.face_distance(faces_encoded, face_encoding)
best_match_index = np.argmin(face_distances)
if matches[best_match_index]:
name = known_face_names[best_match_index]
face_names.append(name)
for (top, right, bottom, left), name in zip(face_locations, face_names):
cv2.rectangle(img, (left-20, top-20), (right+20, bottom+20), (255, 0, 0), 2)
cv2.rectangle(img, (left-20, bottom -15), (right+20, bottom+20), (255, 0, 0), cv2.FILLED)
font = cv2.FONT_HERSHEY_DUPLEX
cv2.putText(img, name, (left -20, bottom + 15), font, 1.0, (255, 255, 255), 2)
return face_names, fname
cap = cv2.VideoCapture(0)
while True:
ret, image = cap.read()
recog, fname = classify_face(image)
print(recog)
cv2.imshow(fname, image)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
video.release()
cv2.destroyAllWindows()
Error:
Traceback (most recent call last):
File "face.py", line 70, in <module>
recog, fname = classify_face(image)
File "face.py", line 37, in classify_face
img = cv2.imread(im, 1)
SystemError: <built-in function imread> returned NULL without setting an error
[ WARN:0] global C:\Users\appveyor\AppData\Local\Temp\1\pip-req-build-wbmte9m7\opencv\modules\videoio\src\cap_msmf.cpp (435) `anonymous-namespace'::SourceReaderCB::~SourceReaderCB terminating async callback
The code works properly while using an image but now when I tried using it with video/real-time its throwing this error
I guess it requires the path instead of the image that is passed on to it, is there any other work around
I am trying to recognize faces in real time and the major issue with it was detecting unknown faces so when I started coding for real time I got this error.
The code and the error message don't agree. Are you running an older version of the code?
Error message:
File "face.py", line 37, in classify_face
img = cv2.imread(im, 1)
Code:
img = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
For debugging it may be helpful to display the received frame from the camera with code like the following:
ret, image = cap.read()
grey = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cv2.imshow('frame', grey)
cv2.waitKey()
cv2.imread(im, 1) requires im to be the filename (datatype: string) of the image that you want to read.
Using cap = cv2.VideoCapture(0), you don't need to read images from files anymore, since the image that you want to classify is returned as an array from cap.read().
To fix your code for using cv2.VideoCapture, remove img = cv2.imread(im, 1) from your classify_face method and change the method definition to
def classify_face(img):
instead of
def classify_face(im):
Note, that the 0 option of cv2.VideoCapture refers to reading the live video stream from a camera with index 0.

Getting this error "ValueError: not enough values to unpack (expected 3, got 2)" while compiling opencv contours

I'm going to run an openCV people counting tutorial code. tutorials are available here. https://fedemejia.com/?p=68
but while i'm running the following code by cmd. I'm getting this error
File "VideoCapture.py", line 25, in
_, contours0, hierarchy = cv2.findContours(mask,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
ValueError: not enough values to unpack (expected 3, got 2)
my python version is 3.6.8
opencv 4.0.0
import numpy as np
import cv2
cap = cv2.VideoCapture('peopleCounter.avi') #Open video file
fgbg = cv2.createBackgroundSubtractorMOG2(detectShadows = True) #Create the background substractor
kernelOp = np.ones((3,3),np.uint8)
kernelCl = np.ones((11,11),np.uint8)
areaTH = 500
while(cap.isOpened()):
ret, frame = cap.read() #read a frame
fgmask = fgbg.apply(frame) #Use the substractor
try:
ret,imBin= cv2.threshold(fgmask,200,255,cv2.THRESH_BINARY)
#Opening (erode->dilate) para quitar ruido.
mask = cv2.morphologyEx(imBin, cv2.MORPH_OPEN, kernelOp)
#Closing (dilate -> erode) para juntar regiones blancas.
mask = cv2.morphologyEx(mask , cv2.MORPH_CLOSE, kernelCl)
except:
#if there are no more frames to show...
print('EOF')
break
_, contours0, hierarchy = cv2.findContours(mask,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
for cnt in contours0:
cv2.drawContours(frame, cnt, -1, (0,255,0), 3, 8)
area = cv2.contourArea(cnt)
print area
if area > areaTH:
#################
# TRACKING #
#################
M = cv2.moments(cnt)
cx = int(M['m10']/M['m00'])
cy = int(M['m01']/M['m00'])
x,y,w,h = cv2.boundingRect(cnt)
cv2.circle(frame,(cx,cy), 5, (0,0,255), -1)
img = cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,0),2)
cv2.imshow('Frame',frame)
#Abort and exit with 'Q' or ESC
k = cv2.waitKey(30) & 0xff
if k == 27:
break
cap.release() #release video file
cv2.destroyAllWindows() #close all openCV windows
It was supposed to give the result describe in the tutorial.
In OpenCV 4.0, cv2.findContour() returns only 2 values. So it should be contours0, hierarchy = cv2.findContours(mask,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE). See here https://docs.opencv.org/master/df/d0d/tutorial_find_contours.html

Categories

Resources