如何计算最小长度的矩形数?

时间:2017-11-24 16:47:52

标签: python eclipse opencv

我有以下代码,我用它来查找铁路是否存在任何连续性。这个想法是创建边界框,如果有2个框,这意味着一切都没问题。否则,如果我有两个以上的盒子,则意味着存在不连续性。所以,在我的代码末尾,我放了一个函数print len(contours)

问题在于,当我有我的最终图像(蓝色矩形)时,我们可以看到我需要的那些(覆盖铁路的那些),还有一些我不想要的小矩形。这意味着函数print len(contours)向我发回一条消息,告诉我例如有19个矩形。

我的想法是做一个小功能,要求程序计算最小长度或宽度的矩形数(因此它只计算覆盖铁路的矩形)。我是使用Python编码的初学者,我不知道如何编写代码,有人可以帮助我吗?

提前感谢您的帮助。

这是我的代码:

 import numpy as np
 import argparse
 import cv2


 image = cv2.imread('..\img.jpg')
 frame = cv2.resize(image,(500,500))

 """boundaries = [
     ([17, 15, 100], [50, 56, 200]),
     ([86, 31, 4], [220, 88, 50]),
     ([25, 146, 190], [62, 174, 250]),
     ([103, 86, 65], [145, 133, 128])]"""

 boundaries = [([100, 100, 100], [255, 255, 255])]

 for (lower, upper) in boundaries:
     # 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(frame, lower, upper)
         output = cv2.bitwise_and(frame, frame, mask = mask)


     # show the images
         cv2.namedWindow("images", cv2.WINDOW_NORMAL)
         cv2.resizeWindow("images", 1000, 500)
         cv2.imshow("images", np.hstack([frame, output]))
         cv2.waitKey(0)


 gray=cv2.cvtColor(output,cv2.COLOR_BGR2GRAY)
 ret,th1 = cv2.threshold(gray,25,255,cv2.THRESH_BINARY)
 contours,hierarchy = cv2.findContours(th1, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
 for cnt in contours:
     x,y,w,h = cv2.boundingRect(cnt)
     cv2.rectangle(output,(x,y),(x+w,y+h),(255,0,0),2)


 cv2.imshow('image2',output)
 cv2.waitKey(0)


 print len(contours)

以下是我的结果(左图是原始图像,中间图像只允许我们看到铁路,右图像检测到带有边界框的铁路):

Results when there is not any discontinuity (the code says that there are 4 rectangles)

Results when there is a discontinuity (the code says that there are 19 rectangles)

1 个答案:

答案 0 :(得分:0)

在您的搜索结果中,我们可以看到很多noisy regions。因此,为了获得矩形的计数,您应该执行更多pre-post-processing步骤,例如二进制文件上的morph-op,或者noisy regionsarea移除width-height-ratio

在这两种情况下,执行morph-op就足够了。但你也可以对它们进行更多的处理。

图像:

enter image description here

情况1

enter image description here

情况2 enter image description here

源代码:

## read and convert to gray 
img = cv2.imread("lines.png")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

## threshed 
th, threshed = cv2.threshold(gray, 100, 255, cv2.THRESH_BINARY|cv2.THRESH_OTSU)

## morph-op      
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))
morphed = threshed.copy()
morphed = cv2.morphologyEx(morphed, cv2.MORPH_ERODE, kernel, iterations=1)
morphed = cv2.morphologyEx(morphed, cv2.MORPH_DILATE, kernel, iterations=2)

## find contours
cnts = cv2.findContours(morphed, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)[-2]
print(len(cnts))

## removingt noisy regions by area
cnts = list(filter(lambda cnt: cv2.contourArea(cnt) > 100, cnts))
print(len(cnts))