简体   繁体   English

细化OpenCV遮罩边缘

[英]Refine OpenCV mask edge

I'm in the process of scanning old photographs, and I would like to automate the process of extracting the photograph from the (noisy) solid white background of the scanner so that I have a transparent photograph. 我正在扫描旧照片,我想自动化从扫描仪的(嘈杂的)纯白色背景中提取照片的过程,以便获得透明的照片。 This part of the program now works, but I have one more small problem with this. 该程序的这一部分现在可以使用,但是我对此还有一个小问题。

The photograph can now be accurately detected (and extracted), but it leaves a small and sharp black border from the background around the entire photograph. 现在可以准确地检测(并提取)照片,但是它会在整个照片周围的背景上留下一个小的且清晰的黑色边框。 I've tried to apply a gaussian blur to the transparency mask, but this wouldn't smooth the blackness away (and it made the border of the photograph look 'smudged'). 我曾尝试对透明蒙版应用高斯模糊,但这不会消除黑度(这会使照片的边框看起来“被弄脏”)。

This is the code that I have to extract the photo and generate the transparency mask: 这是提取照片并生成透明蒙版的代码:

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

I have a sample scan and the result of the code above using the sample scan. 我有一个样本扫描,以及上面使用样本扫描的代码结果 As you can see, there is a slight black border all around the photograph, which I would like to remove. 如您所见,照片周围有轻微的黑色边框,我要删除该边框。

By using the erode method, you could shrink the contour ( mask ), effectively removing the black edge. 通过使用erode方法,可以缩小轮廓( mask ),有效去除黑色边缘。

Since this method supports in-place operation, the code would look something like this: cv2.erode(mask, mask, kernel) , where kernel is a kernel acquired using cv2.getStructuringElement . 由于此方法支持就地操作,因此代码如下所示: cv2.erode(mask, mask, kernel) ,其中kernel是使用cv2.getStructuringElement获取的内核。 By playing around with the kernel and the iteration count, you can control the amount of shrinking. 通过处理内核和迭代计数,您可以控制收缩量。

This page explains everything in great detail and also provides nice examples: https://docs.opencv.org/2.4/doc/tutorials/imgproc/erosion_dilatation/erosion_dilatation.html 该页面详细解释了所有内容,并提供了不错的示例: https : //docs.opencv.org/2.4/doc/tutorials/imgproc/erosion_dilatation/erosion_dilatation.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM