【问题标题】:Convert cv2.minAreaRect() output to contour for input to cv2.boundingRect()将 cv2.minAreaRect() 输出转换为轮廓以输入 cv2.boundingRect()
【发布时间】:2015-01-17 15:16:04
【问题描述】:

我已经尝试了多种方法来围绕 minAreaRect() 创建 boundingRect(),但我一直遇到错误。我可以简单地使用原始轮廓,是的,但在这一点上,需要了解为什么与 cv2.isContourConvex() 和 cv2.drawContours() 一起使用的轮廓不能与 cv2.boundingRect() 一起使用。基本上我试图更好地理解轮廓的构造。

代码如下:

import cv2
import numpy as np

# EX1: draw contour from minAreaRect() output
mar = cv2.minAreaRect( contour )
pts = cv2.cv.BoxPoints( mar )
pts_contour = np.int0(pts)
cv2.drawContours(mask, [pts_contour], 0, 255, -1)

cv2.boundingRect( pts_contour )  # ERROR: see below

# EX2: test contour convex
contour = np.array([(378, 949), (375, 940), (368, 934), 
    (359, 932), (350, 937), (345, 955), (351, 962), (359, 966), (368, 964),
    (376, 958) ], dtype=np.int)
print cv2.isContourConvex(contour)

cv2.boundingRect( contour )  # ERROR: see below

EX1: 来自 boundingRect() 的错误:OpenCV 错误:cvBoundingRect 中不支持的格式或格式组合(函数不支持图像/矩阵格式) Rotated Rectangles section here中提供了这个转换为轮廓的示例

EX2:boundingRect() 出错:OpenCV 错误:在 boundingRect 中断言失败 (points.checkVector(2) >= 0 && (points.depth() == CV_32F || points.depth() == CV_32S)) 这个从头开始创建轮廓的例子was provided here

再次,我可以实现我的目标,所以我不想要有关变通方法的建议,但我想更好地理解轮廓背后的构造和错误本身,因为我可以看到创建一个 boundingRect() 从选定点

另外,我不知道这是否重要,但我注意到 BoxPoints() 和 findContours()[0] 的输出之间存在差异:

# BoxPoints:
[[1051 1367]
[ 968 1364]
[ 977 1072]
[1061 1074]]

# findCountours()[0]:
[[[ 992 1073]]
[[ 991 1074]]
[[ 989 1074]]
[[ 988 1073]]]

>>> cv2.__version__
'2.4.9'

cv2.boxPoints() 对我不可用,所以我不确定这是否会给我带来不同的结果

【问题讨论】:

    标签: python opencv


    【解决方案1】:

    EX2 中的一个细节在 opencv 错误消息中是明确的:它需要 dtype float32 或 int32 的数组:(points.depth() == CV_32F || points.depth() == CV_32S)。 (使用 numpy v19 测试,如果我猜你没有使用它,因为我找不到 int0

    至于 EX1,很抱歉我无法用 opencv 3.0.0-beta 重现它(cv2.cv 不见了)。顺便说一句,我建议不要花太多时间想知道图书馆的这一部分:cv2.cv 是legacy feature

    【讨论】:

    • 所以我修复了 dtype 错误,我应该已经注意到了,但那时我已经走到了尽头。当我将它提供给 cv2.isContourConvex() 时,一切都很好。我也把它作为输入给 cv2.minAreaRect() 没问题。但是,对于 ex2.fixed,cv2.boundingRect() 现在给出与 ex1 相同的错误。关于为什么一个函数接受这种格式作为点数据而另一个不接受的任何想法?
    • 我的看法是,某些函数在执行求和时需要更深的数据类型(否则值可能会溢出),或者如果它们使用分数(例如,accumulateWeighted)则需要浮点数据类型
    【解决方案2】:

    你必须这样写: (x,y,w,h)=cv2.boundingRect(pts_contour) 当你使用这个函数时,它会返回一个元组。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-25
      • 1970-01-01
      • 1970-01-01
      • 2014-12-08
      • 2019-07-19
      • 2017-11-19
      • 1970-01-01
      • 2016-04-23
      相关资源
      最近更新 更多