【问题标题】:Removing partial borders with openCV使用 openCV 去除部分边框
【发布时间】:2019-01-17 09:36:15
【问题描述】:

我正在使用 OpenCV 在图像中查找表格数据,以便可以在其上使用 OCR。到目前为止,我已经能够在图像中找到表格,找到表格的列,然后找到每列中的每个单元格。它工作得很好,但是我遇到了细胞壁卡在我的图像中的问题,我无法可靠地移除它们。This is one example that I'm having difficulty with.This would be another example.

我尝试了几种方法来使这些图像更好。我一直很幸运能找到轮廓。

img2gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

ret, mask = cv2.threshold(img2gray, 180, 255, cv2.THRESH_BINARY)
image_final = cv2.bitwise_and(img2gray, img2gray, mask=mask)
ret, new_img = cv2.threshold(image_final, 180, 255, cv2.THRESH_BINARY_INV)

kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (5, 3))

# dilate , more the iteration more the dilation
dilated = cv2.dilate(new_img, kernel, iterations=3)
cv2.imwrite('../test_images/find_contours_dilated.png', dilated)

我一直在玩弄内核大小和膨胀迭代,发现这是最好的配置。

我使用的另一种方法是使用 PIL,但只有在整个图像周围的边框是统一的情况下才真正好,在我的情况下并非如此。

copy = Image.fromarray(img)
try:
    bg = Image.new(copy.mode, copy.size, copy.getpixel((0, 0)))
except:
    return None
diff = ImageChops.difference(copy, bg)
diff = ImageChops.add(diff, diff, 2.0, -100)
bbox = diff.getbbox()
if bbox:
    return np.array(copy.crop(bbox))

我尝试了其他一些想法,但没有一个能让我走得很远。任何帮助将不胜感激。

【问题讨论】:

    标签: python opencv image-processing python-imaging-library


    【解决方案1】:

    您可以尝试寻找轮廓并将其“绘制”出来。这意味着您可以在图像的边界上使用cv2.rectangle 手动绘制将与“墙壁”连接的边框(这将结合所有轮廓 - 墙壁)。最大的两个轮廓将是墙壁的外线和内线,您可以将轮廓绘制为白色以移除边框。然后再次应用阈值以消除其余的噪声。干杯!

    例子:

    import cv2
    import numpy as np
    
    # Read the image
    img = cv2.imread('borders2.png')
    
    # Get image shape
    h, w, channels = img.shape
    
    # Draw a rectangle on the border to combine the wall to one contour
    cv2.rectangle(img,(0,0),(w,h),(0,0,0),2)
    
    # Convert to grayscale
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
    # Apply binary threshold
    _, threshold = cv2.threshold(gray, 180, 255, cv2.THRESH_BINARY_INV)
    
    # Search for contours and sort them by size
    _, contours, hierarchy = cv2.findContours(threshold,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
    area = sorted(contours, key=cv2.contourArea, reverse=True)
    
    # Draw it out with white color from biggest to second biggest contour
    cv2.drawContours(img, ((contours[0]),(contours[1])), -1, (255,255,255), -1)
    
    # Apply binary threshold again to the new image to remove little noises
    _, img = cv2.threshold(img, 180, 255, cv2.THRESH_BINARY)
    
    # Display results
    cv2.imshow('img', img)
    

    结果:

    【讨论】:

    • 太棒了,效果很好。出于某种原因,它不会为我找到边界的内部轮廓。我只是假设一个 10 像素的边框,它工作得很好。
    • 很高兴它有帮助...有很多可能性如何删除...我发布的一个或仅绘制带有粗边框的白色矩形或仅将图像裁剪几个像素
    猜你喜欢
    • 2020-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-23
    • 2015-01-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多