OpenCV Python错误:错误:(-215)(mtype == CV_8U || mtype == CV_8S)&&函数cv :: binary_op中的_mask.sameSize(* psrc1)

时间:2017-05-17 08:07:20

标签: python opencv

我正在尝试使用OpenCV Python在我自己的直播视频流上叠加衬衫图像。三天以来我一直坚持这个特殊的错误:

错误:(-215)(mtype == CV_8U || mtype == CV_8S)&&函数cv :: binary_op

中的_mask.sameSize(* psrc1)

此错误发生在此行:

roi_bg = cv2.bitwise_and(roi,roi,mask = mask_inv)

我的代码:

import cv2                              # Library for image processing
import numpy as np
imgshirt = cv2.imread('C:/Users/sayyed javed ahmed/Desktop/Humaira/Images For Programs/aureknayashirt.png',1) #original img in bgr
musgray = cv2.cvtColor(imgshirt,cv2.COLOR_BGR2GRAY) #grayscale conversion
ret, orig_mask = cv2.threshold(musgray,150 , 255, cv2.THRESH_BINARY)
orig_mask_inv = cv2.bitwise_not(orig_mask)
origshirtHeight, origshirtWidth = imgshirt.shape[:2]
face_cascade=cv2.CascadeClassifier('C:\Users\sayyed javed ahmed\Desktop\Humaira\haarcascade_frontalface_default.xml')
cap=cv2.VideoCapture(0)
while True:
    ret,img=cap.read()
    gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    faces=face_cascade.detectMultiScale(gray,1.3,5)
    for (x,y,w,h) in faces:
        cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
        shirtWidth =  3 * w  #approx wrt face width
        shirtHeight = shirtWidth * origshirtHeight / origshirtWidth #preserving aspect ratio of original image..

        # Center the shirt..just random calculations..
        x1 = x-w
        x2 =x1+3*w
        y1 = y+h
        y2 = y1+h*2


        # Check for clipping(whetehr x1 is coming out to be negative or not..)

        if x1 < 0:
            x1 = 0
        if y1 < 0:
            y1 = 0
        if x2 > 4*w:
            x2 =4*w
        if y2 > 2* h:
            y2 = x2* origshirtHeight / origshirtWidth

        print x1 #debugging
        print x2
        print y1
        print y2
        print w
        print h
        # Re-calculate the width and height of the shirt image(to resize the image when it wud be pasted)
        shirtWidth = x2 - x1
        shirtHeight = y2 - y1

        # Re-size the original image and the masks to the shirt sizes

        shirt = cv2.resize(imgshirt, (shirtWidth,shirtHeight), interpolation = cv2.INTER_AREA) #resize all,the masks you made,the originla image,everything
        mask = cv2.resize(orig_mask, (shirtWidth,shirtHeight), interpolation = cv2.INTER_AREA)
        mask_inv = cv2.resize(orig_mask_inv, (shirtWidth,shirtHeight), interpolation = cv2.INTER_AREA)

        # take ROI for shirt from background equal to size of shirt image
        roi = img[y1:y2, x1:x2]

        print shirt.size #debugginh
        print mask.size
        print mask_inv.size
        print roi.size

        print shirt.shape
        print roi.shape

        print mask.shape
        print mask_inv.shape


            # roi_bg contains the original image only where the shirt is not
            # in the region that is the size of the shirt.
        roi_bg = cv2.bitwise_and(roi,roi,mask = mask_inv)

            # roi_fg contains the image of the shirt only where the shirt is
        roi_fg = cv2.bitwise_and(shirt,shirt,mask = mask)
        print roi_bg.shape #debugging
        print roi_fg.shape

            # join the roi_bg and roi_fg
        dst = cv2.add(roi_bg,roi_fg)
        print dst.shape
            # place the joined image, saved to dst back over the original image
        roi = dst


        break
    cv2.imshow('img',img)
    if cv2.waitKey(1) == ord('q'):
        break;
cap.release()                           # Destroys the cap object
cv2.destroyAllWindows()                 # Destroys all the windows created by imshow

我读过这个帖子: http://www.stackoverflow.com/questions/30117740/opencv-error-assertion-failed-mask-size-src1-size-in-binary-op 但还没有掌握太多。我知道roi和衬衫的尺寸应该相同,我打印这些值来检查它们是否相同,但它们不是。根据我的说法:

roi = img [y1:y2,x1:x2]

shirt = cv2.resize(imgshirt,(shirtWidth,shirtHeight),interpolation = cv2.INTER_AREA)

应该将它们的大小都设为x2-x1和y2-y1,但这并没有发生。从三天开始,我一直在这条线上摸不着头脑,任何帮助都表示赞赏!

3 个答案:

答案 0 :(得分:2)

您是否确保叠加的图像不会超过前景尺寸,因为这通常会导致遮罩尺寸不同

答案 1 :(得分:2)

错误很可能来自你摆弄x和y变量和衬衫尺码的地方,而不确定它们是否适合网络摄像头饲料的框架。

我将您的代码重新编写为工作代码:

import cv2
import numpy as np
imgshirt = cv2.imread('shirt.png',1)
musgray = cv2.cvtColor(imgshirt,cv2.COLOR_BGR2GRAY) #grayscale conversion
ret, orig_mask = cv2.threshold(musgray,150 , 255, cv2.THRESH_BINARY)
orig_mask_inv = cv2.bitwise_not(orig_mask)
origshirtHeight, origshirtWidth = imgshirt.shape[:2]
face_cascade=cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
cap=cv2.VideoCapture(0)
ret,img=cap.read()
img_h, img_w = img.shape[:2]
while True:
    ret,img=cap.read()
    gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    faces=face_cascade.detectMultiScale(gray,1.3,5)
    for (x,y,w,h) in faces:
        cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)

        face_w = w
        face_h = h
        face_x1 = x
        face_x2 = face_x1 + face_h
        face_y1 = y
        face_y2 = face_y1 + face_h

        # set the shirt size in relation to tracked face
        shirtWidth = 3 * face_w
        shirtHeight = int(shirtWidth * origshirtHeight / origshirtWidth)


        shirt_x1 = face_x2 - int(face_w/2) - int(shirtWidth/2) #setting shirt centered wrt recognized face
        shirt_x2 = shirt_x1 + shirtWidth
        shirt_y1 = face_y2 + 5 # some padding between face and upper shirt. Depends on the shirt img
        shirt_y2 = shirt_y1 + shirtHeight

        # Check for clipping
        if shirt_x1 < 0:
            shirt_x1 = 0
        if shirt_y1 < 0:
            shirt_y1 = 0
        if shirt_x2 > img_w:
            shirt_x2 = img_w
        if shirt_y2 > img_h:
            shirt_y2 = img_h

        shirtWidth = shirt_x2 - shirt_x1
        shirtHeight = shirt_y2 - shirt_y1
        if shirtWidth < 0 or shirtHeight < 0:
            continue

        # Re-size the original image and the masks to the shirt sizes
        shirt = cv2.resize(imgshirt, (shirtWidth,shirtHeight), interpolation = cv2.INTER_AREA) #resize all,the masks you made,the originla image,everything
        mask = cv2.resize(orig_mask, (shirtWidth,shirtHeight), interpolation = cv2.INTER_AREA)
        mask_inv = cv2.resize(orig_mask_inv, (shirtWidth,shirtHeight), interpolation = cv2.INTER_AREA)

        # take ROI for shirt from background equal to size of shirt image
        roi = img[shirt_y1:shirt_y2, shirt_x1:shirt_x2]


        # roi_bg contains the original image only where the shirt is not
        # in the region that is the size of the shirt.
        roi_bg = cv2.bitwise_and(roi,roi,mask = mask)
        roi_fg = cv2.bitwise_and(shirt,shirt,mask = mask_inv)
        dst = cv2.add(roi_bg,roi_fg)
        img[shirt_y1:shirt_y2, shirt_x1:shirt_x2] = dst


        break
    cv2.imshow('img',img)
    if cv2.waitKey(1) == ord('q'):
        break;
cap.release() # Destroys the cap object
cv2.destroyAllWindows() # Destroys all the windows created by imshow

我重命名变量以使它们更容易掌握。我将衬衫图像和haarcascade XML路径设置为工作目录以进行本地测试。我在创建roi bg和fg时也切换了面具,不完全确定为什么这是必要的,但这给出了正确的结果。最后添加了img[shirt_y1:shirt_y2, shirt_x1:shirt_x2] = dst以将衬衫粘贴到视频帧中。

另外需要注意的是,在使用numpy图像时,请始终将任何分割结果转换为int s。

face recognition with shirt webcam capture

答案 2 :(得分:-1)

如果掩码的数据类型不正确,也会发生类似的错误。有关更多详细信息,请参见this