1. 程式人生 > >OpenCV SITF 特徵提取 FeatureDetector物件函式detect執行報錯解決方案

OpenCV SITF 特徵提取 FeatureDetector物件函式detect執行報錯解決方案

本人在使用OpenCV SIFT特徵提取演算法時,遇到了問題,具體表現為 .exe觸發了一個斷點錯誤,經網上查詢,發現是 vector 在析構時,造成了記憶體錯誤,解決方案由大神在csdn部落格中給出,連結地址:

按照大神所提示的 ,在使用opencv 函式之前,先對 vector 進行手動分配記憶體,分配記憶體後問題解決;

個人宣告:本人在VS2013下呼叫sift演算法,已經將問題解決,當然,具體問題,具體分析,本人適用,但不一定適用所有人,也希望大家對該問題的解決方案進行及時補充;

程式碼:

	initModule_nonfree();//初始化模組,使用SIFT或SURF時用到  

	//FeatureDetector::create()函式的引數可選
// 	• "FAST" – FastFeatureDetector
// 		• "STAR" – StarFeatureDetector
// 		• "SIFT" – SIFT(nonfree module)
// 		• "SURF" – SURF(nonfree module)
// 		• "ORB" – ORB
// 		• "BRISK" – BRISK
// 		• "MSER" – MSER
// 		• "GFTT" – GoodFeaturesToTrackDetector
// 		• "HARRIS" – GoodFeaturesToTrackDetector with Harris detector enabled
// 		• "Dense" – DenseFeatureDetector
// 		• "SimpleBlob" – SimpleBlobDetector
	Ptr<FeatureDetector> detector = FeatureDetector::create("SIFT");//建立SIFT特徵檢測器  

	//SiftFeatureDetector detector;
	//Ptr<FeatureDetector> detector = FeatureDetector::create("SURF");
// 	DescriptorExtractor::create()函式的引數如下:
// 
// 		• "SIFT" – SIFT
// 		• "SURF" – SURF
// 		• "BRIEF" – BriefDescriptorExtractor
// 		• "BRISK" – BRISK
// 		• "ORB" – ORB
// 		• "FREAK" – FREAK
	//SiftDescriptorExtractor descriptor_extractor;
	Ptr<DescriptorExtractor> descriptor_extractor = DescriptorExtractor::create("SIFT");//建立特徵向量生成器  
	//Ptr<DescriptorExtractor> descriptor_extractor = DescriptorExtractor::create("SURF");
// // 	DescriptorMatcher::create()函式的引數如下,對應不同的匹配演算法:
// // 		– BruteForce(it uses L2)
// // 		– BruteForce - L1
// // 		– BruteForce - Hamming
// // 		– BruteForce - Hamming(2)
// // 		– FlannBased
	Ptr<DescriptorMatcher> descriptor_matcher = DescriptorMatcher::create("BruteForce");//建立特徵匹配器,暴力匹配(簡單匹配)  
// 	if (detector.empty() || descriptor_extractor.empty())
// 		cout << "fail to create detector!";

	//讀入影象  
	Mat img1 = imread("001.jpg", 0);
	Mat img2 = imread("004.bmp", 0);

	if (img1.empty() || img1.channels() != 1)
		MessageBox(L"影象型別錯誤");
		//CV_Error(Error::StsBadArg, "image is empty or has incorrect depth (!=CV_8U)");

	//if (!mask.empty() && mask.type() != CV_8UC1)
		//CV_Error(Error::StsBadArg, "mask has incorrect type (!=CV_8UC1)");

	//特徵點檢測  
	double t = getTickCount();//當前滴答數  
	vector<KeyPoint> keypoints1, keypoints2;
	keypoints1.resize(100);
	keypoints2.resize(100);
detector->detect(img1, keypoints1);//檢測img1中的SIFT特徵點,儲存到keypoints1中 detector->detect(img2, keypoints2); //detector.detect(img1, keypoints1); //detector.detect(img2, keypoints2); // cout << "影象1特徵點個數:" << keypoints1.size() << endl; // cout << "影象2特徵點個數:" << keypoints2.size() << endl; // // //根據特徵點計算特徵描述子矩陣,即特徵向量矩陣 Mat descriptors1, descriptors2; descriptor_extractor->compute(img1, keypoints1, descriptors1); descriptor_extractor->compute(img2, keypoints2, descriptors2); // t = ((double)getTickCount() - t) / getTickFrequency(); // cout << "SIFT演算法用時:" << t << "秒" << endl; // // // cout << "影象1特徵描述矩陣大小:" << descriptors1.size() // << ",特徵向量個數:" << descriptors1.rows << ",維數:" << descriptors1.cols << endl; // cout << "影象2特徵描述矩陣大小:" << descriptors2.size() // << ",特徵向量個數:" << descriptors2.rows << ",維數:" << descriptors2.cols << endl; // // //畫出特徵點 Mat img_keypoints1, img_keypoints2; drawKeypoints(img1, keypoints1, img_keypoints1, Scalar::all(-1), 0); drawKeypoints(img2, keypoints2, img_keypoints2, Scalar::all(-1), 0); imshow("Src1",img_keypoints1); imshow("Src2",img_keypoints2); waitKey(0); //特徵匹配 vector<DMatch> matches;//匹配結果 matches.resize(100); descriptor_matcher->match(descriptors1, descriptors2, matches);//匹配兩個影象的特徵矩陣 cout << "Match個數:" << matches.size() << endl; //計算匹配結果中距離的最大和最小值 //距離是指兩個特徵向量間的歐式距離,表明兩個特徵的差異,值越小表明兩個特徵點越接近 double max_dist = 0; double min_dist = 100; for (int i = 0; i < matches.size(); i++) { double dist = matches[i].distance; if (dist < min_dist) min_dist = dist; if (dist > max_dist) max_dist = dist; } cout << "最大距離:" << max_dist << endl; cout << "最小距離:" << min_dist << endl; //篩選出較好的匹配點 vector<DMatch> goodMatches; for (int i = 0; i < matches.size(); i++) { if (matches[i].distance < 0.5 * max_dist) { goodMatches.push_back(matches[i]); } } cout << "goodMatch個數:" << goodMatches.size() << endl; //畫出匹配結果 Mat img_matches; //紅色連線的是匹配的特徵點對,綠色是未匹配的特徵點 drawMatches(img1, keypoints1, img2, keypoints2, goodMatches, img_matches, /*Scalar::all(-1)/ **/CV_RGB(255,0,0), CV_RGB(0, 255, 0), Mat(), 2); namedWindow("MatchSIFT", 0); imshow("MatchSIFT", img_matches); waitKey(0);