Python OpenCV face detection code sometimes raises `'tuple' object has no attribute 'shape'` -


i trying build face detection application in python using opencv.
please see below code snippets:

 # loading haar cascade classifier cascadepath = "/home/work/haarcascade_frontalface_default.xml" facecascade = cv2.cascadeclassifier(cascadepath)  # dictionary store image name & number of face detected in num_faces_dict = {}  # iterate on image directory.  # read image, convert in grayscale, detect faces using haarcascade classifier # draw rectangle on image      img_fname in os.listdir('/home/work/images/caltech_face_dataset/'):     img_path = '/home/work/images/caltech_face_dataset/' + img_fname     im = imread(img_path)     gray = cv2.cvtcolor(im, cv2.color_rgb2gray)     faces = facecascade.detectmultiscale(im)     print "number of faces found in-> ", img_fname, " ", faces.shape[0]     num_faces_dict[img_fname] = faces.shape[0]     (x,y,w,h) in faces:         cv2.rectangle(im, (x,y), (x+w,y+h), (255,255,255), 3)     rect_img_path = '/home/work/face_detected/rect_' + img_fname     cv2.imwrite(rect_img_path,im) 

this code works fine of images of them throws error -

attributeerror: 'tuple' object has no attribute 'shape' enter image description here

i error in line print number of faces. appreciated.

the cause of problem detectmultiscale returns empty tuple () when there's no matches, numpy.ndarray when there matches.

>>> faces = classifier.detectmultiscale(cv2.imread('face.jpg')) >>> print(type(faces), faces) <class 'numpy.ndarray'> [[ 30 150  40  40]]   >>> faces = classifier.detectmultiscale(cv2.imread('wall.jpg')) >>> print(type(faces), faces) <class 'tuple'> () 

you might expect negative result ndarray of shape (0,4), that's not case.

this behaviour , reasoning behind not explained in documentation, instead indicates return value should "objects".

opencv has lot of warts this, , cryptic error messages doesn't help. 1 way deal add logging statements or asserts code check type expected.

it's useful explore how library works in repl such ipython. used in rahul k p's answer.

in case, can solve problem not using shape. python has many data types sequences or collections, example tuple, list , dict. of these implement len() built-in function , can loop on them using for x in y. in contrast shape property of numpy.ndarray, , not found in of built-in python data types.

your code should work if rewrite use len(faces) instead of faces.shape[0], since former works both tuple , ndarray.

for img_fname in os.listdir('/home/work/images/caltech_face_dataset/'):     img_path = '/home/work/images/caltech_face_dataset/' + img_fname     im = imread(img_path)     gray = cv2.cvtcolor(im, cv2.color_rgb2gray)     faces = facecascade.detectmultiscale(gray)  # use grayscale image     print "number of faces found in-> {} {}".format(         img_fname, len(faces))  # len() works both tuple , ndarray     num_faces_dict[img_fname] = len(faces)     # when faces (), following loop never run, it's safe.     (x,y,w,h) in faces:          cv2.rectangle(im, (x,y), (x+w,y+h), (255,255,255), 3)     rect_img_path = '/home/work/face_detected/rect_' + img_fname     cv2.imwrite(rect_img_path,im) 

Comments

Popular posts from this blog

wordpress - (T_ENDFOREACH) php error -

Export Excel workseet into txt file using vba - (text and numbers with formulas) -

Using django-mptt to get only the categories that have items -