0
votes

I'm creating a function (in Python) that expects/receives a single image of multiple human faces in it, and returns multiple smaller images (one image per human face). I am able to do a cv2.imshow inside the function and see the expected smaller images, but when I attempt a cv2.imshow from outside the function, it does not work (unable to see the smaller image, and get a TypeError instead). Would appreciate some guidance.

def stills(user_image):

    #sub_frames = []
    fqp_image_src = (user_image)
    raw_pic = cv2.imread(fqp_image_src)
    mpic = cv2.resize(raw_pic,(0,0), fx=0.30, fy=0.30)
    mpic_rgb = cv2.cvtColor(mpic, cv2.COLOR_BGR2RGB)
    face_boxes = haar_cascade_face.detectMultiScale(mpic_rgb, scaleFactor = 1.2, minNeighbors = 5)
    count = int(len(face_boxes))
    for i in range(count):
        face_box = face_boxes[i]
        final = cv2.rectangle(mpic, (face_box[0], face_box[1]), ((face_box[0]+face_box[2]),(face_box[1]+face_box[3])), (0,255,0),2)
        sub_frame = final[face_box[1]:(face_box[1]+face_box[3]), face_box[0]:(face_box[0]+face_box[2])]
        #sub_frames.append(sub_frame)
        cv2.imshow('frame', sub_frame)      # this works
        cv2.waitKey()
    return (sub_frame, final)

# calling the function
something = stills("abc.jpg")
cv2.imshow('frame',something)               # this does not work
cv2.waitKey()

TypeError: Expected cv::UMat for argument 'mat'

1
You function returns a tuple. Try this: something,_=stills('abc.jpg') - honglei
(silly me) thanks, @honglei - JubG

1 Answers

1
votes

This will do what you expected, just whit some simplification and with full file paths . One of the key erros was give detectMultiScale a colored image, the imput shuld have 1 dimension, with brigtness (gray scales).

In order to display a colored image with the faces in a box a copy of the image is needed to convert into gar scales and detect, giving coordenates to draw in the colored image.

import cv2
import os

# Take as a global the dir in witch is this file
PATH = os.path.dirname(os.path.abspath(__file__))

haar_cascade_face = cv2.CascadeClassifier(os.path.join(PATH, 'haarcascade_frontalface_alt.xml'))


def stills(user_image):
    image = os.path.join(PATH, user_image)
    image = cv2.imread(image)
    image = cv2.resize(image, (0, 0), fx=0.30, fy=0.30)

    gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    face_boxes = haar_cascade_face.detectMultiScale(gray_image, scaleFactor=1.073, minNeighbors=8)

    final = image  # make the funtion alwais give a image
    sub_frames = []

    # Check if there are faces
    if len(face_boxes) > 0:
        for x, y, w, h in face_boxes:
            final = cv2.rectangle(image, (x, y), (x+w, y+h), (0, 255, 0), 2)

            sub_frame = image[y:y+h, x:x+w]
            sub_frames.append([x, y, x+w, y+h])

            cv2.imshow('sub_frame', sub_frame)
            # cv2.waitKey() # No need to wait the user
    else:
        print('No faces found')

    return (sub_frames, final)


if __name__ == '__main__':
    fragments, final = stills("abc.jpg")
    cv2.imshow('frame', final)
    cv2.waitKey()