[英]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.