vector< Point2f > getKeys( Mat& img_scene ){ detector.detect( img_scene, keypoints_scene ); LOGI("Keypoints detected"); vector<Point2f> currFrameKeys; for( int i = 0 ; i < keypoints_scene.size() ; i++ ){ currFrameKeys.push_back(keypoints_scene[i].pt); } return currFrameKeys; }
//c'tor OFFeatureMatcher::OFFeatureMatcher( bool _use_gpu, std::vector<cv::Mat>& imgs_, std::vector<std::vector<cv::KeyPoint> >& imgpts_) : AbstractFeatureMatcher(_use_gpu),imgpts(imgpts_), imgs(imgs_) { //detect keypoints for all images FastFeatureDetector ffd; // DenseFeatureDetector ffd; ffd.detect(imgs, imgpts); }
//c'tor OFFeatureMatcher::OFFeatureMatcher(const std::vector<cv::Mat>& imgs, std::vector<std::vector<cv::KeyPoint> >& imgpts, bool precached, bool use_gpu) : AbstractFeatureMatcher(use_gpu), _imgpts(imgpts), _imgs(imgs) { assert(imgpts.size() == imgs.size()); FastFeatureDetector ffd; for (unsigned i = 0, imax = _imgs.size(); i < imax; ++i) { if (precached && !_imgpts[i].empty()) continue; ffd.detect(_imgs[i], _imgpts[i]); } }
int main(int argc, char** argv) { if( argc < 2 ) { printPrompt( argv[0] ); return -1; } initModule_nonfree(); // Get Input Data ifstream file(argv[1]); if ( !file.is_open() ) return false; string str; // Image Name getline( file, str ); getline( file, str ); string image_name = str; // Cloud Name getline( file, str ); getline( file, str ); string cloud_name = str; // width of images to be created. getline( file, str ); getline( file, str ); int w = atoi(str.c_str()); // height of images to be created getline( file, str ); getline( file, str ); int h = atoi(str.c_str()); // resolution of voxel grids getline( file, str ); getline( file, str ); float r = atof(str.c_str()); // f (distance from pinhole) getline( file, str ); getline( file, str ); float f = atof(str.c_str()); // thetax (initial rotation about X Axis of map) getline( file, str ); getline( file, str ); float thetaX = atof(str.c_str()); // thetay (initial rotation about Y Axis of map) getline( file, str ); getline( file, str ); float thetaY = atof(str.c_str()); // number of points to go to getline( file, str ); getline( file, str ); float nop = atoi(str.c_str()); // Number of divisions getline( file, str ); getline( file, str ); float divs = atoi(str.c_str()); // Number of images to return getline( file, str ); getline( file, str ); int numtoreturn = atoi(str.c_str()); // Should we load or create photos? getline( file, str ); getline( file, str ); string lorc =str.c_str(); // Directory to look for photos getline( file, str ); getline( file, str ); string dir =str.c_str(); // Directory to look for kp and descriptors getline( file, str ); getline( file, str ); string kdir =str.c_str(); // save photos? getline( file, str ); getline( file, str ); string savePhotos =str.c_str(); file.close(); // Done Getting Input Data map<vector<float>, Mat> imagemap; map<vector<float>, Mat> surfmap; map<vector<float>, Mat> siftmap; map<vector<float>, Mat> orbmap; map<vector<float>, Mat> fastmap; imagemap.clear(); vector<KeyPoint> SurfKeypoints; vector<KeyPoint> SiftKeypoints; vector<KeyPoint> OrbKeypoints; vector<KeyPoint> FastKeypoints; Mat SurfDescriptors; Mat SiftDescriptors; Mat OrbDescriptors; Mat FastDescriptors; int minHessian = 300; SurfFeatureDetector SurfDetector (minHessian); SiftFeatureDetector SiftDetector (minHessian); OrbFeatureDetector OrbDetector (minHessian); FastFeatureDetector FastDetector (minHessian); SurfDescriptorExtractor SurfExtractor; SiftDescriptorExtractor SiftExtractor; OrbDescriptorExtractor OrbExtractor; if ( !fs::exists( dir ) || lorc == "c" ) { // Load Point Cloud and render images PointCloud<PT>::Ptr cloud (new pcl::PointCloud<PT>); io::loadPCDFile<PT>(cloud_name, *cloud); Eigen::Affine3f tf = Eigen::Affine3f::Identity(); tf.rotate (Eigen::AngleAxisf (thetaX, Eigen::Vector3f::UnitX())); pcl::transformPointCloud (*cloud, *cloud, tf); tf = Eigen::Affine3f::Identity(); tf.rotate (Eigen::AngleAxisf (thetaY, Eigen::Vector3f::UnitY())); pcl::transformPointCloud (*cloud, *cloud, tf); // Create images from point cloud imagemap = render::createImages(cloud, nop, w, h, r, f); if (savePhotos == "y") { for (map<vector<float>, Mat>::iterator i = imagemap.begin(); i != imagemap.end(); ++i) { // Create image name and storagename string imfn = dir + "/"; string kpfn = kdir + "/"; for (int j = 0; j < i->first.size(); j++) { imfn += boost::to_string(i->first[j]) + " "; kpfn += boost::to_string(i->first[j]) + " "; } imfn += ".jpg"; imwrite(imfn, i->second); // Detect keypoints, add to keypoint map. Same with descriptors SurfDetector.detect(i->second, SurfKeypoints); SiftDetector.detect(i->second, SiftKeypoints); OrbDetector.detect(i->second, OrbKeypoints); FastDetector.detect(i->second, FastKeypoints); SurfExtractor.compute(i->second, SurfKeypoints, SurfDescriptors); SiftExtractor.compute(i->second, SiftKeypoints, SiftDescriptors); OrbExtractor.compute(i->second, OrbKeypoints, OrbDescriptors); SiftExtractor.compute(i->second, FastKeypoints, FastDescriptors); // Store KP and Descriptors in yaml file. kpfn += ".yml"; FileStorage store(kpfn, cv::FileStorage::WRITE); write(store,"SurfKeypoints",SurfKeypoints); write(store,"SiftKeypoints",SiftKeypoints); write(store,"OrbKeypoints", OrbKeypoints); write(store,"FastKeypoints",FastKeypoints); write(store,"SurfDescriptors",SurfDescriptors); write(store,"SiftDescriptors",SiftDescriptors); write(store,"OrbDescriptors", OrbDescriptors); write(store,"FastDescriptors",FastDescriptors); store.release(); surfmap[i->first] = SurfDescriptors; siftmap[i->first] = SiftDescriptors; orbmap[i->first] = OrbDescriptors; fastmap[i->first] = FastDescriptors; } } } else { // load images from the folder dir // First look into the folder to get a list of filenames vector<fs::path> ret; const char * pstr = dir.c_str(); fs::path p(pstr); get_all(pstr, ret); for (int i = 0; i < ret.size(); i++) { // Load Image via filename string fn = ret[i].string(); istringstream iss(fn); vector<string> tokens; copy(istream_iterator<string>(iss), istream_iterator<string>(), back_inserter<vector<string> >(tokens)); // Construct ID from filename vector<float> ID; for (int i = 0; i < 6; i++) // 6 because there are three location floats and three direction floats ID.push_back(::atof(tokens[i].c_str())); string imfn = dir + "/" + fn; // Read image and add to imagemap. Mat m = imread(imfn); imagemap[ID] = m; // Create Filename for loading Keypoints and descriptors string kpfn = kdir + "/"; for (int j = 0; j < ID.size(); j++) { kpfn += boost::to_string(ID[j]) + " "; } kpfn = kpfn+ ".yml"; // Create filestorage item to read from and add to map. FileStorage store(kpfn, cv::FileStorage::READ); FileNode n1 = store["SurfKeypoints"]; read(n1,SurfKeypoints); FileNode n2 = store["SiftKeypoints"]; read(n2,SiftKeypoints); FileNode n3 = store["OrbKeypoints"]; read(n3,OrbKeypoints); FileNode n4 = store["FastKeypoints"]; read(n4,FastKeypoints); FileNode n5 = store["SurfDescriptors"]; read(n5,SurfDescriptors); FileNode n6 = store["SiftDescriptors"]; read(n6,SiftDescriptors); FileNode n7 = store["OrbDescriptors"]; read(n7,OrbDescriptors); FileNode n8 = store["FastDescriptors"]; read(n8,FastDescriptors); store.release(); surfmap[ID] = SurfDescriptors; siftmap[ID] = SiftDescriptors; orbmap[ID] = OrbDescriptors; fastmap[ID] = FastDescriptors; } } TickMeter tm; tm.reset(); cout << "<\n Analyzing Images ..." << endl; // We have a bunch of images, now we compute their grayscale and black and white. map<vector<float>, Mat> gsmap; map<vector<float>, Mat> bwmap; for (map<vector<float>, Mat>::iterator i = imagemap.begin(); i != imagemap.end(); ++i) { vector<float> ID = i->first; Mat Image = i-> second; GaussianBlur( Image, Image, Size(5,5), 0, 0, BORDER_DEFAULT ); gsmap[ID] = averageImage::getPixSumFromImage(Image, divs); bwmap[ID] = averageImage::aboveBelow(gsmap[ID]); } Mat image = imread(image_name); Mat gsimage = averageImage::getPixSumFromImage(image, divs); Mat bwimage = averageImage::aboveBelow(gsimage); // cout << gsimage <<endl; imwrite("GS.png", gsimage); namedWindow("GSIMAGE (Line 319)"); imshow("GSIMAGE (Line 319)", gsimage); waitKey(0); vector<KeyPoint> imgSurfKeypoints; vector<KeyPoint> imgSiftKeypoints; vector<KeyPoint> imgOrbKeypoints; vector<KeyPoint> imgFastKeypoints; Mat imgSurfDescriptors; Mat imgSiftDescriptors; Mat imgOrbDescriptors; Mat imgFastDescriptors; SurfDetector.detect(image, imgSurfKeypoints); SiftDetector.detect(image, imgSiftKeypoints); OrbDetector.detect(image, imgOrbKeypoints); FastDetector.detect(image, imgFastKeypoints); SurfExtractor.compute(image, imgSurfKeypoints, imgSurfDescriptors); SiftExtractor.compute(image, imgSiftKeypoints, imgSiftDescriptors); OrbExtractor.compute(image, imgOrbKeypoints, imgOrbDescriptors); SiftExtractor.compute(image, imgFastKeypoints, imgFastDescriptors); tm.start(); cout << ">\n<\n Comparing Images ..." << endl; // We have their features, now compare them! map<vector<float>, float> gssim; // Gray Scale Similarity map<vector<float>, float> bwsim; // Above Below Similarity map<vector<float>, float> surfsim; map<vector<float>, float> siftsim; map<vector<float>, float> orbsim; map<vector<float>, float> fastsim; for (map<vector<float>, Mat>::iterator i = gsmap.begin(); i != gsmap.end(); ++i) { vector<float> ID = i->first; gssim[ID] = similarities::getSimilarity(i->second, gsimage); bwsim[ID] = similarities::getSimilarity(bwmap[ID], bwimage); surfsim[ID] = similarities::compareDescriptors(surfmap[ID], imgSurfDescriptors); siftsim[ID] = similarities::compareDescriptors(siftmap[ID], imgSiftDescriptors); orbsim[ID] = 0;//similarities::compareDescriptors(orbmap[ID], imgOrbDescriptors); fastsim[ID] = 0;//similarities::compareDescriptors(fastmap[ID], imgFastDescriptors); } map<vector<float>, int> top; bool gotone = false; typedef map<vector<float>, int>::iterator iter; // Choose the best ones! for (map<vector<float>, Mat>::iterator i = imagemap.begin(); i != imagemap.end(); ++i) { vector<float> ID = i->first; int sim = /* gssim[ID] + 0.5*bwsim[ID] + */ 5*surfsim[ID] + 0.3*siftsim[ID] + orbsim[ID] + fastsim[ID]; // cout << surfsim[ID] << "\t"; // cout << siftsim[ID] << "\t"; // cout << orbsim[ID] << "\t"; // cout << fastsim[ID] << endl; if (!gotone) { top[ID] = sim; gotone = true; } iter it = top.begin(); iter end = top.end(); int max_value = it->second; vector<float> max_ID = it->first; for( ; it != end; ++it) { int current = it->second; if(current > max_value) { max_value = it->second; max_ID = it->first; } } // cout << "Sim: " << sim << "\tmax_value: " << max_value << endl; if (top.size() < numtoreturn) top[ID] = sim; else { if (sim < max_value) { top[ID] = sim; top.erase(max_ID); } } } tm.stop(); double s = tm.getTimeSec(); cout << ">\n<\n Writing top " << numtoreturn << " images ..." << endl; int count = 1; namedWindow("Image"); namedWindow("Match"); namedWindow("ImageBW"); namedWindow("MatchBW"); namedWindow("ImageGS"); namedWindow("MatchGS"); imshow("Image", image); imshow("ImageBW", bwimage); imshow("ImageGS", gsimage); vector<KeyPoint> currentPoints; for (iter i = top.begin(); i != top.end(); ++i) { vector<float> ID = i->first; cout << " Score: "<< i->second << "\tGrayScale: " << gssim[ID] << "\tBW: " << bwsim[ID] << " \tSURF: " << surfsim[ID] << "\tSIFT: " << siftsim[ID] << endl; string fn = "Sim_" + boost::to_string(count) + "_" + boost::to_string(i->second) + ".png"; imwrite(fn, imagemap[ID]); count++; normalize(bwmap[ID], bwmap[ID], 0, 255, NORM_MINMAX, CV_64F); normalize(gsmap[ID], gsmap[ID], 0, 255, NORM_MINMAX, CV_64F); imshow("Match", imagemap[ID]); imshow("MatchBW", bwmap[ID]); imshow("MatchGS", gsmap[ID]); waitKey(0); } cout << ">\nComparisons took " << s << " seconds for " << imagemap.size() << " images (" << (int) imagemap.size()/s << " images per second)." << endl; return 0; }
//------------------------------------------------------------------------------ String PAN::authenticate(String CWD,String fileoutput){ Point matchLoc; float percentage, threshold; float average = 0; int count = 0; Mat big_image; big_image = panimage.img->clone();//big image resize(big_image, big_image, Size(2000, 1500)); if (!big_image.data) { std::cout << "Error reading images " << std::endl; return""; } Mat temp, temp1[3]; if (big_image.channels() >= 2){ cvtColor(big_image, temp, COLOR_BGR2GRAY); } //split(temp, temp1); big_image = temp.clone(); /*img_1 = temp2.clone(); resize(img_2, img_2, Size(600, 400)); *///-- Step 1: Detect the keypoints using SURF Detector vector<KeyPoint> keypoints_big, keypoints_small; int minHessian = 200; //FeatureDetector * detector = new SURF(); FastFeatureDetector detector; detector.detect(big_image, keypoints_big); cout << "big sift done\n\n"; //-- Step 2: Calculate descriptors (feature vectors) int Threshl = 10; int Octaves = 3; //(pyramid layer) from which the keypoint has been extracted float PatternScales = 1.0f; //declare a variable BRISKD of the type cv::BRISK Mat descriptors_2, descriptors_small; BRISK BRISKD; //BRISKD.detect(img_1, keypoints_1); //BRISKD.detect(img_2, keypoints_2); BRISKD.compute(big_image, keypoints_big, descriptors_2); cout << "big brisk done\n\n"; int i = 0; for ( i = 0; i < 7; i++){ String path(CWD); // setting up input standard containers used for matching to String temp = "win1"; temp = temp + char(i + 48) + ".jpg"; path = path + temp; Mat find = imread(path, CV_LOAD_IMAGE_UNCHANGED); //cout << path << "\n\n"; if (find.data == NULL){ break; } //templateMatch(*panimage.img, find, matchLoc, threshold, percentage); //------------------------------------------------------------------------------------- if (!find.data) { std::cout << "Error reading images " << std::endl; return ""; } if (find.channels() >= 2){ cvtColor(find,find, COLOR_BGR2GRAY); } //img_1 = temp2.clone(); resize(find ,find, Size(1200, 600)); //-- Step 1: Detect the keypoints using SURF Detector vector<KeyPoint> keypoints_small; int minHessian = 200; detector.detect(find, keypoints_small); cout << "small sift done\n\n"; //-- Step 2: Calculate descriptors (feature vectors) int Threshl = 10; int Octaves = 3; //(pyramid layer) from which the keypoint has been extracted float PatternScales = 1.0f; //declare a variable BRISKD of the type cv::BRISK Mat descriptors_small; //BRISKD.detect(img_1, keypoints_1); //BRISKD.detect(img_2, keypoints_2); BRISKD.compute(find, keypoints_small, descriptors_small); cout << "brisk done\n\n"; //------------------------------------------------------------------------------------- //-- Step 3: Matching descriptor vectors using FLANN matcher //FlannBasedMatcher matcher; BFMatcher matcher; std::vector< DMatch > matches; matcher.match(descriptors_small, descriptors_2, matches); cv::Mat all_matches; drawMatches(find, keypoints_small, big_image, keypoints_big, matches, all_matches, cv::Scalar::all(-1), cv::Scalar::all(-1), vector<char>(), cv::DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS); namedWindow("BRISK", CV_WINDOW_NORMAL); imshow("BRISK", all_matches); cv::waitKey(0); double max_dist = 0; double min_dist = 800; //-- Quick calculation of max and min distances between keypoints for (int i = 0; i < descriptors_small.rows; i++) { double dist = matches[i].distance; if (dist < min_dist) min_dist = dist; if (dist > max_dist) max_dist = dist; } //-- Draw only "good" matches (i.e. whose distance is less than 2*min_dist, //-- or a small arbitary value ( 0.02 ) in the event that min_dist is very //-- small) //-- PS.- radiusMatch can also be used here. std::vector< DMatch > good_matches; for (int i = 0; i < descriptors_small.rows; i++) { if (matches[i].distance <= 1.2 * min_dist) { good_matches.push_back(matches[i]); } } //-- Draw only "good" matches Mat img_matches; drawMatches(find, keypoints_small, big_image, keypoints_big,good_matches, img_matches, Scalar::all(-1), Scalar::all(-1),vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS); ////-- Show detected matches namedWindow("Good Matches", CV_WINDOW_NORMAL); imshow("Good Matches", img_matches); waitKey(); for (int i = 0; i < (int)good_matches.size(); i++) { //printf("-- Good Match [%d] Keypoint 1: %d -- Keypoint 2: %d \n", i, good_matches[i].queryIdx, good_matches[i].trainIdx); } percentage = (float)((float)good_matches.size() / (float)matches.size()) * 100; int width, height; width = find.size().width; height = find.size().height; //cout << i + 1 << "--LOC x=" << matchLoc.x << " y=" << matchLoc.y << " % match= " << percentage << "\n"; if (percentage > 50){ average += percentage; count++; } fileoutput = fileoutput + to_string(percentage) + "$"; //cout << percentage << "$"; //rectangle(find,Rect(matchLoc.x, matchLoc.y, width, height),0,1,4,0); //removed to prevent alteration of the find image find.release(); } if (count != 0){ average /= count; } else { average = 0; } //cout << "Authenticity is " << average <<"\n"; authenticity = average; fileoutput = fileoutput + to_string(average) + "$"; //cout << to_string(average) << "$"; cout << fileoutput; if (i == 0){ cout << "database not loaded"; } return fileoutput; }