过滤掉最小区域矩形 - Python OpenCV

时间:2015-05-25 09:20:35

标签: python opencv image-processing computer-vision

我试图获取围绕图像中某些具有相似特征的对象构建的最小区域矩形的4个顶点的坐标,忽略它们是否等于某组值,如果它们不相等,则将它们添加到一个清单。

以下是我获取顶点的方法:

contours, hierarchy = cv2.findContours(mask2, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for contour in contours:
        rect = cv2.minAreaRect(contour) 
        points = cv2.cv.BoxPoints(rect)    
        points = np.int0(points)  
        coordinate_list.append(points)

所以points包含坐标。我尝试打印points,这是打印在控制台中的输出的一部分:

[[459 467]
 [459 467]
 [459 467]
 [459 467]]
[[450 466]
 [450 466]
 [450 466]
 [450 466]]
[[306 376]
 [306 376]
 [306 376]
 [306 376]]

这个输出让我感到困惑,因为我不知道如何在我的代码中编写它们。

现在假设我想忽略坐标为((459, 467),(459, 467),(459, 467),(459, 467))((450, 466),(450, 466),(450, 466),(450, 466))顶点的矩形。我尝试在coordinate_list.append(points)语句之前插入以下代码:

if points in [[[459 467], [459 467], [459 467], [459 467]], [[450 466], [450 466], [450 466], [450 466]]]:
    continue

我还尝试了多种方法来显示顶点(比如添加逗号,用普通括号替换方括号等),希望匹配points存储值的正确格式,但我似乎无法看到找到正确的答案。

如何正确编写此if语句?

P / s:如果有人对此问题有更合适的标题,请帮我改变它。谢谢!

1 个答案:

答案 0 :(得分:1)

cv2.boxPoints应仅返回4个坐标,其中包含轮廓的最小跨越边界框。在您的代码中,返回的是numpy大小为4 x 2的数组,其中每一行都是最小跨越边界框的矩形坐标。你得到重复坐标的事实很奇怪。

在任何情况下,由于points现在是numpy数组,因此一种方法是检查返回的框坐标的x坐标是否在由一组坐标提供的位置。你和y一样。

因此,numpy - ish看起来像这样:

# Store x and y coordinates as column vectors
xcoord = np.array([[459, 450]]).T
ycoord = np.array([[467, 466]]).T

# Run contour detection code
contours, hierarchy = cv2.findContours(mask2, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

coordinate_list = []

# Go through each contour...
for contour in contours:
    rect = cv2.minAreaRect(contour) 
    points = cv2.cv.BoxPoints(rect)    
    points = np.int0(points) 

    # Check to see if any rectangle points are in our lists
    if np.any(np.logical_and(xcoords == points[:,0], ycoords == points[:,1])):
        continue

    coordinate_list.append(points)

我首先要做的是创建单独的numpy数组,其中包含您不希望在列表中看到的坐标的xy坐标。您需要确保将这些点置于正确顺序中。因此,xcoords[0]ycoords[0]属于(x,y)个点。同样,xcoords[1]ycoords[1]属于(x,y)点等。

请注意,我已经制作了列向量(N x 1数组),以便我可以轻松地进行广播。接下来,对于我们检测到的每个轮廓,获取最小跨越边界框,然后检查此最小跨越边界框x中的任何yxcoords == points[:,0]坐标是否检查到查看我们列表中是否存在我们不想包含的任何x点,这些点在检测到的矩形的x坐标集中被检测到。 ycoords == points[:,1]坐标y的类似情况。执行np.logical_and现在将检查坐标对,并查看我们在(x,y)中定义的xcoord, ycoord对是否被视为检测到的边界框中的坐标。执行np.any检查是否发生任何此类实例。如果这是True,我们继续并跳过此边界框。

输出应存储在coordinate_list中,其中您想要跳过其坐标的矩形不会出现。