过滤掉最小面积的矩形 - Python OpenCV

Filter out minimum area rectangles - Python OpenCV

我正在尝试获取围绕图像中一些具有相似特征的对象构建的最小面积矩形的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: 如果哪位朋友有更合适的题目请帮我改一下。谢谢!

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

无论如何,由于 points 现在是一个 numpy 数组,一种方法是检查 returned 框坐标的 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 数组)以便我可以轻松地进行广播。接下来,对于我们检测到的每个轮廓,获取最小跨度边界框,然后检查此最小跨度边界框 xcoords == points[:,0] 中的任何 xy 坐标是否检查到查看列表中是否有我们不想包含的 x 点在检测到的矩形的 x 坐标集中被检测到。对于 y 坐标,ycoords == points[:,1] 的情况类似。执行 np.logical_and 现在将检查坐标对,并查看我们在 xcoord, ycoord 中定义的两个 (x,y) 对是否被视为检测到的边界框中的坐标。执行 np.any 检查是否有任何此类实例发生。如果这是 True,我们继续并跳过这个边界框。

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