OpenCV Python:不同轮廓逼近方法为何输出结果相同?
为什么cv2.CHAIN_APPROX_NONE和cv2.CHAIN_APPROX_SIMPLE输出看起来一样?
嘿,我之前也踩过这个坑!其实视觉上看起来输出相同,大多是因为两种逼近方法的轮廓点集绘制出来的形状完全一致,但内部存储的点数量天差地别,咱们来拆解具体原因:
1. 你的目标轮廓本身就是“无冗余点”的形状
如果你的图像里的目标是完美的正方形、边缘笔直的线段,或是低分辨率下的规则图形,那cv2.CHAIN_APPROX_SIMPLE会只保留线段的端点,而cv2.CHAIN_APPROX_NONE会保留所有边界点。但用cv2.drawContours绘制时,不管是连接所有点还是只连接端点,最终呈现的形状都是一样的——毕竟直线就是直线,多几个中间点不影响视觉效果。
2. 你只看了绘制后的图像,没检查轮廓数据本身
要验证两种方法的区别,别只看画出来的图,直接打印轮廓里的点数量就清楚了:
import cv2 im = cv2.imread('simple.jpg') imgray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY) ret, thresh = cv2.threshold(imgray, 127, 255, 0) # 用CHAIN_APPROX_NONE提取轮廓 _, contours_none, hierarchy_none = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) print(f"CHAIN_APPROX_NONE 保留的点数量:{len(contours_none[0])}") # 用CHAIN_APPROX_SIMPLE提取轮廓 _, contours_simple, hierarchy_simple = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) print(f"CHAIN_APPROX_SIMPLE 保留的点数量:{len(contours_simple[0])}")
运行这段代码,你会发现NONE的点数量远多于SIMPLE——比如一个正方形,SIMPLE可能只保留4个角点,而NONE会保留每条边上的所有像素点。
3. 额外注意:OpenCV版本的返回值差异
顺便提一句,如果你用的是OpenCV 4.x版本,cv2.findContours的返回值是contours, hierarchy,而不是你代码里的_, contours, hierarchy(这是OpenCV 3.x的写法)。不过这个不是导致两种逼近方法视觉相同的原因,但版本不对可能会引发其他报错,需要注意。
总结一下:两种方法的核心区别是内部存储的点数量,而不是绘制后的视觉效果。只要检查轮廓的点集数据,就能看到明显差异啦!
内容的提问来源于stack exchange,提问作者masan




