numpy 矩形框检测器和绘制包围盒

ar7v8xwq  于 2023-04-06  发布在  其他
关注(0)|答案(2)|浏览(117)

我试图从图像中检测一些表格,但图像的结构使它很难使用一些库来提取它们,所以我决定将它们提取为图像,我试图使用下面的代码来绘制矩形周围的边界框,代码工作,但它似乎没有检测到颜色较浅的矩形:
这是我使用的代码:

import numpy as np 
import cv2

#load the image
image = cv2.imread("aaaaaaaaaaa.jpg")

# grayscale
result = image.copy()
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)

# adaptive threshold
thresh = cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV,51,9)

# Fill rectangular contours
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    cv2.drawContours(thresh, [c], -1, (255,255,255), -1)

# Morph open
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9,9))
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=4)

# Draw rectangles, the 'area_treshold' value was determined empirically
cnts = cv2.findContours(opening, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
area_treshold = 4000
for c in cnts:
    if cv2.contourArea(c) > area_treshold :
      x,y,w,h = cv2.boundingRect(c)
      cv2.rectangle(image, (x, y), (x + w, y + h), (36,255,12), 3)

cv2.imwrite('thresh.jpg', thresh)
cv2.imwrite('opening.jpg', opening)
cv2.imwrite('image.jpg', image)
cv2.waitKey()

这是输入:this is the input image
如果你注意到从图像中它只检测足够暗的盒子而不是较亮的盒子this is the output
任何帮助都将不胜感激

bxjv4tth

bxjv4tth1#

如果你知道表格的颜色,那么使用cv2.inRange()对图像进行阈值化呢?

下面是一个例子,有两个不同的范围来分隔表头和表体

import numpy as np 
import cv2

image = cv2.imread("image.jpg")
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)

thresh_header = cv2.inRange(hsv, (10, 130, 0), (20, 140, 255))
thresh_body = cv2.inRange(hsv, (10, 80, 0), (20, 90, 255))

现在,您可以重用已完成的代码来查找轮廓并绘制矩形:

def draw_countours(image, thresh, color):
    cnts, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    for c in cnts:
        if cv2.contourArea(c) < area_treshold:
            continue
        x, y, w, h = cv2.boundingRect(c)
        cv2.rectangle(image, (x, y), (x + w, y + h), color, 3)
        
draw_countours(image, thresh_header, (0, 0, 255))
draw_countours(image, thresh_body, (255, 0, 0))

下面是一个结果示例

请注意,当然,只有在您事先知道表的颜色时才有效。

  • 编辑评论 *

有没有一种方法我可以提取或裁剪整个表。这是标题和身体一起
在这种情况下,您可以扩展用于阈值化图像的HSV范围,以在同一掩码(thresh_header + thresh_body)中获得标题和主体。
要得到整个矩形,而不包括线条,可以使用形态学变换,如闭合。下面是一个例子:

# Threshold with a broader HSV range 
thresh = cv2.inRange(hsv, (10, 80, 0), (20, 140, 255))

kernel = np.ones((10, 10), np.uint8)
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)

下面是使用上面定义的draw_countours()获得的轮廓:

你可以使用矩形框裁剪图像。确保删除所有 * 噪声 * 轮廓,只保留感兴趣的主要轮廓。

cnts, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

rects = [cv2.boundingRect(cnt) for cnt in cnts if cv2.contourArea(cnt) > area_treshold]
x, y, w, h = rects[0]

crop = image[y:y+h, x:x+w]

vltsax25

vltsax252#

我们可以increase_contrastcv2.findContours提供一个更适合使用的图像:

def increase_contrast(x):
    return 127.0 if x >= 230.0 else 255.0

increase_contrast = np.vectorize(increase_contrast)
new_image = increase_contrast(gray)

相关问题