【问题标题】:how to detect all the rectangular boxes in the given image如何检测给定图像中的所有矩形框
【发布时间】:2019-07-26 04:24:00
【问题描述】:

我尝试使用阈值、canny 边缘和应用轮廓检测​​来检测图像中的所有矩形,但它无法检测到所有矩形。最后,我想使用hough 变换来检测相同的内容,但是当我尝试检测图像中的线条时,我得到了所有线条。我只需要检测图像中的矩形框。有人能帮我吗?我是opencv的新手。

输入图片

代码:

import cv2
import matplotlib.pyplot as plt
import numpy as np

img =  cv2.imread("demo-hand-written.png",-1)
#img = cv2.resize(img,(1280,720))
edges = cv2.Canny(img,180,200)
kernel = np.ones((2,2),np.uint8)
d = cv2.dilate(edges,kernel,iterations = 2)
e = cv2.erode(img,kernel,iterations = 2)  
#ret, th = cv2.threshold(img, 220, 255, cv2.THRESH_BINARY_INV)

lines = cv2.HoughLinesP(edges,1,np.pi/180,30, maxLineGap=20,minLineLength=30)
for line in lines:
    #print(line)
    x1,y1,x2,y2 = line[0]
    cv2.line(img,(x1,y1),(x2,y2),(0,255,0),3)
cv2.imshow("image",img)
cv2.waitKey(0)
cv2.destroyAllWindows()

【问题讨论】:

标签: python opencv image-processing


【解决方案1】:

您可以使用以下代码作为起点。

img =  cv2.imread('demo-hand-written.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

thresh_inv = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)[1]

# Blur the image
blur = cv2.GaussianBlur(thresh_inv,(1,1),0)

thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)[1]

# find contours
contours = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0]

mask = np.ones(img.shape[:2], dtype="uint8") * 255
for c in contours:
    # get the bounding rect
    x, y, w, h = cv2.boundingRect(c)
    if w*h>1000:
        cv2.rectangle(mask, (x, y), (x+w, y+h), (0, 0, 255), -1)

res_final = cv2.bitwise_and(img, img, mask=cv2.bitwise_not(mask))

cv2.imshow("boxes", mask)
cv2.imshow("final image", res_final)
cv2.waitKey(0)
cv2.destroyAllWindows()

输出:

图1:上图中检测到的矩形框

图2:在原图中检测到的矩形轮廓

【讨论】:

  • 很好的解决方案,你能解释一下阈值化然后模糊然后再次阈值化的思考过程吗?
  • 首先是使用 otsu 方法的二进制阈值,只是为了反转背景和内容颜色。只需将此结果传递给cv2.findContours 函数即可获得结果。但是,我故意在高斯滤波之后添加了 Otsu 的阈值,只是为了更好、更通用的输出。似乎改变高斯模糊中的内核值会影响结果,(1, 1) 在上述情况下效果很好。
  • 最后在高斯模糊之后应用 otsu 的阈值是推荐的选择。看到这个:opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/…
【解决方案2】:

建议:

使用 Hough,检测水平线。然后依次取每一行,并考虑一个与该行一样大且高度较短的窗口。使用 Hough 检测此窗口中的垂直线。这将为您提供候选角。 (您也可以尝试线上一窗,线下一窗。)

然后通过一些额外的局部处理(?),确认候选者确实是框角,并找到角方向。最后,您应该能够以几何上有意义的方式连接角吗?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-30
    • 1970-01-01
    • 2016-09-19
    • 2011-08-22
    • 1970-01-01
    • 1970-01-01
    • 2020-04-21
    • 1970-01-01
    相关资源
    最近更新 更多