FindContours问题

先对image进行clone,作对比实验
虽然参数传递为const&,按道理对src的操作不会对src造成改变
但是在创建c_image时对src只进行了浅拷贝,相当于仅创建了矩阵头,共用的同一份内空间;
cvFindContours处理之后c_image变成了轮廓图
视频中可以看出,原始image与copyimg已经不同
compare对比函数,当单通道像素值相同时输出tmp此处像素为255;
建议在实现myfindContours时申请局部cv::Mat tmp = src.clone();
然后对tmp进行操作,使用完后tmp.release();保证原始图像的数据正确;

环境:Opencv3.4.12,VS2017,Win10

视频图像插件:VS2017插件ImageWatch,可实时显示内存中的Mat图像

findContours

最为对:

OpenCV findContours函数崩溃的真正有效解决方案_amani_liu的博客-CSDN博客_cv::findcontours奔溃最近在windows平台使用OpenCV的findContours函数时,会出现崩溃问题。在网上搜了很多解决方案,比如:1.配置属性->常规->项目默认值->MFC的使用->在共享DLL中使用MFC;2.C/C+±>代码生成->运行库-&ghttps://blog.csdn.net/amani_liu/article/details/87932141

的补充;

void myfindContours(const cv::Mat& src, std::vector<std::vector<cv::Point>>& contours, std::vector<cv::Vec4i>& hierarchy, int retr, int method, cv::Point offset)
{
#if CV_VERSION_REVISION <= 6
	cv::Mat tmp = src.clone();
	CvMat c_image = tmp;
#else
	cv::Mat tmp = src.clone();
	CvMat c_image;
	c_image = cvMat(tmp.rows, tmp.cols, tmp.type(), tmp.data);
	c_image.step = tmp.step[0];
	c_image.type = (c_image.type & ~cv::Mat::CONTINUOUS_FLAG) | (tmp.flags & cv::Mat::CONTINUOUS_FLAG);
#endif
	cv::MemStorage storage(cvCreateMemStorage());
	CvSeq* _ccontours = nullptr;

#if CV_VERSION_REVISION <= 6
	cvFindContours(&c_image, storage, &_ccontours, sizeof(CvContour), retr, method, CvPoint(offset));
#else
	cvFindContours(&c_image, storage, &_ccontours, sizeof(CvContour), retr, method, CvPoint{ offset.x, offset.y });
#endif
	if (!_ccontours)
	{
		contours.clear();
		return;
	}
	cv::Seq<CvSeq*> all_contours(cvTreeToNodeSeq(_ccontours, sizeof(CvSeq), storage));
	size_t total = all_contours.size();
	contours.resize(total);

	cv::SeqIterator<CvSeq*> it = all_contours.begin();
	for (size_t i = 0; i < total; i++, ++it)
	{
		CvSeq* c = *it;
		reinterpret_cast<CvContour*>(c)->color = static_cast<int>(i);
		int count = c->total;
		int* data = new int[static_cast<size_t>(count * 2)];
		cvCvtSeqToArray(c, data);
		for (int j = 0; j < count; j++)
			contours[i].push_back(cv::Point(data[j * 2], data[j * 2 + 1]));
		delete[] data;
	}

	hierarchy.resize(total);
	it = all_contours.begin();
	for (size_t i = 0; i < total; i++, ++it)
	{
		CvSeq* c = *it;
		int h_next = c->h_next ? reinterpret_cast<CvContour*>(c->h_next)->color : -1;
		int h_prev = c->h_prev ? reinterpret_cast<CvContour*>(c->h_prev)->color : -1;
		int v_next = c->v_next ? reinterpret_cast<CvContour*>(c->v_next)->color : -1;
		int v_prev = c->v_prev ? reinterpret_cast<CvContour*>(c->v_prev)->color : -1;
		hierarchy[i] = cv::Vec4i(h_next, h_prev, v_next, v_prev);
	}

	storage.release();
	tmp.release();
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值