OpenCV 学习笔记03 boundingRect、minAreaRect、minEnclosingCircle、boxPoints、int0、circle、rectangle函数的用法...

函数中的代码是部分代码,详细代码在最后

1 cv2.boundingRect

作用:矩形边框(boundingRect),用于计算图像一系列点的外部矩形边界。

cv2.boundingRect(array) -> retval

参数:

array - 灰度图像(gray-scale image)或 2D点集( 2D point set ) 

返回值:元组

元组(x, y, w, h ) 矩形左上点坐标,w, h 是矩阵的宽、高,例如 (161, 153, 531, 446)

代码示例:

contours, hierarchy = cv2.findContours(re_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

for c in contours:
    # find bounding box coordinates
    # 现计算出一个简单的边界框
    x, y, w, h = cv2.boundingRect(c)
     # 画出矩形
    cv2.rectangle(img, (x,y), (x+w, y+h), (0, 255, 0), 2) 

 

 

2 cv2.minAreaRect

作用:minAreaRect - min Area Rect 最小区域矩形;计算指定点集的最小区域的边界矩形,矩形可能会发生旋转 possibly rotated,以保证区域面积最小。

cv2.minAreaRect(points) -> retval

参数:

points - 2D点的矢量( vector of 2D points )

返回值:元组

 元组((最小外接矩形的中心坐标),(宽,高),旋转角度)----->    ((x, y), (w, h), θ )

关于旋转角度的注意事项:

1)旋转角度是水平轴(x轴)逆时针旋转,与碰到的矩形第一条边的夹角。

2)“ 第一条边 " 定义为 宽width,另一条边定义为高 height。这里的宽、高不是按照长短来定义的。

3)在 opencv 中,坐标系原点在图像左上角,将其延伸到整个二维空间,可以发现 “x轴镜像对称”,角度则 逆时针旋转为负、顺时针旋转为正。故θ∈(-90度,0];(笛卡尔坐标系中,逆时针为正、顺时针为负)

4)旋转角度为角度值,而非弧度制。

 

 

如 ((458.70343017578125, 381.97894287109375), (202.513916015625, 634.2526245117188), -45.707313537597656)

但绘制这个矩形,一般需要知道矩形的 4 个顶点坐标;通常是通过函数 cv2.boxPoints()获取。

2.1 附1 : cv2.boxPoints

作用:查找旋转矩形的 4 个顶点(用于绘制旋转矩形的辅助函数)。

cv2.boxPoints(box) -> points

参数:

box - 旋转的矩形

返回值:列表list

points - 矩形 4 个顶点组成的列表 list

返回值示例:

[[614.9866  675.9137 ]
 [161.      232.99997]
 [302.4203   88.04419]
 [756.40686 530.9579 ]]

 

 

2.2 附2:int0

int0 有两种相近的描述,

第一种,int0 意味是 64位整数。字符代码'l'。与 Python int兼容,参考文档https://kite.com/python/docs/numpy.int0

int0 ( *args, **kwargs )

第二种,等价于intp,在 数组类型和类型之间的转换 文档中,有intp,释义为 “ 用于索引的整数(与C ssize_t

### 关于C++中的最小包围圆(Min Enclosing Circle) 在C++中实现最小包围圆(MinEnclosingCircle),通常涉及几何算法的设计与实现。虽然提供的引用并未直接提及该主题,但可以从其他角度探讨其实现方式。 #### 几何背景 最小包围圆是指能够覆盖平面上给定一组点的最小半径的圆。其核心思想基于 Welzl 的随机化算法[^5],这是一种高效的递归方法,能够在平均情况下达到 O(n) 时间复杂度,在最坏情况下的时间复杂度为 O(n&sup2;)[^6]。 以下是Welzl算法的核心逻辑: 1. 随机选取一个点作为候选中心。 2. 对剩余未被当前圆覆盖的点重复上述过程,直到找到满足条件的最小圆。 3. 使用三点确定唯一圆心的方式计算最终结果。 #### 实现代码示例 下面是一个简单的 C++ 实现: ```cpp #include <iostream> #include <vector> #include <cmath> #include <cstdlib> using namespace std; struct Point { double x, y; }; double dist(const Point& p1, const Point& p2) { return sqrt((p1.x - p2.x)*(p1.x - p2.x) + (p1.y - p2.y)*(p1.y - p2.y)); } Point make_circle_two_points(const Point& p1, const Point& p2) { return {(p1.x + p2.x)/2, (p1.y + p2.y)/2}; } bool is_in_circle(const Point& center, double radius, const Point& point) { return dist(center, point) <= radius; } pair<Point, double> min_enclosing_circle(vector<Point>& P) { random_shuffle(P.begin(), P.end()); auto helper = [&](auto&& self, vector<Point>::iterator begin, vector<Point>::iterator end, vector<Point>& B) -> pair<Point, double> { if (begin == end || B.size() == 0) { return {{0, 0}, 0}; // Base case: no points. } pair<Point, double> res = self(self, begin + 1, end, B); if (is_in_circle(res.first, res.second, *begin)) { return res; } B.push_back(*begin); if (B.size() == 1) { res = {*B.begin(), 0}; } else if (B.size() == 2) { res = {make_circle_two_points(B[0], B[1]), dist(B[0], B[1])/2}; } else if (B.size() == 3) { // Use three-point circle formula here... } B.pop_back(); return res; }; vector<Point> B; return helper(helper, P.begin(), P.end(), B); } ``` 此代码实现了基本框架,具体三点半径计算部分需进一步补充。 #### 注意事项 - 上述代码仅提供了一个基础版本,实际应用可能需要优化性能并处理边界情况。 - 可能还需要引入更复杂的数值稳定性和精度控制机制来应对浮点运算误差问题[^7]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值