c++ - Access violation reading in FeatureDetector OpenCV 2.4.5 -
i tried sample codes matching many images in opencv 2.4.5 , modified code. found error code:
unhandled exception @ 0x585a7090 in testing.exe: 0xc0000005: access violation reading location 0x00000000.
its fault @ featuredetector->detect(queryimage, querykeypoints)
.
i can't find solution problem. please 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 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 read." << endl; return false; } // end if int readimagecount = 0; for(size_t = 0; < 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 read." << endl; } else { readimagecount++; }// end if trainimages.push_back(img); } // end if(!readimagecount) { cout << "all train images can not read." << endl; return false; } else { cout << readimagecount << " train images 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 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 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 read." << endl; return false; } // end if int readimagecount = 0; for(size_t = 0; < 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 read." << endl; } else { readimagecount++; }// end if trainimages.push_back(img); } // end if(!readimagecount) { cout << "all train images can not read." << endl; return false; } else { cout << readimagecount << " train images read." << endl; } cout << endl; return true; } static void detectkeypoints(const mat& queryimage, vector<keypoint>& querykeypoints, ptr<featuredetector>& featuredetector){ cout << endl << "extracting keypoints 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 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 read." << endl; return false; } // end if int readimagecount = 0; for(size_t = 0; < 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 read." << endl; } else { readimagecount++; }// end if trainimages.push_back(img); } // end if(!readimagecount) { cout << "all train images can not read." << endl; return false; } else { cout << readimagecount << " train images read." << endl; } cout << endl; return true; } static void detectkeypoints(const mat& queryimage, vector<keypoint>& querykeypoints, ptr<featuredetector>& featuredetector){ cout << endl << "extracting keypoints 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 , 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 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 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 read." << endl; return false; } // end if int readimagecount = 0; for(size_t = 0; < 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 read." << endl; } else { readimagecount++; }// end if trainimages.push_back(img); } // end if(!readimagecount) { cout << "all train images can not read." << endl; return false; } else { cout << readimagecount << " train images 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 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 , 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 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 matcher , match query descriptors 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 = 0; < 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 saved (may because directory " << resultdir << " 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 = 0; < 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
the documentation class featuredetector
says, abstract base class, means should not able create instance of class. opencv's fault, compiler not complaining!
try adding:
ptr<featuredetector> featuredetector = featuredetector::create(defaultdetectortype);
update:
my next suggestion reduce complexity. simplify main program until have minimal working version:
int main() { cv::initmodule_nonfree(); // 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 above version works, start adding more functionality (slowly), until arrive @ current version. moment error comes back, know last added part culprit , can focus on that.
if above version not work, have @ least created sscce, can try fix (with of others).
btw: error message telling you, program trying read memory location 0x00000000
indicator, using uninitialized data structure, not sure problem in program.
Comments
Post a Comment