我正在扫描旧照片,我想自动从扫描仪(嘈杂的)纯白背景中提取照片的过程,这样我就有了一张透明的照片。程序的这一部分现在可以工作了,但是我还有一个小问题。在
照片现在可以被精确地检测到(并提取出来),但是它在整个照片的背景上留下了一个小而锐利的黑色边界。我曾尝试将高斯模糊应用到透明遮罩上,但这并不能消除黑度(这会使照片的边界看起来“模糊”)。在
这是我提取照片并生成透明度遮罩的代码:
# Load the scan, and convert it to RGBA.
original = cv2.imread('input.jpg')
original = cv2.cvtColor(original, cv2.COLOR_BGR2BGRA)
# Make the scan grayscale, and apply a blur.
image = cv2.cvtColor(original, cv2.COLOR_BGR2GRAY)
image = cv2.GaussianBlur(image, (25, 25), 0)
# Binarize the scan.
retval, threshold = cv2.threshold(image, 50, 255, cv2.THRESH_BINARY)
# Find the contour of the object.
contours, hierarchy = cv2.findContours(threshold, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
largestContourArea = -1
largestContour = -1
for contour in contours:
area = cv2.contourArea(contour)
if area > largestContourArea:
largestContourArea = area
largestContour = contour
# Generate the transparency mask.
mask = numpy.zeros(original.shape, numpy.uint8)
cv2.drawContours(mask, [ largestContour ], -1, (255, 255, 255, 255), -1)
# Apply the transparency mask.
original = cv2.multiply(mask.astype(float) / 255.0, original.astype(float))
cv2.imwrite('output.png', original)
我有一个sample scan和上面使用示例扫描的result of the code。正如你所看到的,照片周围有一个轻微的黑色边框,我想把它去掉。在
通过使用
erode
方法,可以收缩轮廓(mask
),从而有效地去除黑色边缘。在因为这个方法支持就地操作,代码看起来像这样:
cv2.erode(mask, mask, kernel)
,其中kernel
是使用cv2.getStructuringElement
获得的内核。通过使用内核和迭代计数,可以控制收缩量。在这个页面非常详细地解释了一切,还提供了很好的示例:https://docs.opencv.org/2.4/doc/tutorials/imgproc/erosion_dilatation/erosion_dilatation.html
相关问题 更多 >
编程相关推荐