error: (-215:Assertion failed) !image.empty() in function 'cv::imencode'

created at 07-31-2021 views: 137

problem

Python cv2 extracts the face and then crops it, and an error is reported when the cropped face photo is base64. How can I solve it?

import cv2
import base64
def get_face_img(img):
    image = cv2.imread(img)
    face_model = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
    gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
    faces = face_model.detectMultiScale(gray, 1.1, 3, 0, (100, 100))
    for (x, y, w, h) in faces:
        # Capture the specified position of the face
        image = image[y - 100:y + h + 100, x - 100:x + h + 100]
    retval, buffer = cv2.imencode('.jpg', image)
    image_code = base64.b64encode(buffer)
    return str(image_code)[2:-1]
if __name__ == '__main__':
    get_face_img(img)

The above code always fails when running, and the error is reported as follows:

cv2.error: OpenCV(4.5.2) C:\Users\runneradmin\AppData\Local\Temp\pip-req-build-m8us58q4\opencv\modules\imgcodecs\src\loadsave.cpp:896: error: (-215:Assertion failed) !image.empty() in function 'cv::imencode'

When I remove the cropping code image = image[y-100:y + h + 100, x-100:x + h + 100], or convert base64 before cropping, there is no problem, so I guess it is The format after cropping does not use the imencode function.

What should I do to convert the cropped face to base64? I don't want to read the file after writing it out, I want to encode it directly.

solution

It can be achieved with the io module, the code is as follows:

import cv2
import base64
import io
def get_face_img(img):
    image = cv2.imread(img)
    face_model = cv2.CascadeClassifier(
        'D:\\Program Files\\Python37\\Lib\\site-packages\\cv2\\data\\haarcascade_frontalface_default.xml') # Replace with your own file path
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    faces = face_model.detectMultiScale(gray, 1.1, 3, 0, (100, 100))
    for (x, y, w, h) in faces:
        # Capture the specified position of the face
        image = image[y - 100:y + h + 100, x - 100:x + h + 100]
    #retval, buffer = cv2.imencode('.jpg', image)
    buffer=io.BytesIO(image)
    image_code = base64.b64encode(str(buffer).encode('utf-8'))
    return str(image_code)[2:-1]

if __name__ == '__main__':
    print(get_face_img('F:/images/screenshot/1.jpg'))

#output:
PF9pby5CeXRlc0lPIG9iamVjdCBhdCAweDAwMDAwMjgxOTMzNThGNDg+
created at:07-31-2021
edited at: 07-31-2021: