Opencv2.4.9+VS2015+MFC出现问题:expression:"(_Ptr_user&(_BIG_ALLOCATION_ALIGNMENT-1))==0"&&0解决方案

必须过来怒写一波博客了,遇到这么狗血和奇葩的问题真是不多见,还好解决了!现在分享解决方案给大家^0^

Opencv+VS2015+MFC出现问题:

(1)报错行数:

xmemory0 Line 100:
expression:"(_Ptr_user&(_BIG_ALLOCATION_ALIGNMENT-1))==0"&&0

(2)报错行数:

debug_heap.cpp Line: 892
expression:is_block_type_valid(header->_block_use)

(3)报错行数:

xmemory0 Line 110:
reinterpret_cast(_Ptr_ptr)[-1] ==_BIG_ALLOCATION_SENTINEL);

三个看似不怎么一致的问题,就恰恰出在了一起!也是很令人醉醉的。

不过这三个问题单独来看的话,是没有一个正常的解决方案的,综合多篇在StackOverflow上类似的回答才可以看出,这其实就是一个典型的leaking memory(内存溢出)问题,而在我对图像处理的代码中,用到的最费内存的结构就是一个又一个的不同类型的vector数组了,咋一看并没有什么不妥,因为是C++编程,这些vector都是以局部变量的形式存在的,而我用到了特征检测算法,由于是dense SIFT算法,检测到的特征点会比较多,代码没有被嵌入MFC之前,是可以运行成功的,可当代码被嵌入到事件处理函数中后,奇怪的事情出现了,函数体整个部分没有任何错误,但是在函数结束时,执行return就会出现上述三种错误中的一种,具体出现哪种依据改动的大小而定,这就很令人恼火了,毕竟是两个都好使的代码,按正常手段放到一起照理不应该啊!

类似的错误StackOverflow上有人提出这样的解决方案,供大家参考:

Because the memory of vector is limited, there are too many keypoints. If the keypoints are about 10000:

keypoints.reserve(10000);

但是这是一个只治标不治本的方法,大家可以尝试,真正的问题还是vector导致的leaking memory,那怎么办呢?我突然向导了一个类似的案例,也就是说,当在main()函数中开不出1000000大小的数组时,往往爱把这个大数组定义为全局变量,于是乎,我本着一试的心态,把所有用到的vector全部定义为的全局变量,并在用完之后就调用.clear()函数,将内存释放掉,结果!问题就这样完美的解决啦!程序无bug还是硬道理!

现在附上我不再报错的代码:

vector buff1;
vector buff2;
vector buff3;
vector keyPoints1;
vector keyPoints2;
vector matches; //定义匹配结果变量 
vector goodMatches;
vector obj;
vector scene;

void CToolsV1Dlg::OnBnClickedHandle()
{
	// TODO: 在此添加控件通知处理程序代码
	/*OpenCV2CXimage o2i;
	IplImage *iplImage1;
	IplImage *iplImage2;
	bool okk1 = o2i.Cximage2IplImage(m_pImage1, &iplImage1); ///从Cximage类转换为IplImage类
	bool okk2 = o2i.Cximage2IplImage(m_pImage2, &iplImage2);*/
	
	uint8_t* buf1 = NULL;
	int32_t len1 = 0;
	CxImage cximage1 = *m_pImage1;
	bool okk1 =cximage1.Encode(buf1, len1, CXIMAGE_FORMAT_BMP);
	
	uint8_t* buf2 = NULL;
	int32_t len2 = 0;
	CxImage cximage2 = *m_pImage2; 
	bool okk2 = cximage2.Encode(buf2, len2, CXIMAGE_FORMAT_JPG);
	
	if (okk1 && okk2)
	{
		 
		//1.SIFT特征点提取——detect()方法    
		///Mat srcImg1 = cvarrToMat(iplImage1);   ///从IplImage类转换为Mat类
		///Mat srcImg2 = cvarrToMat(iplImage2);
		
		buff1.resize(len1);
		memcpy(&buff1[0], buf1, len1);

		
		buff2.resize(len2);
		memcpy(&buff2[0], buf2, len2);

		Mat srcImg1;
		Mat srcImg2;
		srcImg1=imdecode(buff1, 1);
		srcImg2 = imdecode(buff2, 1);

		delete []buf1;
		delete []buf2;

		buff1.clear();
		buff2.clear();

		Mat srcImg1_copy = srcImg1;
		Mat srcImg2_copy = srcImg2;
		Mat dstImg1, dstImg2;
		DenseFeatureDetector siftDetector;//SiftFeatureDetector是SIFT类的别名      
		
		keyPoints1.clear();
		keyPoints1.clear();
		//2.特征点描述符(特征向量)提取——compute()方法    
		SiftDescriptorExtractor descriptor;//SiftDescriptorExtractor是SIFT类的别名      
		Mat description1;
		Mat description2;

		int step = 10; // 10 pixels spacing between kp's  

		for (int i = step; i> matcher;//实例化暴力匹配器    
		   
		matcher.match(description1, description2, matches);//实现描述符之间的匹配    
		MessageBox(_T("格式转换正确,正在计算......"));
		//4.对匹配结果进行筛选(依据DMatch结构体中的float类型变量distance进行筛选)    
		float minDistance = 100;
		float maxDistance = 0;
		for (int i = 0; i < matches.size(); i++)
		{
			if (matches[i].distance < minDistance)
				minDistance = matches[i].distance;
			if (matches[i].distance > maxDistance)
				maxDistance = matches[i].distance;
		}
		///cout << "minDistance: " << minDistance << endl;
		///cout << "maxDistance: " << maxDistance << endl;
		
		for (int i = 0; i < matches.size(); i++)
		{
			if (matches[i].distance < 3 * minDistance)
			{
				goodMatches.push_back(matches[i]);
			}
		}
		//5.绘制匹配结果——drawMatches()    
		Mat dstImg3;
		drawMatches(srcImg1, keyPoints1, srcImg2, keyPoints2, goodMatches, dstImg3);
		
		for (int i = 0; i < goodMatches.size(); i++)
		{
			obj.push_back(keyPoints1[goodMatches[i].queryIdx].pt);
			scene.push_back(keyPoints2[goodMatches[i].trainIdx].pt);
		}

		Mat H = findHomography(scene, obj, CV_RANSAC);
		Mat srcImg3;

		//Size size(500, 500);  
		//原图像变形    
		warpPerspective(srcImg2_copy, srcImg3, H, srcImg2_copy.size());

		///srcImg3是最终结果,将其写到磁盘上
		imwrite("pic/test3.jpg", srcImg3);
		keyPoints1.clear();
		keyPoints2.clear();
		matches.clear();
		goodMatches.clear();
		obj.clear();
		scene.clear();
		/*
		OpenCV2CXimage o2i2;
		IplImage *iplImage3 = &IplImage(srcImg3);//从Mat类转换为IplImage类
		bool okk3 = o2i2.IplImage2Cximage(iplImage3, m_pImage3); //从IplImage类转换为Cximage类
		if(okk3)
		{
			//绘制图像到相应的图像控件上
			m_pWnd3 = this->GetDlgItem(IDC_IMAGEC); ////这里一定要和picture Control控件的ID对应起来  
		    DrawImgOnCtrl(m_pImage3, m_pWnd3);
		}
		else
		{
			MessageBox(_T("图像类型转换出现问题!"));
		}*/
		
		
		imencode(".jpg", srcImg3, buff3);
		CxImage img3(&buff3[0], buff3.size(), CXIMAGE_FORMAT_JPG);
		
		//判断指针是否为空  
		if (m_pImage3 != NULL)
		{
			delete m_pImage3;
			m_pImage3 = NULL;
		}

		//开辟内存  
		m_pImage3 = new CxImage();
		m_pImage3 = &img3;

		if (!m_pImage3->IsValid())
		{
			AfxMessageBox(_T("建立图像指针失败!"));
			delete m_pImage3;
			m_pImage3 = NULL;
			return;
		}
		MessageBox(_T("就差显示了!"));
		m_pWnd3 = this->GetDlgItem(IDC_IMAGEC);
		DrawImgOnCtrl(m_pImage3, m_pWnd3);
		MessageBox(_T("成功显示了呢!"));
	}
	else
	{
		MessageBox(_T("请先输入矫正前的两张图像!"));
	}
    MessageBox(_T("矫正完事儿啦!开心吗?开心^0^,非常开心!哒哒哒"));
}

总结:ACM真的不是白学的!倔强青铜也不是白倔强的!




-------------------------------------这是一条分割线20180330----------------------------------------

用VS运行别人的代码常遇到的错误及解决方法:

error C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

这是一个十分常见的错误,最方便的解决办法就是:在c++预处理器中添加_CRT_SECURE_NO_WARNINGS的定义。

具体操作为:

解决方案下,右键项目-->属性-->c/c++-->预处理器-->预处理定义-->点击下拉菜单

添加_CRT_SECURE_NO_WARNINGS,点击确定,应用即可!


你可能感兴趣的:(MFC)