2013-05-13 33 views
4

我嘗試了與OpenCV 2.4.5中的許多圖像匹配的示例代碼,我修改了該代碼。我找到了錯誤代碼:在FeatureDetector OpenCV 2.4.5中訪問衝突閱讀

Unhandled exception at 0x585a7090 in testing.exe: 
0xC0000005: Access violation reading location 0x00000000. 

它的錯誤在。

我無法從該問題中找到解決方案。 請幫幫我。

#include <opencv2\highgui\highgui.hpp> 
#include <opencv2\features2d\features2d.hpp> 
#include <opencv2\contrib\contrib.hpp> 
#include <iostream> 
#include <fstream> 
#include <conio.h> 
#include <string> 

using namespace std; 
using namespace cv; 

static void readTrainFilenames(const string& filename, string& dirName, vector<string>& trainFilenames); 
static bool readImages(const string& queryImageName, Mat& queryImage); 
static bool readTrainImages(const string& trainFilename, vector<Mat>& trainImages, vector<string>& trainImageNames); 
static void detectKeypoints(const Mat& queryImage, vector<KeyPoint>& queryKeypoints, 
    const vector<Mat>& trainImages, vector<vector<KeyPoint>>& trainKeypoints, Ptr<FeatureDetector>& featureDetector); 


static void readTrainFilenames(const string& filename, string& dirName, vector<string>& trainFilenames) 
{ 
    trainFilenames.clear(); 

    ifstream file(filename.c_str()); 

    if(!file.is_open()) 
    { 
     cout << "File can't open" << endl; 
     return; 
    } 

    size_t pos = filename.rfind("\\"); 
    char dlmtr = '\\'; 

    if(pos == String::npos) 
    { 
     pos = filename.rfind('/'); 
     dlmtr = '/'; 
    } 

    dirName = pos == string::npos ? "" : filename.substr(0, pos) + dlmtr; 

    while(!file.eof()) 
    { 
     string str; getline(file, str); 
     if(str.empty()) break; 
     trainFilenames.push_back(str); 
    } // end while 

    file.close(); 
} // end void readTrainFilenames 


static bool readImages(const string& queryImageName, Mat& queryImage) 
{ 
    cout << "reading images..." << endl; 
    queryImage = imread(queryImageName, CV_LOAD_IMAGE_GRAYSCALE); 
    if(queryImage.empty()) 
    { 
     cout << "query image can not be read. \n"; 
     return false; 
    } // end if 


    return true; 
} 

static bool readTrainImages(const string& trainFilename, vector<Mat>& trainImages, vector<string>& trainImageNames) 
{ 
    cout << "reading training images..." << endl; 
    string trainDirName = "D:/matching_to_many_images/"; 

    readTrainFilenames(trainFilename, trainDirName, trainImageNames); 
    if(trainImageNames.empty()) 
    { 
     cout << "Train image filenames can not be read." << endl; 
     return false; 
    } // end if 

    int readImageCount = 0; 
    for(size_t i = 0; i < trainImageNames.size(); i++) 
    { 
     string filename = trainDirName + trainImageNames[i]; 
     Mat img = imread(filename, CV_LOAD_IMAGE_GRAYSCALE); 
     if(img.empty()) 
     { 
      cout << "Train image " << filename << " can not be read." << endl; 
     } 
     else 
     { 
      readImageCount++; 
     }// end if 

     trainImages.push_back(img); 
    } // end for 

    if(!readImageCount) 
    { 
     cout << "All train images can not be read." << endl; 
     return false; 
    } 
    else 
    { 
     cout << readImageCount << " train images were read." << endl; 
    } 

    cout << endl; 

    return true; 
} 

static void detectKeypoints(const Mat& queryImage, vector<KeyPoint>& queryKeypoints, 
          const vector<Mat>& trainImages, 
          vector<vector<KeyPoint>>& trainKeypoints, 
          Ptr<FeatureDetector>& featureDetector){ 
    cout << endl << "Extracting keypoints from images..." << endl; 

    try{ 
     featureDetector->detect(queryImage, queryKeypoints); 
    } 
    catch(Ptr<FeatureDetector> a) 
    { 
     cout << "hmm" << endl; 
    } 

    cout << endl; 
} // end void detectKeypoints 

int main() 
{ 
    const string defaultDetectorType = "SURF"; 
    const string defaultDescriptorType = "SURF"; 
    const string defaultMatcherType = "FlannBased"; 
    const string defaultQueryImageName = "D:/matching_to_many_images/query.png"; 
    const string defaultFileWithTrainImages = "D:/matching_to_many_images/train/trainImages.txt"; 
    const string defaultDirToSaveResImages = "D:/matching_to_many_images/results"; 

    Ptr<FeatureDetector> featureDetector; 
    Ptr<DescriptorExtractor> descriptorExtractor; 
    Ptr<DescriptorMatcher> descriptorMatcher; 

    Mat queryImages; 
    vector<Mat> trainImages; 
    vector<string> trainImagesNames; 

    vector<KeyPoint> queryKeypoints; 
    vector<vector<KeyPoint>> trainKeypoints; 

    if(!readImages(defaultQueryImageName, queryImages)) 
    { 
     _getch(); 
     return -1; 
    } // end if 

    if(!readTrainImages(defaultFileWithTrainImages, trainImages, trainImagesNames)) 
    { 
     _getch(); 
     return -1; 
    } 

    detectKeypoints(queryImages, queryKeypoints, trainImages, trainKeypoints, featureDetector); 

    cout << "\n done \n"; 
    _getch(); 
    return 0; 
} // end main method 

更新:

#include <opencv2\highgui\highgui.hpp> 
#include <opencv2\features2d\features2d.hpp> 
#include <opencv2\contrib\contrib.hpp> 
#include <iostream> 
#include <fstream> 
#include <conio.h> 
#include <string> 

using namespace std; 
using namespace cv; 

static void readTrainFilenames(const string& filename, string& dirName, vector<string>& trainFilenames); 
static bool readImages(const string& queryImageName, Mat& queryImage); 
static bool readTrainImages(const string& trainFilename, vector<Mat>& trainImages, vector<string>& trainImageNames); 
static void detectKeypoints(const Mat& queryImage, vector<KeyPoint>& queryKeypoints, Ptr<FeatureDetector>& featureDetector); 


static void readTrainFilenames(const string& filename, string& dirName, vector<string>& trainFilenames) 
{ 
    trainFilenames.clear(); 

    ifstream file(filename.c_str()); 

    if(!file.is_open()) 
    { 
     cout << "File can't open" << endl; 
     return; 
    } 

    size_t pos = filename.rfind("\\"); 
    char dlmtr = '\\'; 

    if(pos == String::npos) 
    { 
     pos = filename.rfind('/'); 
     dlmtr = '/'; 
    } 

    dirName = pos == string::npos ? "" : filename.substr(0, pos) + dlmtr; 

    while(!file.eof()) 
    { 
     string str; getline(file, str); 
     if(str.empty()) break; 
     trainFilenames.push_back(str); 
    } // end while 

    file.close(); 
} // end void readTrainFilenames 


static bool readImages(const string& queryImageName, Mat& queryImage) 
{ 
    cout << "reading images..." << endl; 
    queryImage = imread(queryImageName, CV_LOAD_IMAGE_GRAYSCALE); 
    if(queryImage.empty()) 
    { 
     cout << "query image can not be read. \n"; 
     return false; 
    } // end if 


    return true; 
} 

static bool readTrainImages(const string& trainFilename, vector<Mat>& trainImages, vector<string>& trainImageNames) 
{ 
    cout << "reading training images..." << endl; 
    string trainDirName = "D:/matching_to_many_images/"; 

    readTrainFilenames(trainFilename, trainDirName, trainImageNames); 
    if(trainImageNames.empty()) 
    { 
     cout << "Train image filenames can not be read." << endl; 
     return false; 
    } // end if 

    int readImageCount = 0; 
    for(size_t i = 0; i < trainImageNames.size(); i++) 
    { 
     string filename = trainDirName + trainImageNames[i]; 
     Mat img = imread(filename, CV_LOAD_IMAGE_GRAYSCALE); 
     if(img.empty()) 
     { 
      cout << "Train image " << filename << " can not be read." << endl; 
     } 
     else 
     { 
      readImageCount++; 
     }// end if 

     trainImages.push_back(img); 
    } // end for 

    if(!readImageCount) 
    { 
     cout << "All train images can not be read." << endl; 
     return false; 
    } 
    else 
    { 
     cout << readImageCount << " train images were read." << endl; 
    } 

    cout << endl; 

    return true; 
} 

static void detectKeypoints(const Mat& queryImage, vector<KeyPoint>& queryKeypoints, Ptr<FeatureDetector>& featureDetector){ 
    cout << endl << "Extracting keypoints from images..." << endl; 

    featureDetector->detect(queryImage, queryKeypoints); 


    cout << endl; 
} // end void detectKeypoints 

int main() 
{ 
    const string defaultDetectorType = "SURF"; 
    const string defaultDescriptorType = "SURF"; 
    const string defaultMatcherType = "FlannBased"; 
    const string defaultQueryImageName = "D:/matching_to_many_images/query.png"; 
    const string defaultFileWithTrainImages = "D:/matching_to_many_images/train/trainImages.txt"; 
    const string defaultDirToSaveResImages = "D:/matching_to_many_images/results"; 

    Ptr<FeatureDetector> featureDetector; 
    Ptr<DescriptorExtractor> descriptorExtractor; 
    Ptr<DescriptorMatcher> descriptorMatcher; 

    Mat queryImages; 
    vector<Mat> trainImages; 
    vector<string> trainImagesNames; 

    vector<KeyPoint> queryKeypoints; 
    vector<vector<KeyPoint>> trainKeypoints; 

    if(!readImages(defaultQueryImageName, queryImages)) 
    { 
     _getch(); 
     return -1; 
    } // end if 

    if(!readTrainImages(defaultFileWithTrainImages, trainImages, trainImagesNames)) 
    { 
     _getch(); 
     return -1; 
    } 

    detectKeypoints(queryImages, queryKeypoints, featureDetector); 

    cout << "\n done \n"; 
    _getch(); 
    return 0; 
} // end main method 

亟待解決的問題:

#include <opencv2\highgui\highgui.hpp> 
#include <opencv2\features2d\features2d.hpp> 
#include <opencv2\contrib\contrib.hpp> 
#include <opencv2\nonfree\nonfree.hpp> 
#include <iostream> 
#include <fstream> 
#include <conio.h> 
#include <string> 

using namespace std; 
using namespace cv; 

const string defaultDetectorType = "SURF"; 
const string defaultDescriptorType = "SURF"; 
const string defaultMatcherType = "FlannBased"; 
const string defaultQueryImageName = "D:/matching_to_many_images/query.png"; 
const string defaultFileWithTrainImages = "D:/matching_to_many_images/train/trainImages.txt"; 
const string defaultDirToSaveResImages = "D:/matching_to_many_images/results"; 

static void readTrainFilenames(const string& filename, string& dirName, vector<string>& trainFilenames); 
static bool readImages(const string& queryImageName, Mat& queryImage); 
static bool readTrainImages(const string& trainFilename, vector<Mat>& trainImages, vector<string>& trainImageNames); 
static void detectKeypoints(const Mat& queryImage, vector<KeyPoint>& queryKeypoints, Ptr<FeatureDetector>& featureDetector); 
static bool createDetectorDescriptorMatcher(const string& detectorType, 
             const string& descriptorType, 
             const string& matcherType, 
             Ptr<FeatureDetector>& featureDetector, 
             Ptr<DescriptorExtractor>& descriptorExtractor, 
             Ptr<DescriptorMatcher>& descriptorMatcher); 

static void readTrainFilenames(const string& filename, string& dirName, vector<string>& trainFilenames) 
{ 
    trainFilenames.clear(); 

    ifstream file(filename.c_str()); 

    if(!file.is_open()) 
    { 
     cout << "File can't open" << endl; 
     return; 
    } 

    size_t pos = filename.rfind("\\"); 
    char dlmtr = '\\'; 

    if(pos == String::npos) 
    { 
     pos = filename.rfind('/'); 
     dlmtr = '/'; 
    } 

    dirName = pos == string::npos ? "" : filename.substr(0, pos) + dlmtr; 

    while(!file.eof()) 
    { 
     string str; getline(file, str); 
     if(str.empty()) break; 
     trainFilenames.push_back(str); 
    } // end while 

    file.close(); 
} // end void readTrainFilenames 


static bool readImages(const string& queryImageName, Mat& queryImage) 
{ 
    cout << "reading images..." << endl; 
    queryImage = imread(queryImageName, CV_LOAD_IMAGE_GRAYSCALE); 
    if(queryImage.empty()) 
    { 
     cout << "query image can not be read. \n"; 
     return false; 
    } // end if 


    return true; 
} 

static bool readTrainImages(const string& trainFilename, vector<Mat>& trainImages, vector<string>& trainImageNames) 
{ 
    cout << "reading training images..." << endl; 
    string trainDirName = "D:/matching_to_many_images/"; 

    readTrainFilenames(trainFilename, trainDirName, trainImageNames); 
    if(trainImageNames.empty()) 
    { 
     cout << "Train image filenames can not be read." << endl; 
     return false; 
    } // end if 

    int readImageCount = 0; 
    for(size_t i = 0; i < trainImageNames.size(); i++) 
    { 
     string filename = trainDirName + trainImageNames[i]; 
     Mat img = imread(filename, CV_LOAD_IMAGE_GRAYSCALE); 
     if(img.empty()) 
     { 
      cout << "Train image " << filename << " can not be read." << endl; 
     } 
     else 
     { 
      readImageCount++; 
     }// end if 

     trainImages.push_back(img); 
    } // end for 

    if(!readImageCount) 
    { 
     cout << "All train images can not be read." << endl; 
     return false; 
    } 
    else 
    { 
     cout << readImageCount << " train images were read." << endl; 
    } 

    cout << endl; 

    return true; 
} 

static void detectKeypoints(const Mat& queryImage, vector<KeyPoint>& queryKeypoints, Ptr<FeatureDetector>& featureDetector){ 
    cout << endl << "Extracting keypoints from images..." << endl; 

    if(queryImage.empty()) 
    { 
     cout << "Query Image EMPTY" << endl; 
    } 
    else{ 
     cout << "Query Image FILLED" << endl; 
    } 

    featureDetector->detect(queryImage, queryKeypoints); 


    cout << endl; 
} // end void detectKeypoints 

static bool createDetectorDescriptorMatcher(const string& detectorType, 
             const string& descriptorType, 
             const string& matcherType, 
             Ptr<FeatureDetector>& featureDetector, 
             Ptr<DescriptorExtractor>& descriptorExtractor, 
             Ptr<DescriptorMatcher>& descriptorMatcher) 
{ 
    cout << "Creating feature detector, descriptor extractor and descriptor matcher ... " << endl; 
    featureDetector = FeatureDetector::create(detectorType); 
    descriptorExtractor = DescriptorExtractor::create(descriptorType); 
    descriptorMatcher = DescriptorMatcher::create(matcherType); 
    cout << endl; 

    if(featureDetector.empty()) 
    { 
     cout << "feature detector empty" << endl; 
    } 

    if(descriptorExtractor.empty()) 
    { 
     cout << "descriptor extractor empty" << endl; 
    } 

    if(descriptorMatcher.empty()) 
    { 
     cout << "descriptor matcher empty" << endl; 
    } 

    bool isCreated = !(featureDetector.empty() || descriptorExtractor.empty() || descriptorMatcher.empty()); 

    if(!isCreated) 
    { 
     cout << "can not create feature detector or descriptor extractor or descriptor matcher of given types." << endl; 
    } // end if 

    return isCreated; 
} // end void createDetectorDescriptorMatcher 

int main() 
{ 
    initModule_nonfree(); 
    string detectorType = defaultDetectorType; 
    string descriptorType = defaultDetectorType; 
    string matcherType = defaultMatcherType; 
    string queryImageName = defaultQueryImageName; 
    string fileWithTrainImages = defaultFileWithTrainImages; 
    string dirToSaveResImages = defaultDirToSaveResImages; 

    Ptr<FeatureDetector> featureDetector = FeatureDetector::create("SURF"); 
    Ptr<DescriptorExtractor> descriptorExtractor = DescriptorExtractor::create("SURF"); 
    Ptr<DescriptorMatcher> descriptorMatcher; 

    if(!createDetectorDescriptorMatcher(detectorType, descriptorType, matcherType, featureDetector, descriptorExtractor, descriptorMatcher)) 
    { 

     _getch(); 
     return -1; 
    } 


    Mat queryImages; 
    vector<Mat> trainImages; 
    vector<string> trainImagesNames; 

    vector<KeyPoint> queryKeypoints; 
    vector<vector<KeyPoint>> trainKeypoints; 

    if(!readImages(defaultQueryImageName, queryImages)) 
    { 
     _getch(); 
     return -1; 
    } // end if 

    if(!readTrainImages(defaultFileWithTrainImages, trainImages, trainImagesNames)) 
    { 
     _getch(); 
     return -1; 
    } 

    detectKeypoints(queryImages, queryKeypoints, featureDetector); 

    cout << "\n done \n"; 
    _getch(); 
    return 0; 
} // end main method 

完整示例代碼相匹配的許多圖像:

#include <opencv2\highgui\highgui.hpp> 
#include <opencv2\features2d\features2d.hpp> 
#include <opencv2\contrib\contrib.hpp> 
#include <opencv2\nonfree\nonfree.hpp> 
#include <iostream> 
#include <fstream> 
#include <conio.h> 
#include <string> 

using namespace std; 
using namespace cv; 

const string defaultDetectorType = "SURF"; 
const string defaultDescriptorType = "SURF"; 
const string defaultMatcherType = "FlannBased"; 
const string defaultQueryImageName = "D:/matching_to_many_images/query.png"; 
const string defaultFileWithTrainImages = "D:/matching_to_many_images/train/trainImages.txt"; 
const string defaultDirToSaveResImages = "D:/matching_to_many_images/results"; 

static void readTrainFilenames(const string& filename, string& dirName, vector<string>& trainFilenames); 
static bool readImages(const string& queryImageName, Mat& queryImage); 
static bool readTrainImages(const string& trainFilename, vector<Mat>& trainImages, vector<string>& trainImageNames); 
static void detectKeypoints(const Mat& queryImage, vector<KeyPoint>& queryKeypoints, const vector<Mat>& trainImages, vector<vector<KeyPoint>>& trainKeypoints, Ptr<FeatureDetector>& featureDetector); 
static bool createDetectorDescriptorMatcher(const string& detectorType, 
             const string& descriptorType, 
             const string& matcherType, 
             Ptr<FeatureDetector>& featureDetector, 
             Ptr<DescriptorExtractor>& descriptorExtractor, 
             Ptr<DescriptorMatcher>& descriptorMatcher); 
static void computeDescriptors(const Mat& queryImage, vector<KeyPoint>& queryKeypoints, Mat& queryDescriptors, 
    const vector<Mat>& trainImages, vector<vector<KeyPoint>>& trainKeypoints, vector<Mat>& trainDescriptors, 
    Ptr<DescriptorExtractor>& descriptorExtractor); 
static void matchDescriptors(const Mat& queryDescriptors, const vector<Mat>& trainDescriptors, vector<DMatch>& matches, Ptr<DescriptorMatcher>& descriptorMatcher); 
static void maskMatchesByTrainImgIdx(const vector<DMatch>& matches, int trainImgIdx, vector<char>& mask); 

static void readTrainFilenames(const string& filename, string& dirName, vector<string>& trainFilenames) 
{ 
    trainFilenames.clear(); 

    ifstream file(filename.c_str()); 

    if(!file.is_open()) 
    { 
     cout << "File can't open" << endl; 
     return; 
    } 

    size_t pos = filename.rfind("\\"); 
    char dlmtr = '\\'; 

    if(pos == String::npos) 
    { 
     pos = filename.rfind('/'); 
     dlmtr = '/'; 
    } 

    dirName = pos == string::npos ? "" : filename.substr(0, pos) + dlmtr; 

    while(!file.eof()) 
    { 
     string str; getline(file, str); 
     if(str.empty()) break; 
     trainFilenames.push_back(str); 
    } // end while 

    file.close(); 
} // end void readTrainFilenames 


static bool readImages(const string& queryImageName, Mat& queryImage) 
{ 
    cout << "reading images..." << endl; 
    queryImage = imread(queryImageName, CV_LOAD_IMAGE_GRAYSCALE); 
    if(queryImage.empty()) 
    { 
     cout << "query image can not be read. \n"; 
     return false; 
    } // end if 


    return true; 
} 

static bool readTrainImages(const string& trainFilename, vector<Mat>& trainImages, vector<string>& trainImageNames) 
{ 
    cout << "reading training images..." << endl; 
    string trainDirName = "D:/matching_to_many_images/"; 

    readTrainFilenames(trainFilename, trainDirName, trainImageNames); 
    if(trainImageNames.empty()) 
    { 
     cout << "Train image filenames can not be read." << endl; 
     return false; 
    } // end if 

    int readImageCount = 0; 
    for(size_t i = 0; i < trainImageNames.size(); i++) 
    { 
     string filename = trainDirName + trainImageNames[i]; 
     Mat img = imread(filename, CV_LOAD_IMAGE_GRAYSCALE); 
     if(img.empty()) 
     { 
      cout << "Train image " << filename << " can not be read." << endl; 
     } 
     else 
     { 
      readImageCount++; 
     }// end if 

     trainImages.push_back(img); 
    } // end for 

    if(!readImageCount) 
    { 
     cout << "All train images can not be read." << endl; 
     return false; 
    } 
    else 
    { 
     cout << readImageCount << " train images were read." << endl; 
    } 

    cout << endl; 

    return true; 
} 

static void detectKeypoints(const Mat& queryImage, vector<KeyPoint>& queryKeypoints, const vector<Mat>& trainImages, vector<vector<KeyPoint>>& trainKeypoints, Ptr<FeatureDetector>& featureDetector){ 
    cout << endl << "Extracting keypoints from images..." << endl; 

    if(queryImage.empty()) 
    { 
     cout << "Query Image EMPTY" << endl; 
    } 
    else{ 
     cout << "Query Image FILLED" << endl; 
    } 

    featureDetector->detect(queryImage, queryKeypoints); 
    featureDetector->detect(trainImages, trainKeypoints); 

    cout << endl; 
} // end void detectKeypoints 

static bool createDetectorDescriptorMatcher(const string& detectorType, 
             const string& descriptorType, 
             const string& matcherType, 
             Ptr<FeatureDetector>& featureDetector, 
             Ptr<DescriptorExtractor>& descriptorExtractor, 
             Ptr<DescriptorMatcher>& descriptorMatcher) 
{ 
    cout << "Creating feature detector, descriptor extractor and descriptor matcher ... " << endl; 
    featureDetector = FeatureDetector::create(detectorType); 
    descriptorExtractor = DescriptorExtractor::create(descriptorType); 
    descriptorMatcher = DescriptorMatcher::create(matcherType); 
    cout << endl; 

    if(featureDetector.empty()) 
    { 
     cout << "feature detector empty" << endl; 
    } 

    if(descriptorExtractor.empty()) 
    { 
     cout << "descriptor extractor empty" << endl; 
    } 

    if(descriptorMatcher.empty()) 
    { 
     cout << "descriptor matcher empty" << endl; 
    } 

    bool isCreated = !(featureDetector.empty() || descriptorExtractor.empty() || descriptorMatcher.empty()); 

    if(!isCreated) 
    { 
     cout << "can not create feature detector or descriptor extractor or descriptor matcher of given types." << endl; 
    } // end if 

    return isCreated; 
} // end void createDetectorDescriptorMatcher 

static void computeDescriptors(const Mat& queryImage, vector<KeyPoint>& queryKeypoints, Mat& queryDescriptors, 
    const vector<Mat>& trainImages, vector<vector<KeyPoint>>& trainKeypoints, vector<Mat>& trainDescriptors, 
    Ptr<DescriptorExtractor>& descriptorExtractor) 
{ 
    cout << "computing descriptors for keypoints..." << endl; 
    descriptorExtractor->compute(queryImage, queryKeypoints, queryDescriptors); 
    descriptorExtractor->compute(trainImages, trainKeypoints, trainDescriptors); 

    int totalTrainDesc = 0; 
    for(vector<Mat>::const_iterator tdIter = trainDescriptors.begin(); tdIter != trainDescriptors.end(); tdIter++) 
     totalTrainDesc += tdIter->rows; 

    cout << "Query descriptors count : " << queryDescriptors.rows << "; Total train descriptors count : " << totalTrainDesc << endl; 
    cout << endl; 
} // end void computeDescriptors 

static void matchDescriptors(const Mat& queryDescriptors, const vector<Mat>& trainDescriptors, vector<DMatch>& matches, Ptr<DescriptorMatcher>& descriptorMatcher) 
{ 
    cout << "Set train descriptors collection in the matcher and match query descriptors to them..." << endl; 
    TickMeter tm; 
    tm.start(); 
    descriptorMatcher->add(trainDescriptors); 
    descriptorMatcher->train(); 
    tm.stop(); 
    double buildTime = tm.getTimeMilli(); 

    tm.start(); 
    descriptorMatcher->match(queryDescriptors, matches); 
    tm.stop(); 
    double matchTime = tm.getTimeMilli(); 

    CV_Assert(queryDescriptors.rows == (int)matches.size() || matches.empty()); 

    cout << "Number of matches: " << matches.size() << endl; 
    cout << "Build time: " << buildTime << " ms; Match time: " << matchTime << " ms" << endl; 
    cout << endl; 
} // end void matchDescriptors 

static void saveResultImages(const Mat& queryImage, const vector<KeyPoint>& queryKeypoints, 
    const vector<Mat>& trainImages, const vector<vector<KeyPoint>> &trainKeypoints, const vector<DMatch>& matches, 
    const vector<string>& trainImageNames, const string& resultDir) 
{ 
    cout << "Save results..." << endl; 
    Mat drawImg; 
    vector<char> mask; 
    for(size_t i = 0; i < trainImages.size(); i++) 
    { 
     if(!trainImages[i].empty()) 
     { 
      maskMatchesByTrainImgIdx(matches, (int)i, mask); 
      drawMatches(queryImage, queryKeypoints, trainImages[i], trainKeypoints[i], matches, drawImg, Scalar(255, 0, 0), Scalar(0, 255, 255), mask); 
      string filename = resultDir + "/res_" + trainImageNames[i]; 
      if(!imwrite(filename, drawImg)) 
      { 
       cout << "Image " << filename << " can not be saved (may be because directory " << resultDir << " does not exist" << endl; 
      } // end if 
     } // end if 
    } 
} // end void saveResultImages 

static void maskMatchesByTrainImgIdx(const vector<DMatch>& matches, int trainImgIdx, vector<char>& mask) 
{ 
    mask.resize(matches.size()); 
    fill(mask.begin(), mask.end(), 0); 
    for(size_t i = 0; i < matches.size(); i++) 
    { 
     if(matches[i].imgIdx == trainImgIdx) 
     { 
      mask[i] = 1; 
     } 
    } 
} // end void maskMatchesByTrainImgIdx 

int main() 
{ 
    initModule_nonfree(); 
    string detectorType = defaultDetectorType; 
    string descriptorType = defaultDetectorType; 
    string matcherType = defaultMatcherType; 
    string queryImageName = defaultQueryImageName; 
    string fileWithTrainImages = defaultFileWithTrainImages; 
    string dirToSaveResImages = defaultDirToSaveResImages; 

    Ptr<FeatureDetector> featureDetector = FeatureDetector::create("SURF"); 
    Ptr<DescriptorExtractor> descriptorExtractor = DescriptorExtractor::create("SURF"); 
    Ptr<DescriptorMatcher> descriptorMatcher; 

    if(!createDetectorDescriptorMatcher(detectorType, descriptorType, matcherType, featureDetector, descriptorExtractor, descriptorMatcher)) 
    { 

     _getch(); 
     return -1; 
    } 

    Mat queryImages; 
    vector<Mat> trainImages; 
    vector<string> trainImagesNames; 

    vector<KeyPoint> queryKeypoints; 
    vector<vector<KeyPoint>> trainKeypoints; 

    if(!readImages(defaultQueryImageName, queryImages)) 
    { 
     _getch(); 
     return -1; 
    } // end if 

    if(!readTrainImages(defaultFileWithTrainImages, trainImages, trainImagesNames)) 
    { 
     _getch(); 
     return -1; 
    } 

    detectKeypoints(queryImages, queryKeypoints, trainImages, trainKeypoints, featureDetector); 

    Mat queryDescriptors; 
    vector<Mat> trainDescriptors; 

    computeDescriptors(queryImages, queryKeypoints, queryDescriptors, trainImages, trainKeypoints, trainDescriptors, descriptorExtractor); 

    vector<DMatch> matches; 
    matchDescriptors(queryDescriptors, trainDescriptors, matches, descriptorMatcher); 

    saveResultImages(queryImages, queryKeypoints, trainImages, trainKeypoints, matches, trainImagesNames, dirToSaveResImages); 

    cout << "\n done \n"; 
    _getch(); 
    return 0; 
} // end main method 
+1

檢查*矢量 queryKeypoints *。是否初始化? – SChepurin 2013-05-13 07:56:24

+0

現在解決了。謝謝。 :) – 2013-05-13 08:04:55

回答

2

documentationFeatureDetector類說,它是一個抽象基類,這意味着你不應該能夠創建一個實例該類別。這是OpenCV的錯,編譯器不抱怨!

嘗試增加:

Ptr<FeatureDetector> featureDetector = FeatureDetector::create(defaultDetectorType); 

更新:

我的下一個建議是,以降低複雜性。簡化主程序直到你有一個最小的工作版本:

int main() 
{ 
    cv::initModule_nonfree(); // to load SURF/SIFT etc. 
    std::vector<cv::KeyPoint> queryKeypoints; 
    cv::Mat queryImage = cv::imread(FILENAME, CV_LOAD_IMAGE_GRAYSCALE); 
    cv::Ptr<FeatureDetector> featureDetector = cv::FeatureDetector::create("SURF"); 
    featureDetector->detect(queryImage, queryKeypoints); 
} 

如果以上版本的作品,開始添加更多的功能(慢),直到你在當前版本到達。錯誤恢復的那一刻,你知道最後添加的部分是罪魁禍首,你可以專注於此。

如果上述版本不起作用,您至少已創建了一個SSCCE,您可以嘗試修復(在其他人的幫助下)。

順便說一句:錯誤信息告訴你,你的程序試圖讀取內存位置0x00000000這是一個指標,你使用的是未初始化的數據結構,但我不確定問題出在你的程序中。

+0

當我添加Ptr時仍存在問題 featureDetector = FeatureDetector :: create(defaultDetectorType); – 2013-05-13 07:16:33

+0

我已經更新了我的答案。 – bjoernz 2013-05-13 07:55:30

+0

我用你的解決方案解決了這個問題。但是還有一個錯誤,必須添加cv :: initModule_nonfree()。 – 2013-05-13 08:02:12

0

看來你沒有初始化Ptr<FeatureDetector> featureDetector;任何地方,它是一個抽象類

+0

我已經初始化了。 – 2013-05-13 07:17:14