【问题标题】:Draw line on a gridless image Python Opencv在无网格图像Python Opencv上画线
【发布时间】:2021-07-26 02:15:46
【问题描述】:

我在下面有一张这样的图片。 [![在此处输入图像描述][2]][2] 我尝试在行和列之间添加垂直线和水平线。我使用[这里][1]提供的代码成功地添加了水平的。但我没有添加垂直的。谁能帮忙指出我的代码出了什么问题?

import cv2
import numpy as np
import matplotlib.pyplot as plt
file = r"C:/Users/gaojia/Dropbox/Projects/Parking_lot/Community_Group_Buying/scripts/test_2.png"
# read image
img = cv2.imread(file)
hh, ww = img.shape[:2]

# convert to grayscale 
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

# threshold gray image
thresh = cv2.threshold(gray, 254, 255, cv2.THRESH_BINARY)[1]

# count number of non-zero pixels in each row
count = np.count_nonzero(thresh, axis=0)

# threshold count at ww (width of image)
count_thresh = count.copy()
count_thresh[count==hh] = 255
count_thresh[count<hh] = 0
count_thresh = count_thresh.astype(np.uint8)

# get contours
contours = cv2.findContours(count_thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]

# loop over contours and get bounding boxes and ycenter and draw horizontal line at ycenter
result = img.copy()
for cntr in contours:
    x,y,w,h = cv2.boundingRect(cntr)
    xcenter = x+w//2
    cv2.line(result, (xcenter,0), (xcenter, hh-1), (0, 0, 0), 2)


# display results
cv2.imshow("THRESHOLD", thresh)
cv2.imshow("RESULT", result)
cv2.waitKey(0)

上面的代码只在图像的最左边绘制了一条垂直线。我把原图中的竖线去掉了,结果还是一样。

------------编辑-------------------- ---------

与第一个答案一样,我意识到findContours() 的输入不应该是一维数组。因此,我替换了以下代码:

# count number of non-zero pixels in each row
count = np.count_nonzero(thresh, axis=0)

# threshold count at ww (width of image)
count_thresh = count.copy()
count_thresh[count==hh] = 255
count_thresh[count<hh] = 0
count_thresh = count_thresh.astype(np.uint8)

与:

# find row index with any value equals 0
row_zero = np.nonzero(np.any(thresh == 0, axis=1))[0]
# replace values in column with any 0 with 0.
thresh[row_zero, :] =  0

这会在文本列之间添加垂直线。 [1]:Python & OpenCV: How to add lines to gridless table [2]:https://i.stack.imgur.com/YnPns.png

【问题讨论】:

    标签: python opencv-python


    【解决方案1】:

    您的问题是,无论沿轴 0 还是轴 1,计数都是一维的。因此,您必须像在 Python/OpenCV 中一样使用边界框中的 x,y 和 w,h。

    输入:

    import cv2
    import numpy as np
    
    # read image
    img = cv2.imread("gridless_table.png")
    hh, ww = img.shape[:2]
    
    # convert to grayscale 
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    
    # threshold gray image
    thresh = cv2.threshold(gray, 254, 255, cv2.THRESH_BINARY)[1]
    
    # count number of non-zero pixels in each column
    count = np.count_nonzero(thresh, axis=0)
    
    # threshold count at hh (height of image)
    count_thresh = count.copy()
    count_thresh[count==hh] = 255
    count_thresh[count<hh] = 0
    count_thresh = count_thresh.astype(np.uint8)
    
    # get contours
    contours = cv2.findContours(count_thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    contours = contours[0] if len(contours) == 2 else contours[1]
    
    # loop over contours and get bounding boxes and xcenter and draw vertical line at ycenter
    result = img.copy()
    for cntr in contours:
        # must transpose x,y and w,h since count is one-dimensional but represents each column
        y,x,h,w = cv2.boundingRect(cntr)
        print(x,y,w,h)
        xcenter = x+w//2
        cv2.line(result, (xcenter,0), (xcenter, hh-1), (0, 0, 0), 2)
    
    # save results
    cv2.imwrite("gridless_table_lines.png", result)
    
    # display results
    cv2.imshow("THRESHOLD", thresh)
    cv2.imshow("RESULT", result)
    cv2.waitKey(0)
    

    结果:

    【讨论】:

    • 感谢@fmw42,我还发现findContours 函数的输入错误,我更改了它,您的代码的其他所有内容都很好。只是一个快速的跟进,你如何建议我,一个openCV的初学者,从这样的表中提取信息?
    • @JasonGoal 使用 pytesseract(光学字符识别又名 OCR)从图像中提取文本/数据。有关如何执行此操作的良好介绍性教程,请参阅以下链接:medium.com/analytics-vidhya/…towardsdatascience.com/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-09
    • 2014-06-11
    • 1970-01-01
    • 2018-11-05
    • 2021-07-12
    • 2020-12-20
    相关资源
    最近更新 更多