关于OpenCV中contour[:, :, 0].argmin()及轮廓极值端点的疑问
理解OpenCV中轮廓极值点的计算逻辑
咱们一步一步拆解这段代码,搞清楚它怎么找到轮廓的四个方向极值点,还有你疑惑的contour[:, :, 0].argmin()到底在做什么。
先搞懂轮廓的数组结构
OpenCV找到的单个轮廓(比如代码里的变量c)是一个三维NumPy数组,形状为(N, 1, 2):
N代表轮廓上包含的总点数- 第二个维度的
1是固定格式(每个坐标点被包裹在一个单元素数组里) - 第三个维度的
0对应点的x坐标,1对应点的y坐标
举个直观的例子:c[0][0]就能取出轮廓上第一个点的(x, y)坐标,结果是类似[100, 200]的数组。
核心逻辑:c[:, :, 0].argmin()的工作原理
咱们把这个表达式拆成两部分看:
c[:, :, 0]:提取所有点的x坐标
这是NumPy的切片操作:- 第一个
:表示取轮廓上的所有N个点 - 第二个
:表示取每个点对应的单元素数组 - 第三个
0表示取数组中的x坐标值
执行后会得到一个一维数组,里面是轮廓上所有点的x坐标。
- 第一个
.argmin():找到最小值的索引
这个NumPy方法会返回数组中最小值所在的索引位置(索引从0开始)。比如如果x坐标最小的点是轮廓的第5个点,argmin()就会返回4。
把这两步结合起来:c[c[:, :, 0].argmin()]就能取出x坐标最小的那个点所在的数组(形状是(1,2)),再加上[0]就得到了[x_min, y_min]这个坐标数组,最后用tuple()转成元组就是我们要的extLeft。
四个极值点的计算逻辑
搞懂了核心逻辑,四个方向的极值点就很好理解了:
- extLeft(最左端点):取所有点中x坐标最小的点 → 用
c[:, :, 0].argmin()定位 - extRight(最右端点):取所有点中x坐标最大的点 → 用
c[:, :, 0].argmax()定位 - extTop(最上端点):注意图像坐标系中y轴是从上到下递增的,所以y坐标最小的点就是最顶部的点 → 用
c[:, :, 1].argmin()定位 - extBot(最下端点):y坐标最大的点就是最底部的点 → 用
c[:, :, 1].argmax()定位
完整代码的流程回顾
再把整个代码的执行逻辑串一遍:
cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE):从二值化图像中提取所有最外层的轮廓imutils.grab_contours(cnts):兼容不同OpenCV版本的返回值(不同版本返回值数量不同,这个函数帮我们直接拿到纯净的轮廓列表)max(cnts, key=cv2.contourArea):从所有轮廓中选出面积最大的那个(通常这就是我们要分析的目标物体)- 分别计算四个方向的极值点,转成元组后输出
内容的提问来源于stack exchange,提问作者Prayash Shrestha
相关产品推荐
相关产品推荐

