Opencv2.4.9 中 findContours 的报错与解决方案

findContours的使用

	最近在做opencv相关的轮廓发现和分离。在opencv 中右两种方式使用findContours函数,第一个是检测轮廓和层次信息,第二个只检测轮廓。
//! retrieves contours and the hierarchical information from black-n-white image.
CV_EXPORTS_W void findContours( InputOutputArray image, OutputArrayOfArrays contours,
                              OutputArray hierarchy, int mode,
                              int method, Point offset=Point());

//! retrieves contours from black-n-white image.
CV_EXPORTS void findContours( InputOutputArray image, OutputArrayOfArrays contours,
                              int mode, int method, Point offset=Point());
	我需要的是第二种就直接调函数。
	Mat image = imread(img_path, 1);
	if (image.empty())
	{
		cout << "Couldn't load " << img_path << endl;
	}
	Mat timg(image);
	medianBlur(image, timg, 9);

	Mat gray0, gray;
	vector<vector<Point> > contours;  // 存储轮廓信息
	// 灰度化+二值化
	cvtColor(timg, gray0, CV_BGR2GRAY);
	threshold(gray0, gray, 50, 255, THRESH_BINARY);
	//imshow("threshold gray", gray);
	// find contours and store them all as a list
	findContours(gray, contours, CV_RETR_EXTERNAL, CHAIN_APPROX_NONE);
	
	使用opencv3.4.14运行下面代码没有任何问题,能检测出来轮廓并且运行无报错。
	项目中使用的是opencv 2.4.9。当我配置好opencv2.4.9后,将代码复制到该环境后,运行...,也能检测出来轮廓,但是报错了!!!弹出来一个警告,让我不得不中止程序。

在这里插入图片描述

	搜索了很多解决方法,很多人也是直接换版本了,可是我现在要用2.4.9,然后又发现了一下几个解决方法:
	方案一: 
	如果使用vector<vector<Point> > contours;作为findContours的参数,在运行时会得到 

Assertion failed (mtype == type0 || (CV_MAT_CN(mtype) == CV_MAT_CN(type0) && ((1 << type0) & f… 原因是标准库里有std::vector 和 Point 和findContours里要用到的vector和Point不是一回事所以,声明的时候要用cv::vector和cv::Point就可以了。

	方案二: 
	“修改了当前程序的vc运行库配置,问题解决。具体方法是:项目-属性-配置属性-C/C++-代码生成-运行库,将其改为“多线程调试(/MTd)”。”

	方案三: 
	当一个DLL采用静态的方式链接到C运行时库时,会创建一个相对于该DLL的堆(Heap),而如果采用共享的方式链接到C运行时库的时候则使用的是应用程序的堆内存。而_CrtIsValidHeapPointer()在 DEBug模式下将确保传入的地址在本地的堆内存中。 因此就有理由相信,真有可能是静态链接的问	题。所以,我立即尝试将: 
	项目–属性–配置属性–常规–MFC的使用– 选择在共享DLL中使用MFC ;同时, 
	项目–属性–配置属性–C/C++–代码生成–运行库–选择 多线程DLL(/MD)。

	以上方案都不能解决这个问题,直到我试了这个。

	方案四: 
	在调用finContours函数之前,自己进行空间的分配。 于是,我对程序进行部分修改,修改程序如下:
vector<Mat> contours(100); 
findContours(gray, contours, CV_RETR_EXTERNAL, CHAIN_APPROX_NONE);

注意,此时得到的每一个轮廓存放的方式不在是Point类型而是Mat类型,在操作轮廓坐标时使用的是Mat的操作方式,例如后续我用到了approxPolyDP函数。

Mat approxArray;
approxPolyDP(Mat(contours[maxLengthPosition]), approxArray, arcLength(Mat(contours[maxLengthPosition]), true) * 0.02, true);
	其中,maxLengthPosition是最大轮廓的所在索引位置。

	此时的approxArray也要用Mat接收,然后操作时使用:
approxArray.at<int>(i, j);
	int 是Mat 定义的数据类型,如果出现错误,可以使用approxArray.type()来确定。approxArray.type()返回一个数值,该数值对应该图像是什么类型的,具体的对应可以去https://blog.csdn.net/kakiebu/article/details/79359867看下,写的很详细。

	问题就这样解决了~
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值