简体   繁体   English

在无网格图像 Python Opencv 上画线

[英]Draw line on a gridless image Python Opencv

I have an image like this below.我有一个像下面这样的图像。 [![enter image description here][2]][2] I try to add both vertical and horizontal lines between rows and columns. [![在此处输入图像描述][2]][2] 我尝试在行和列之间添加垂直线和水平线。 I succeeded in adding the horizontal ones using the code provided [here][1].我成功地使用 [此处][1] 提供的代码添加了水平方向。 But I failed to add the vertical ones.但是我没有添加垂直的。 Can anyone help to point out what went wrong with my code?谁能帮忙指出我的代码出了什么问题?

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)

The code above draws only one vertical line at the far left of the image.上面的代码仅在图像的最左侧绘制了一条垂直线。 I removed the vertical line in the original image, but the result remains the same.我删除了原始图像中的垂直线,但结果保持不变。

-----------------------EDIT----------------------------- - - - - - - - - - - - -编辑 - - - - - - - - - - - - - ---

As is in the first answer, I realized that the input for findContours() should not be a one-dimensional array.正如在第一个答案中一样,我意识到findContours()的输入不应该是一维数组。 I thus replaced the following code:我因此替换了以下代码:

# 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)

with:和:

# 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

This adds the vertical lines between columns of text.这会在文本列之间添加垂直线。 [1]: Python & OpenCV: How to add lines to gridless table [2]: https://i.stack.imgur.com/YnPns.png [1]: Python & OpenCV:如何向无网格表中添加线条[2]: https : //i.stack.imgur.com/YnPns.png

Your issue is that count is one dimensional no matter whether along axis 0 or 1. So you have to transpose the x,y and w,h in your bounding boxes to use as you did in Python/OpenCV.您的问题是无论沿轴 0 还是 1,计数都是一维的。因此,您必须像在 Python/OpenCV 中一样使用边界框中的 x、y 和 w、h 来转置。

Input:输入:

在此处输入图片说明

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)

Result:结果:

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM