Home > Software engineering >  Python OpenCV Face Detection method returns NoneType object when not detecting any face
Python OpenCV Face Detection method returns NoneType object when not detecting any face

Time:03-13

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:

TypeError: cannot unpack non-iterable NoneType object

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()
  • Related