在trimap生成中几乎不需要Alpha遮罩

时间:2019-01-30 07:13:25

标签: python numpy opencv image-processing

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

  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()

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

Original Image

Trimap

1 个答案:

答案 0 :(得分:1)

unknownsure_fg之间的黑线是因为unknown在该行的末端被腐蚀了

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

删除该行之后,将创建以下遮罩:

enter image description here