CV2 SeamlessClone(-215:Assertion Failed)

问题描述 投票:0回答:1

[我有一个神经网络,可以输出人脸的各个部分-我正在研究将这些部分组合在一起然后将它们克隆为真实人脸的功能。

示例图像在这里:https://imgur.com/a/HnpqhEE,我不敢在内嵌它们。

到目前为止,我的功能是将化妆的脸部和嘴唇分段并将其与添加物组合在一起。然后使用SeamlessClone克隆左眼和右眼(首先翻转右眼)。然后将组合的化妆片段克隆到正常脸部。

[偶尔,我的组合函数失败并返回(-215:Assertion失败)0 <= roi.x && 0 <= roi.width && roi.x + roi.width <= m.cols && 0 <= roi .y && 0 <= roi.height && roi.y + roi.height <= m.rows函数'cv :: Mat :: Mat'错误。

我的函数在下面,我只在最后一个SeamlessClone中看到它错误

def combineFace(images, radius = 70):
    # Given image segments and eye radii, combine face.
    realFace    = tensor2im(images['realNormal'])
    makeupFace  = tensor2im(images['fakeMakeupFace'])
    makeupLeft  = tensor2im(images['fakeMakeupLeft'])
    makeupRight = tensor2im(images['fakeMakeupRight'])
    makeupLips  = tensor2im(images['fakeMakeupLips'])
    makeupRight = cv2.flip(makeupRight, 1)
    # I use cv2 and dlib to get face landmarks and interesting points.
    normalLandmarks = faceLandmarks(realFace)
    facePoints      = getFacePoints(normalLandmarks)
    # PP means pupil points
    outerPoints, leftPP, rightPP, lipPoints, eyeMids = facePoints
    # eyeMid is (x, y) of center of eye obtained from landmark points
    leftEye  = eyeMids[0]
    rightEye = eyeMids[1]

    faceMask = np.zeros(realFace.shape, realFace.dtype)
    cv2.fillPoly(faceMask, [outerPoints], [255, 255, 255])
    cv2.fillPoly(faceMask, [lipPoints], [0, 0, 0])
    cv2.fillPoly(faceMask, [leftPP], [0, 0, 0])
    cv2.fillPoly(faceMask, [rightPP], [0, 0, 0])


    # Occasionally, the eye segments overlap eachother so I cut the right eye from the left and vice 
    # versa

    leftMask = np.zeros(realFace.shape, realFace.dtype)
    cv2.circle(leftMask, leftEye, radius, [255, 255, 255], -1)
    cv2.circle(leftMask, rightEye, radius,  [0, 0, 0], -1)
    # Errors if i do not use UMat
    cv2.circle(cv2.UMat(makeupLeft), rightEye, radius, [0, 0, 0], -1)

    rightMask = np.zeros(realFace.shape, realFace.dtype)
    cv2.circle(rightMask, rightEye, radius, [255, 255, 255], -1)
    cv2.circle(rightMask, leftEye, radius,  [0, 0, 0], -1)
    cv2.circle(cv2.UMat(makeupRight), leftEye, radius, [0, 0, 0], -1)

    # Combine face output and lips
    baseCombine = makeupFace + makeupLips
    # Left Eye
    output = cv2.seamlessClone(makeupLeft,  baseCombine, leftMask, leftEye, cv2.MIXED_CLONE)
    output = cv2.seamlessClone(makeupRight, output, rightMask, rightEye, cv2.MIXED_CLONE)


    # Get center of face
    faceRect = cv2.boundingRect(outerPoints)
    x, y, w, h = faceRect

    output = cv2.bitwise_and(output, faceMask)
    center = ( x + w // 2, y + h // 2)

    # I have only seen the function error at this point 
    combinedFace = cv2.seamlessClone(output, realFace, faceMask, center, cv2.MIXED_CLONE)
    return combinedFace

知道为什么这偶尔会出错吗?

所有输入图像的格式为(256,256,3)

python opencv image-processing
1个回答
0
投票

此版本的功能效果更好。我的脸部中心计算出了问题,这引起了错误

def combineFace(images, radius = 70):
    # Given image segments and eye radii, combine face.
    realFace    = tensor2im(images['realNormal'])
    makeupFace  = tensor2im(images['fakeMakeupFace'])
    makeupLeft  = tensor2im(images['fakeMakeupLeft'])
    makeupRight = tensor2im(images['fakeMakeupRight'])
    makeupLips  = tensor2im(images['fakeMakeupLips'])

    # Right eye is flipped before input into the network.
    makeupRight = cv2.flip(makeupRight, 1)

    normalLandmarks = faceLandmarks(realFace)
    facePoints      = getFacePoints(normalLandmarks)

    outerPoints, leftPP, rightPP, lipPoints, eyeMids = facePoints
    leftEye  = eyeMids[0]
    rightEye = eyeMids[1]


    leftMask = np.zeros(makeupLeft.shape, makeupLeft.dtype)
    cv2.circle(leftMask, leftEye, radius,   [255, 255, 255], -1)
    cv2.circle(leftMask, rightEye, radius,  [0, 0, 0], -1)
    # Errors if i do not use cv2.UMat
    cv2.circle(cv2.UMat(makeupLeft), rightEye, radius, [0, 0, 0], -1)

    rightMask = np.zeros(makeupRight.shape, makeupRight.dtype)
    cv2.circle(rightMask, rightEye, radius, [255, 255, 255], -1)
    cv2.circle(rightMask, leftEye, radius,  [0, 0, 0], -1)
    cv2.circle(cv2.UMat(makeupRight), leftEye, radius, [0, 0, 0], -1)

    # Base output is combination of face without lips and pupils + lips
    baseCombine = makeupFace + makeupLips
    # Areas around eyes are changes
    output = cv2.seamlessClone(makeupLeft,  baseCombine, leftMask,  leftEye, cv2.MIXED_CLONE)
    output = cv2.seamlessClone(makeupRight, output,      rightMask, rightEye, cv2.MIXED_CLONE)

    # Find center of face 
    faceRect   = cv2.boundingRect(outerPoints)

    x, y, w, h = faceRect 

    if x < 0:
        x = 0
    if y < 0: 
        y = 0

    faceCenter = ( x + w // 2, y + h // 2)

    croppedOutput = output[y:y+h, x:x+w]

    faceMask = np.zeros(realFace.shape, realFace.dtype)
    cv2.fillPoly(faceMask, [outerPoints], [255, 255, 255])
    cv2.fillPoly(faceMask, [lipPoints],   [0, 0, 0])
    cv2.fillPoly(faceMask, [leftPP],      [0, 0, 0])
    cv2.fillPoly(faceMask, [rightPP],     [0, 0, 0])

    croppedMask = faceMask[y:y+h, x:x+w]

    if len(croppedOutput) == 0:
        print("OUTPUT 0")
        print("FACE RECT: ", faceRect)


    sourceW, sourceH, sCH = realFace.shape
    width, height, ch = croppedOutput.shape

    faceWidth  = width/2
    faceHeight = height/2
    xdiff = 0
    ydiff = 0
    cx = faceCenter[0]
    cy = faceCenter[1]

    if cx - faceWidth < 0:
        # Face overflows left
        xdiff = abs(cx - faceWidth)
    if cx + faceWidth > sourceW:
        xdiff = (cx + faceWidth - sourceW) * -1

    if cy + faceHeight > sourceH:
        ydiff = (cy + faceHeight - sourceH) * -1
    if cy - faceHeight < 0:
        ydiff = abs(cy - faceHeight)

    centerx = int(cx + xdiff)
    centery = int(cy + ydiff)
    center = (centerx, centery)

    # We move center, also move mask?


    combinedFace = cv2.seamlessClone(croppedOutput, realFace, croppedMask, center, cv2.MIXED_CLONE)
    return combinedFace
© www.soinside.com 2019 - 2024. All rights reserved.