Python 使用openCV删除部分边框
我正在使用OpenCV查找图像中的表格数据,这样我就可以在上面使用OCR了。到目前为止,我已经能够在图像中找到表,找到表中的列,然后找到每列中的每个单元格。它工作得很好,但我有一个问题,细胞壁卡在我的图像中,我无法可靠地删除它们 我尝试了几种方法来改善这些图像。我最幸运的是找到了轮廓Python 使用openCV删除部分边框,python,opencv,image-processing,python-imaging-library,Python,Opencv,Image Processing,Python Imaging Library,我正在使用OpenCV查找图像中的表格数据,这样我就可以在上面使用OCR了。到目前为止,我已经能够在图像中找到表,找到表中的列,然后找到每列中的每个单元格。它工作得很好,但我有一个问题,细胞壁卡在我的图像中,我无法可靠地删除它们 我尝试了几种方法来改善这些图像。我最幸运的是找到了轮廓 img2gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ret, mask = cv2.threshold(img2gray, 180, 255, cv2.THRESH_
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))
我尝试过其他一些想法,但没有一个能让我走得很远。任何帮助都将不胜感激。您可以尝试找到轮廓并“绘制”出来。这意味着您可以在图像的边框上手动绘制一个与“墙”相连的边框,使用
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像素的边框,效果很好。我很高兴它有帮助…有很多方法可以删除…一个我贴的,或者只画了一个带厚边框的白色矩形,或者只是用几个像素来剪切图像