When I run this program, everything works fine if there is a detectable face in front of the camera. The second it lose the face, program crashes and gives an error like this:
Traceback (most recent call last):
File "C:\Users\oguzs\PycharmProiects\DroneDeneme\FaceTracking.py", line 77, in <module>
img, info = findFace(img)
TypeError: cannot unpack non-iterable NoneType object
Here is my face detection code:
def findFace(img):
faceCascade = cv2.CascadeClassifier("Resources/haarcascade_frontalface_default.xml")
imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = faceCascade.detectMultiScale(imgGray, scaleFactor=1.1, minNeighbors=3, flags=cv2.CASCADE_SCALE_IMAGE)
myFaceListC = []
myFaceListArea = []
for (x, y, w, h) in faces:
cv2.rectangle(img, (x, y), (x w, y h), (0, 0, 255), 2)
cx = x w // 2
cy = y h // 2
area = w * h
cv2.circle(img, (cx, cy), 5, (0, 255, 0), cv2.FILLED)
myFaceListC.append([cx, cy])
myFaceListArea.append(area)
if len(myFaceListArea) != 0:
i = myFaceListArea.index(max(myFaceListArea))
return img, [myFaceListC[i], myFaceListArea[i]]
else:
return img, [[0, 0], 0]
This is where i call findFace()
cap = cv2.VideoCapture(0)
while True:
_, img = cap.read()
img = cv2.resize(img, (w, h))
img, info = findFace(img)
cv2.imshow("Output", img)
cv2.waitKey(1)
I just started to learn openCV so any advice would be great :)
CodePudding user response:
The error says that findFace
returned nothing.
If you look carefully, you'll see that indeed findFace
may not return anything if the loop loops over an empty list. That happens when no faces were found. That situation should have been expected. Not all pictures contain faces.
Programming requires figuring out the meaning and causes of error messages. How you fix that is up to you. Perhaps check for the condition (list is empty), or simply return a default value after the loop, i.e. when there was no return issued in the loop.
CodePudding user response:
take a look at the code below. BTW i recommend you to use newer and better one
import numpy as np
import cv2 as cv
def findFace(img, faceCascade):
imgGray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
faces = faceCascade.detectMultiScale(imgGray, scaleFactor=1.1, minNeighbors=3, flags=cv.CASCADE_SCALE_IMAGE)
myFaceListC = []
myFaceListArea = []
if len(faces) == 0:
return img, [[0, 0], 0]
for (x, y, w, h) in faces:
cv.rectangle(img, (x, y), (x w, y h), (0, 0, 255), 2)
cx = x w // 2
cy = y h // 2
area = w * h
cv.circle(img, (cx, cy), 5, (0, 255, 0), cv.FILLED)
myFaceListC.append([cx, cy])
myFaceListArea.append(area)
if len(myFaceListArea) != 0:
i = myFaceListArea.index(max(myFaceListArea))
return img, [myFaceListC[i], myFaceListArea[i]]
else:
return img, [[0, 0], 0]
def main():
cascade = cv.CascadeClassifier(cv.samples.findFile("haarcascades/haarcascade_frontalface_alt.xml"))
cam = cv.VideoCapture(0)
while True:
_ret, img = cam.read()
img, info = findFace(img,cascade)
cv.imshow('facedetect', img)
if cv.waitKey(5) == 27:
break
print('Done')
if __name__ == '__main__':
main()
cv.destroyAllWindows()