Python 从包含带边框的表的图像中提取表结构

Python 从包含带边框的表的图像中提取表结构,python,opencv,image-processing,computer-vision,Python,Opencv,Image Processing,Computer Vision,我正在尝试提取下表中的单元格位置 在应用自适应阈值和HoughLines获得垂直和水平结构元素后,我能够得到细胞位置周围的轮廓。 这是我的密码: img = cv2.imread(os.path.join(img_path, file)) img1 = img.copy() gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) bw = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C

我正在尝试提取下表中的单元格位置

在应用自适应阈值和HoughLines获得垂直和水平结构元素后,我能够得到细胞位置周围的轮廓。 这是我的密码:

img = cv2.imread(os.path.join(img_path, file))
img1 = img.copy()


gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
bw = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 17, 1)
bw = cv2.bitwise_not(bw)


#detect horizontal lines
horizontalStructure = cv2.getStructuringElement(cv2.MORPH_RECT, (15, 1))

horizontal = cv2.erode(bw, horizontalStructure)
horizontal = cv2.dilate(horizontal, horizontalStructure)

horizontal = cv2.dilate(horizontal, (1,1), iterations=5)
horizontal = cv2.erode(horizontal, (1,1), iterations=5)


hlines = cv2.HoughLinesP(horizontal, 1, np.pi/180, 20, np.array([]), 20, 2)


for line in hlines :
    for x1,y1,x2,y2 in line:
        if abs(x1 - x2) > img.shape[1]/4:    
            cv2.line(img,(x1,y1),(x2,y2),(0,255,0),2)





#detect vertical lines
verticalStructure = cv2.getStructuringElement(cv2.MORPH_RECT, (1, 15))

vertical = cv2.erode(bw, verticalStructure)
vertical = cv2.dilate(vertical, verticalStructure)

vertical = cv2.dilate(vertical, (1,1), iterations=5)
#vertical = cv2.erode(vertical, (1,1), iterations=5)


vlines = cv2.HoughLinesP(vertical, 1, np.pi/180, 20, np.array([]), 20, 2)


for line in vlines :
    for x1,y1,x2,y2 in line:
        #if abs(y1 - y2) > img.shape[0]/2:
        cv2.line(img,(x1,y1),(x2,y2),(0,255,0),2)





# red color boundaries [B, G, R]
lower = [0, 240, 0]
upper = [20, 255, 20]

# create NumPy arrays from the boundaries
lower = np.array(lower, dtype="uint8")
upper = np.array(upper, dtype="uint8")

# find the colors within the specified boundaries and apply
# the mask
mask = cv2.inRange(img, lower, upper)
output = cv2.bitwise_and(img1, img, mask=mask)



ret,thresh = cv2.threshold(mask, 40, 255, 0)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

img_area  = img.shape[0] * img.shape[1]

for c in contours:
    x, y, w, h = cv2.boundingRect(c)
    if w * h > 0.005 * img_area:
        cv2.rectangle(img1, (x, y), (x+w, y+h), (0, 0, 255), 2)


如何改进此解决方案?为了更好地以更稳健的方式提取表格单元格信息,我还可以实施哪些其他方法?

对于检测到的每个框,使用更大的区域来处理任意错误树阈值(n像素宽度,如5像素),一旦对图像进行阈值化,您应该能够检测到每个文本内容,将其反转,使线条为白色。然后使用cv2.findContours获得最大轮廓,删除文本的轮廓。然后,您可以使用轮廓的边界框来查找每个左上角(如果您正试图这样做)。@fmw42如何删除文本轮廓?基于什么条件?基于面积。丢弃小于最小矩形区域的轮廓也可以使用形态学仅提取水平线,然后再次仅提取垂直线。然后合并并得到大的白色区域的轮廓。在我上面的评论中,在阈值化之后获得大白色区域的轮廓,并且不要反转。那是个错误,这正是我在做的。首先提取水平和垂直线段,然后叠加它们以获得栅格。我将尝试在不反转图像的情况下获得轮廓,然后看看它是如何工作的。