首页 > 解决方案 > 在生成 alpha 遮罩的 trimap 时几乎不需要支持

问题描述

我正在尝试从肖像图像中提取头发。为此,我到目前为止已经完成了以下工作:

  1. 将图像转换为灰度然后转换为二进制
  2. 分离出毛发的形态学操作。
  3. 查找轮廓,从上到下对其进行排序,仅将最顶部的轮廓绘制为蒙版(显然是头发)。
  4. 再次执行一些形态学操作以找出确定的前景和未知区域。

现在,当我结合确定前景和未知来制作我将用于 alpha 遮罩以提取头发的遮罩时,我得到了一条不需要的黑色边界线。那么,如何在没有该边界的情况下组合两个图像。或者,还有其他更好的方式来生成 trimap 吗?

这是我的代码:

import numpy as np
import cv2


img = cv2.imread("Test5.jpg")
image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# cv2.imshow("GrayScaled", image)
# cv2.waitKey(0)

ret, thresh = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY_INV)
# cv2.imshow("Black&White", thresh)
# cv2.waitKey(0)


kernel1 = np.ones((2,2),np.uint8)
erosion = cv2.erode(thresh,kernel1,iterations=4)
# cv2.imshow("AfterErosion", erosion)
# cv2.waitKey(0)

kernel2 = np.ones((1,1),np.uint8)
dilation = cv2.dilate(erosion,kernel2,iterations = 5)
# cv2.imshow("AfterDilation", dilation)
# cv2.waitKey(0)

contours, hierarchy = cv2.findContours(dilation, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

#sort contours
sorted_ctrs = sorted(contours, key=lambda ctr: cv2.boundingRect(ctr)[1])

mask = np.zeros_like(img) # Create mask where white is what we want, black otherwise
cv2.drawContours(mask, sorted_ctrs, 0, (255, 255, 255), -1) # Draw filled contour in mask
out = np.zeros_like(img) # Extract out the object and place into output image
out[mask == 255] = [255]

# Show the output image
cv2.imshow('Output', out)
cv2.waitKey(0)

image1 = cv2.cvtColor(out, cv2.COLOR_BGR2GRAY)

# noise removal
kernel = np.ones((10, 10), np.uint8)
opening = cv2.morphologyEx(image1, cv2.MORPH_OPEN, kernel, iterations = 2)

# sure background area
sure_bg = cv2.dilate(opening, kernel, iterations=4)

# Finding sure foreground area
sure_fg = cv2.erode(opening, kernel, iterations=3)
cv2.imshow("foreground", sure_fg)
cv2.waitKey(0)

# Finding unknown region
sure_fg = np.uint8(sure_fg)
unknown = cv2.subtract(sure_bg, sure_fg)
ret, thresh = cv2.threshold(unknown, 240, 255, cv2.THRESH_BINARY)

unknown[thresh == 255] = 128

kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
unknown = cv2.erode(unknown, kernel, iterations=1)

cv2.imshow("unknown", unknown)
cv2.waitKey(0)

final_mask = sure_fg + unknown
cv2.imwrite("Trimap.jpg", final_mask)
cv2.imshow("final_mask", final_mask)
cv2.waitKey(0)
cv2.destroyAllWindows()

这是我的输入和输出图像:

原始图像

三图

标签: pythonnumpyopencvimage-processing

解决方案


unknown和之间的黑线sure_fg是因为unknown在末端被线侵蚀

unknown = cv2.erode(unknown, kernel, iterations=1)

删除该行后,这是创建的掩码:

在此处输入图像描述


推荐阅读