OpenCV SITF 特徵提取 FeatureDetector物件函式detect執行報錯解決方案
阿新 • • 發佈:2019-01-04
本人在使用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);