在OpenCV中,findContours
函数是一个非常常用的工具,用于检测图像中的轮廓,在实际使用过程中,可能会遇到一些报错问题,下面将详细介绍cv::findContours
函数的用法,分析常见的报错原因及相应的解决方案:
函数介绍
1、函数原型:void findContours(InputOutputArray image, OutputArrayOfArrays contours, OutputArray hierARChy, int mode, int method, Point offset=Point())
。
2、参数说明
image:输入图像,必须为二值单通道图像。
contours:检测到的轮廓数组,每个轮廓用一个point
类型的vector
表示。
hierarchy:轮廓的层次结构,与轮廓数量相同,每个轮廓对应4个元素,分别表示后一个轮廓、前一个轮廓、父轮廓和内嵌轮廓的索引编号,如果没有对应项,则该值为负数。
mode:轮廓的检索模式,包括:
CV_RETR_EXTERNAL
:只检测外轮廓。
CV_RETR_LIST
:检测的轮廓不建立等级关系。
CV_RETR_CCOMP
:建立两个等级的轮廓,顶层为外边界,内层为内孔边界信息。
CV_RETR_TREE
:建立等级树结构的轮廓。
method:轮廓的近似方法,包括:
CV_CHAIN_appROX_NONE
:存储所有轮廓点。
CV_CHAIN_APPROX_SIMPLE
:仅保留轮廓的拐点。
CV_CHAIN_APPROX_TC89_L1
和CV_CHAIN_APPROX_TC89_KCOS
:使用TehChin链码近似算法。
offset:轮廓点的偏移量,默认为Point(0, 0)
。
常见报错及解决方案
| 错误类型 | 描述 | 解决方案 |
||||
| Assertion failed (mtype == type0 || (CV_MAT_CN(mtype) == CV_MAT_CN(type0) && ((1 << type0) & f…)) | 在使用vector<vector<Point> >
作为contours
参数时,可能会出现断言失败的错误,这是因为标准库中的std::vector
和Point
与findContours
函数中使用的vector
和Point
不同。 | 使用cv::vector<cv::Point>
或cv::Mat
替代标准库中的vector<Point>
。vector<cv::Point>
或Mat
。 |
| Assertion failed (npoints >= 0 && (depth == CV_32F || depth == CV_32S)) | 当传入的图像格式不是uint8
时,可能会出现此错误。 | 确保传入的图像格式为uint8
,可以使用print(image.dtype)
检查图像格式,并在必要时进行转换。 |
| ValueError: not enough values to unpack (expected 3, got 2) | 在使用旧版OpenCV(4.0以下)时,findContours
返回三个参数,而新版OpenCV返回两个参数。 | 根据OpenCV版本调整代码,对于旧版OpenCV,使用image, contours, hierarchy = cv2.findContours(...)
;对于新版OpenCV,使用contours, hierarchy = cv2.findContours(...)
。 |
| 内存分配错误 | 在某些情况下,程序可能会因为内存分配错误而崩溃,尤其是在处理视频帧时。 | 检查内存管理,确保在处理每一帧图像时正确释放不再使用的内存,如果问题仍然存在,尝试调整堆大小或检查是否有内存泄漏。 |
FAQs
1、Q1: 为什么在使用cv::findContours
时会出现“Assertion failed”错误?
A1:这通常是由于使用了错误的数据类型或未正确配置项目属性导致的,确保使用cv::vector<cv::Point>
或cv::Mat
作为contours
参数,并检查项目属性是否正确配置。
2、Q2: 如何处理ValueError: not enough values to unpack
错误?
A2:这个错误是由于OpenCV版本不匹配导致的,根据你使用的OpenCV版本,调整代码以正确接收返回值,对于旧版OpenCV,使用三个变量接收返回值;对于新版OpenCV,使用两个变量接收返回值。
通过上述内容,可以更好地理解和解决在使用cv::findContours
函数时可能遇到的报错问题,希望这些信息对你有所帮助!