【问题标题】:CV2 SeamlessClone (-215:Assertion Failed)CV2 无缝克隆(-215:断言失败)
【发布时间】:2020-04-02 06:23:56
【问题描述】:

我有一个输出面部片段的神经网络 - 我正在研究一个将这些片段组合在一起然后将它们克隆成真实面部的函数。

示例图片在这里:https://imgur.com/a/HnpqhEE,我没有将它们包含在内的声誉。

到目前为止,我的功能采用化妆脸和嘴唇部分并将它们与添加相结合。然后用 seamlessClone 克隆左眼和右眼(首先翻转右眼)。 然后将组合的化妆片段克隆到正常人脸中。

我的组合函数偶尔会失败并返回 (-215:Assertion failed) 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'])
    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)

【问题讨论】:

  • 该错误与人脸中心计算有关。如果我使用 while 正方形作为掩码,以及 dest 图像的中心和克隆中心,则该功能可以正常工作。我知道 cv2 错误意味着某些东西正在溢出其他东西,但我对 cv2 不是很熟悉,所以我不知道什么溢出了什么。我已经编辑了代码,以便从基于 faceRect 的 256x256 图像中裁剪出面部和 faceMask,然后我正在检查放置裁剪后的面部是否溢出目标图像并调整中心坐标(如果是)。

标签: python opencv image-processing


【解决方案1】:

这个版本的函数效果更好。我的面部中心计算有问题导致错误

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-27
    • 2021-02-13
    • 1970-01-01
    • 2021-03-14
    • 2022-10-15
    • 2021-10-29
    • 2020-02-03
    • 2019-12-04
    相关资源
    最近更新 更多