问题
I tried the sample codes about matching to many images in OpenCV 2.4.5 and I modified that code. I found the error code:
Unhandled exception at 0x585a7090 in testing.exe:
0xC0000005: Access violation reading location 0x00000000.
Its fault is at featureDetector->detect(queryImage, queryKeypoints)
.
I can't find the solution from that problem. Please help me.
#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
Update:
#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
SOLVED PROBLEMS:
#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
COMPLETE SAMPLE CODES MATCHING TO MANY IMAGES:
#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:
The documentation for class FeatureDetector
says, that it is an abstract base class, which means that you should not be able to create an instance of that class. It is OpenCV's fault, that the compiler is not complaining!
Try adding:
Ptr<FeatureDetector> featureDetector = FeatureDetector::create(defaultDetectorType);
Update:
My next suggestion would be to reduce complexity. Simplify the main program until you have a minimal working version:
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);
}
If the above version works, start adding more functionality (slowly), until you arrive at your current version. The moment the error comes back, you know that the last added part is the culprit and you can focus on that.
If the above version does not work, you have at least created a SSCCE, which you can try to fix (with the help of others).
BTW: The error message is telling you, that your program is trying to read memory location 0x00000000
which is an indicator, that you are using an uninitialized data structure, but I am not sure where the problem is in your program.
回答2:
It seems that you did not initialize Ptr<FeatureDetector> featureDetector;
anywhere, it is an abstract class
来源:https://stackoverflow.com/questions/16516023/access-violation-reading-in-featuredetector-opencv-2-4-5