Opencv错误:(-215:声明失败)(mtype == CV_8U || mtype == CV_8S)&& _mask.sameSize(* psrc1)在函数'cv :: binary_op'

时间:2020-09-23 06:04:02

标签: python-3.x opencv roi

我正在尝试在通过级联检测到的脸上粘贴图片。

我在编写代码时遇到了这个错误。

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

起初我以为问题是掩码的大小和roi不相同,所以我在stackoverflow上引用了相同的problem,并尝试在我的代码上实现相同的值,然后将其更改为我的要求。我的目的是将所需的图片粘贴到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()

请指出我哪里出错了? 预先感谢。.

2 个答案:

答案 0 :(得分:2)

我必须运行它才能找到问题。实际上,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()

我希望这会有所帮助,否则请发表评论

答案 1 :(得分:0)

确保您的蒙版编码为uint8格式。

 mask = mask.astype("uint8")

并尝试打印您要进行“与”运算的2张图像的形状,如果它们匹配,则是编码问题,否则是形状问题

相关问题