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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何计算最小长度的矩形数?相关的知识,希望对你有一定的参考价值。

我有以下代码,用于查找铁路是否存在任何连续性。这个想法是创建边界框,如果有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)

答案

在你的结果中,我们可以看到许多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))

以上是关于如何计算最小长度的矩形数?的主要内容,如果未能解决你的问题,请参考以下文章

bzoj-2338 2338: [HNOI2011]数矩形(计算几何)

九度oj 题目1397:查找数段

POJ2559 Largest Rectangle in a Histogram(单调栈)

求二值图像的最小外接矩形

使用带有actionscript 3 Flash cs6的矩形或线条创建2D重复模式

给定矩形内的最小瓷砖数