Opencv error: (-215:Assertion failed) (mtype == CV_8U || mtype == CV_8S) && _mask.sameSize(*psrc1) in function 'cv::binary_op'

Opencv error: (-215:Assertion failed) (mtype == CV_8U || mtype == CV_8S) && _mask.sameSize(*psrc1) in function 'cv::binary_op'

我正在尝试将图片粘贴到通过 haarcascade 检测到的面部。

我在写代码的时候遇到了这个错误..

error: (-215:Assertion failed) (mtype == CV_8U || mtype == CV_8S) && _mask.sameSize(*psrc1) in function 'cv::binary_op'

起初我认为问题是掩码的大小和 roi 不一样,所以我在 Whosebug 上参考了相同的 并尝试在我的代码中实现相同的然后更改它根据我的要求。我的目的是将所需的图片粘贴到 roi 上(在我的情况下是人脸),但问题仍然存在。

这是代码..

import cv2
import numpy as np
import imutils

cap=cv2.VideoCapture(0)
classifier= cv2.CascadeClassifier('D:\Downloads\Computer-Vision-Tutorial-master\Computer-Vision-Tutorial-master\Haarcascades\haarcascade_frontalface_default.xml')

img=cv2.imread("D:\Downloads\anonymous_face_mask.jpg")
rows,cols,channels=img.shape
while(cap.isOpened()):
    img=cv2.imread("D:\Downloads\anonymous_face_mask.jpg")
    _,frame=cap.read()

    gray=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
    
    img_gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    ret,original_mask=cv2.threshold(img_gray,100,255,cv2.THRESH_BINARY_INV)
    original_mask_inv=cv2.bitwise_not(original_mask)
    #cv2.imshow("mask_inv",mask_inv)
    face=classifier.detectMultiScale(gray,1.4,5)

    
    for x,y,w,h in face:
        
        face_w = w
        face_h = h
        face_x1 = x
        face_x2 = face_x1 + face_h
        face_y1 = y
        face_y2 = face_y1 + face_h
        img_width=3*face_w
        img_height=int(img_width*rows/cols)

        img_x1=face_x2-int(face_w/2)-int(img_width/2)
        img_x2=face_x1+img_width
        img_y1=face_y2+5
        img_y2=img_y1+img_height

        if img_x1<0:
            img_x1=0
        if img_y1<0:
            img_y1=0
        if img_x2<cols:
            img_x2=cols
        if img_y2<rows:
            img_y2=rows

        imgwidth=img_x2-img_x1
        imgheight=img_y2-img_y1
        if imgwidth<0 or imgheight<0:
            continue

        image=cv2.resize(img,(imgwidth,imgheight),cv2.INTER_AREA)
        mask=cv2.resize(original_mask,(imgwidth,imgheight),cv2.INTER_AREA)
        mask_inv=cv2.resize(original_mask_inv,(imgwidth,imgheight),cv2.INTER_AREA)
        roi=frame[img_y1:img_y2,img_x1:img_x2]
        frame_bg=cv2.bitwise_and(roi,roi,mask=mask)
        img_fg=cv2.bitwise_and(image,image,mask=mask_inv)
        dst=cv2.add(frame_bg,img_fg)
        frame[img_y1:img_y2,img_x1:img_x2]=dst
        cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,255),2)
        cv2.imshow("framee",frame)
    
    k = cv2.waitKey(1) & 0xff
    if k == ord('q'):
        break
cap.release()
cv2.destroyAllWindows()

请指出我哪里错了? 提前致谢..

确保您的掩码编码为 uint8 格式。

 mask = mask.astype("uint8")

并尝试打印你的 2 张图像的形状 AND-ing,如果它们匹配则为编码问题,否则为形状问题

我必须 运行 它才能找到问题所在。实际上,roi 始终与掩码的大小不同......我认为它在设置变量 roi 时“越界”,numpy 只是放弃了它可以达到的程度。

很难确定哪里出了问题,因为代码(在我看来)一团糟。对于找到的每张脸,您可以计算几个宽度和高度,如果您只想用图像的脸替换找到的脸并创建图像的蒙版,则不需要这些宽度和高度。

尝试这样的事情:

import cv2
import numpy as np

# initialize camera, classifier and load the new image
cap=cv2.VideoCapture(0)
img=cv2.imread("image.png")
classifier= cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

# create masks to be used later
img_gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,original_mask=cv2.threshold(img_gray,100,255,cv2.THRESH_BINARY_INV)
original_mask_inv=cv2.bitwise_not(original_mask)

while(cap.isOpened()):
    # get image and find the face(s)
    _,frame=cap.read()
    gray=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
    face = classifier.detectMultiScale(gray,1.4,5)
    
    for x,y,w,h in face:
        # resize images and mask to size of the face
        newFace = cv2.resize(img,(w,h),cv2.INTER_AREA)
        mask = cv2.resize(original_mask,(w,h),cv2.INTER_AREA)
        mask_inv = cv2.resize(original_mask_inv,(w,h),cv2.INTER_AREA)

        # obtain the foreground of the image and the background of the camera frame
        roi=frame[y:y+h,x:x+w]
        frame_bg=cv2.bitwise_and(roi,roi,mask=mask)
        img_fg=cv2.bitwise_and(newFace,newFace,mask=mask_inv)

        # replace the face with the image data and draw a rectangle
        frame[y:y+h,x:x+w]= frame_bg + img_fg
        cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,255),2)
    
    # show image and wait parse key    
    cv2.imshow("framee",frame)
    k = cv2.waitKey(1) & 0xff
    if k == ord('q'):
        break
cap.release()
cv2.destroyAllWindows()

希望对您有所帮助,如果没有,请留下评论