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.
Related
import cv2
import numpy as np
from math import ceil
import os
dst = "C:\OpencvPython\frames\slide" # Images destination
images = os.listdir(dst) # Get their names in a list
length = len(images)
result = np.zeros((360,360,3), np.uint8) # Image window
of size (360, 360)
i = 1
a = 1.0 # alpha
b = 0.0 # beta
img = cv2.imread(dst + images[i])
img = cv2.resize(img, (360, 360))
# Slide Show Loop
while(True):
if(ceil(a)==0):
a = 1.0
b = 0.0
i = (i+1)%length # Getting new image from directory
img = cv2.imread(dst + images[i])
img = cv2.resize(img, (360, 360))
a -= 0.01
b += 0.01
# Image Transition from one to another
result = cv2.addWeighted(result, a, img, b, 0)
cv2.imshow("Slide Show", result)
key = cv2.waitKey(1) & 0xff
if key==ord('q'):
break
cv2.destroyAllWindows()
[ WARN:0#0.007] global D:\a\opencv-python\opencv-python\opencv\modules\imgcodecs\src\loadsave.cpp (239) cv::findDecoder imread_('C:/OpencvPython/frames/slidedownload (2).jpg'): can't open/read file: check file path/integrity
cv2.error: OpenCV(4.6.0) D:\a\opencv-python\opencv-python\opencv\modules\imgproc\src\resize.cpp:4052: error: (-215:Assertion failed) !ssize.empty() in function 'cv::resize'
The issue is with the path, you can replace img = cv2.imread(dst + images[i]) with
img = cv2.imread(os.path.join(dst, images[i]))
Using + operator will directly add 2nd sting to the base path, for example if dst = "C:\OpencvPython\frames\slide" and images[i] = "img1.png" then dst + images[i] would become "C:\OpencvPython\frames\slideimg1.png" hence leading to file not found error while os.path.join will generate correct path.
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.
I am a beginner to programming and i am trying to model face recognition attendance programming in python,and i am not able to get the face distance list of webcam. the webcam light would come on but i won't even see images.
i dont know what i am doing wrong.
here is the codes
import cv2
import numpy as np
import face_recognition
import os
path = 'ImagesAttendance'
images = []
staffNames = []
myList = os.listdir(path)
print(myList)
for st in myList:
curImg = cv2.imread(f'{path}/{st}')
images.append(curImg)
staffNames.append(os.path.splitext(st)[0])
print(staffNames)
#encoding functions finding begins automatically
def findEncodings(images):
encodeList = []
for img in images:
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
#finding encodings
encode = face_recognition.face_encodings(img)
encodeList.append(encode)
return encodeList
encodeListKnown = findEncodings(images)
#printing the number or length of pictures in the folder
#print(len(encodeListKnown))
print('Encoding Complete')
#Initializing webcam to match images in the folder
cap = cv2.VideoCapture(0)
while True:
success, img = cap.read()
#because its real time capture, we wld reduce the size of image to speed up the process
imgS = cv2.resize(img,(0,0),None,0.25,0.25)
#realtime image size has been divided by 4 using 0.25
imgS = cv2.cvtColor(imgS, cv2.COLOR_BGR2RGB)
facesCurFrame = face_recognition.face_locations(imgS)
encodeCurFrame = face_recognition.face_encodings(imgS,facesCurFrame)
#finding matches
for encodeFace,faceLoc in zip(encodeCurFrame,facesCurFrame):
matches = face_recognition.compare_faces(encodeListKnown,encodeFace)
faceDis = face_recognition.face_distance(encodeListKnown,encodeFace)
print(faceDis)
here are the errors
C:\Users\AAA\PycharmProjects\FaceRecognitionProject\venv\Scripts\python.exe C:/Users/AAA/PycharmProjects/FaceRecognitionProject/AttendanceProject.py
['2LT Chinonso.jpg', 'Hadizah Abdul.jpg', 'Nosa Igiemwin.jpg']
['2LT Chinonso', 'Hadizah Abdul', 'Nosa Igiemwin']
Encoding Complete
C:\Users\AAA\PycharmProjects\FaceRecognitionProject\venv\lib\site-packages\face_recognition\api.py:75: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray
return np.linalg.norm(face_encodings - face_to_compare, axis=1)
Traceback (most recent call last):
File "C:/Users/AAA/PycharmProjects/FaceRecognitionProject/AttendanceProject.py", line 46, in <module>
matches = face_recognition.compare_faces(encodeListKnown,encodeFace)
File "C:\Users\AAA\PycharmProjects\FaceRecognitionProject\venv\lib\site-packages\face_recognition\api.py", line 226, in compare_faces
return list(face_distance(known_face_encodings, face_encoding_to_check) <= tolerance)
File "C:\Users\AAA\PycharmProjects\FaceRecognitionProject\venv\lib\site-packages\face_recognition\api.py", line 75, in face_distance
return np.linalg.norm(face_encodings - face_to_compare, axis=1)
ValueError: operands could not be broadcast together with shapes (3,) (128,)
[ WARN:0] global C:\projects\opencv-python\opencv\modules\videoio\src\cap_msmf.cpp (674) SourceReaderCB::~SourceReaderCB terminating async callback
Things i did to fix errors, now its working perfectly in my pc
Inside def findingEncodings(images) check 4th line i.e. encode = face_recognition.face_encodings(img) replace it with encode = face_recognition.face_encodings(img)[0]
I wrote the below mentioned loop(last four lines) again as it was showing
unreachable as an error might b due to improper indentation
for encodeFace,faceLoc in zip(encodeCurFrame,facesCurFrame):
matches = face_recognition.compare_faces(encodeListKnown,encodeFace)
faceDis = face_recognition.face_distance(encodeListKnown,encodeFace)
print(faceDis)
I completed your code as well you can use this for comparison
import cv2
import numpy as np
import face_recognition
import os
path = 'ImagesAttendance'
images = []
staffNames = []
myList = os.listdir(path)
print(myList)
for st in myList:
curImg = cv2.imread(f'{path}/{st}')
images.append(curImg)
staffNames.append(os.path.splitext(st)[0])
print(staffNames)
def findEncodings(images):
encodeList = []
for img in images:
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
#finding encodings
encode = face_recognition.face_encodings(img)[0]
encodeList.append(encode)
return encodeList
encodeListKnown = findEncodings(images)
cap = cv2.VideoCapture(0)
while True:
success, img = cap.read()
#because its real time capture, we wld reduce the size of image to speed up the process
imgS = cv2.resize(img,(0,0),None,0.25,0.25)
#realtime image size has been divided by 4 using 0.25
imgS = cv2.cvtColor(imgS, cv2.COLOR_BGR2RGB)
facesCurFrame = face_recognition.face_locations(imgS)
encodeCurFrame = face_recognition.face_encodings(imgS,facesCurFrame)
#finding matches
for encodeFace,faceLoc in zip(encodeCurFrame, facesCurFrame):
matches =face_recognition.compare_faces(encodeListKnown,encodeFace)
faceDis = face_recognition.face_distance(encodeListKnown,encodeFace)
print(faceDis)
matchIndex = np.argmin(faceDis)
print('matchIndex', matchIndex)
if matches[matchIndex]:
name = staffNames[matchIndex].upper()
print(name)
y1, x2, y2, x1 = faceLoc
y1, x2, y2, x1 = y1 * 4, x2 * 4, y2 * 4, x1 * 4
cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2)
cv2.rectangle(img, (x1, y2 - 35), (x2, y2), (0, 0, 0), cv2.FILLED)
cv2.putText(img, name, (x1 + 6, y2 - 6), cv2.FONT_HERSHEY_COMPLEX, 1, (0, 0, 255), 2)
cv2.imshow('Webcam', img)
#press'esc' to close program
if cv2.waitKey(1) == 27:
break
#release camera
cap.release()
cv2.destroyAllWindows()
hello o try to combine detect.multiscale code wit calc.hist code. i try to run this program but i can't access 'w' in for in loop.??
import cv2
import numpy as np
from matplotlib import pyplot as plt
import time
import sys
import serial
#execfile("/home/arizal/Documents/Sorting Jeruk/motor1.py")
#ser = serial.Serial('/dev/ttyACM0', 9600)
#Cascade jeruk
jeruk_cascade = cv2.CascadeClassifier('cascade.xml')
camera = cv2.VideoCapture(1)
base1 = cv2.imread('base11.jpg')
base2 = cv2.imread('base22.jpg')
base3 = cv2.imread('base33.jpg')
#Set hist parameters
hist_height = 64
hist_width = 256
nbins = 32
bin_width = hist_width/nbins
hrange = [0,180]
srange = [0,256]
ranges = hrange+srange # ranges = [0,180,0,256]
#Create an empty image for the histogram
e = np.zeros((hist_height,hist_width))
#print ("h : ",h)
#print type(h)
#x=1
this is for detect.multiscale loop
while 1:
grabbed, img = camera.read()
cam = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
if not grabbed:
"Camera could not be started."
break
# add this
# image, reject levels level weights.
jeruks = jeruk_cascade.detectMultiScale(cam, 1.03, 5)
this for cascade for in loop, for give rectangle mark on the object
# add this
for (x,y,w,h) in jeruks:
cv2.rectangle(img,(x,y),(x+w,y+h),(17,126,234),2)
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(img,'Jeruk',(x+w,y+h), font, 1, (17,126,234), 2, cv2.LINE_AA) #---write the text
roi_gray = cam[y:y+h, x:x+w]
roi_color = img[y:y+h, x:x+w]
and calc the histogram when the object detected
if w > 250 :
print ('w', w)
histcam = cv2.calcHist([cam], [0], None, [nbins], [0,256])
cv2.normalize(histcam,histcam, hist_height, cv2.NORM_MINMAX)
hist=np.int32(np.around(histcam))
but i got this error :
Traceback (most recent call last):
File "/home/arizal/Documents/Sorting Jeruk/doalcoba.py", line 65, in <module>
if w > 250 :
NameError: name 'w' is not defined
anyone can help me ?
I think the problem that your code has is of indentation. In the code -
for (x,y,w,h) in jeruks:
....
And
if w > 250 :
....
Are on same level of indentation. (x,y,w,h) are only available for the for loop, not outside of it. Fix you indentation -
for (x,y,w,h) in jeruks:
....
if w > 250 :
print ('w', w)
Let me know if that works
i would like to do some program by capture image from webcam, then cropped it. after crop, i do some image processing and from the process it will run my robots. Here the full program:
import cv2
from cv2 import *
import numpy as np
import pylab
import pymorph
import mahotas
from matplotlib import pyplot
from PIL import Image
# initialize the camera
cam = VideoCapture(0) # 0 -> index of camera
s, img = cam.read()
# frame captured without any errors
if s:
imwrite("img.jpg",img) #save image
#Crop Image
imageFile = "img.jpg"
im1 = Image.open(imageFile)
def imgCrop(im):
box = (0, 199, 640, 200)
region = im.crop(box)
region.save('crop.jpg')
cImg = imgCrop(im1)
#thresholding
def greyImg(im):
gray = im.convert('L')
bw = gray.point(lambda x: 0 if x<128 else 255, '1')
bw.save("bw.jpg")
tImg = greyImg(cImg )
#direction
def find_centroid(im, rez):
width, height = im.size
XX, YY, count = 0, 0, 0
for x in xrange(0, width, rez):
for y in xrange(0, height, rez):
if im.getpixel((x, y)) == 255:
XX += x
YY += y
count += 1
return XX/count, YY/count
print find_centroid(tImg, 1)
def robo_direct():
cen = find_centroid(im, 1)
diff = cen[0] - 320
if diff > 10:
print 'right'
if diff < -10:
print 'left'
else:
print 'straight'
print robo_direct()
The error was come out like this:
File "compile.py", line 32, in greyImg
gray = im.convert('L')
AttributeError: 'NoneType' object has no attribute 'convert'
That is because im is a None object.
Try again the code with:
print im is None
And you'll see. I don't know about threshold, but obviously you are creating the im object the wrong way.
Your function imgCrop(im1) has no return statement and as such returns None. And then your greyImg(im) function also has no return statement and also will return None.
To fix that add return statements to both functions that for the first return region and the second return bw.
Also your robo_direct() function should return and not print the direction so that the call to it in the statement print robo_direct() would print the direction.