#include "ASIFT_matcher.hpp" ASIFT_matcher::ASIFT_matcher(): _nb_refs(0), _total_num_matchings(0), _resize_imgs(false), _showDebug(false) { default_sift_parameters(_siftParam); } ASIFT_matcher::ASIFT_matcher(const char* ref_path): ASIFT_matcher() { if(!loadReferences(ref_path)) { std::cerr<<"Error : Failed to load references"< ipixels1(iarr1, iarr1 + w1 * h1); // free(iarr1); /*memcheck*/ // cout<<"Size : "< image; try { image.assign(image_path); } catch(cimg_library::CImgIOException) { std::cerr << "Unable to load image file " << image_path << std::endl; return false; } //Convert to grayscale cimg_library::CImg gray(image.width(), image.height(), 1, 1, 0); cimg_forXY(image,x,y) { // Separation of channels int R = (int)image(x,y,0,0); int G = (int)image(x,y,0,1); int B = (int)image(x,y,0,2); // Arithmetic addition of channels for gray // int grayValue = (int)(0.33*R + 0.33*G + 0.33*B); // Real weighted addition of channels for gray int grayValueWeight = (int)(0.299*R + 0.587*G + 0.114*B); // saving píxel values into image information // gray(x,y,0,0) = grayValue; gray(x,y,0,0) = grayValueWeight; } std::vector ipixels1; size_t w1=gray.width(), h1=gray.height(); ipixels1.assign(gray.begin(), gray.end()); std::cout<<"Building reference from "<< image_path << std::endl; return addReference(ipixels1, w1, h1, num_tilts); // ///// Resize the images to area wS*hW in remaining the apsect-ratio // ///// Resize if the resize flag is not set or if the flag is set unequal to 0 // float wS = IM_X; // float hS = IM_Y; // float zoom1=0; // int wS1=0, hS1=0; // vector ipixels1_zoom; // if(_resize_imgs) // { // cout << "WARNING: The input image is resized to " << wS << "x" << hS << " for ASIFT. " << endl // << " But the results will be normalized to the original image size." << endl << endl; // float InitSigma_aa = 1.6; // float fproj_p, fproj_bg; // char fproj_i; // float *fproj_x4, *fproj_y4; // int fproj_o; // fproj_o = 3; // fproj_p = 0; // fproj_i = 0; // fproj_bg = 0; // fproj_x4 = 0; // fproj_y4 = 0; // float areaS = wS * hS; // // Resize image 1 // float area1 = w1 * h1; // zoom1 = sqrt(area1/areaS); // wS1 = (int) (w1 / zoom1); // hS1 = (int) (h1 / zoom1); // int fproj_sx = wS1; // int fproj_sy = hS1; // float fproj_x1 = 0; // float fproj_y1 = 0; // float fproj_x2 = wS1; // float fproj_y2 = 0; // float fproj_x3 = 0; // float fproj_y3 = hS1; // /* Anti-aliasing filtering along vertical direction */ // if ( zoom1 > 1 ) // { // float sigma_aa = InitSigma_aa * zoom1 / 2; // GaussianBlur1D(ipixels1,w1,h1,sigma_aa,1); // GaussianBlur1D(ipixels1,w1,h1,sigma_aa,0); // } // // simulate a tilt: subsample the image along the vertical axis by a factor of t. // ipixels1_zoom.resize(wS1*hS1); // fproj (ipixels1, ipixels1_zoom, w1, h1, &fproj_sx, &fproj_sy, &fproj_bg, &fproj_o, &fproj_p, // &fproj_i , fproj_x1 , fproj_y1 , fproj_x2 , fproj_y2 , fproj_x3 , fproj_y3, fproj_x4, fproj_y4); // } // else // { // ipixels1_zoom.resize(w1*h1); // ipixels1_zoom = ipixels1; // wS1 = w1; // hS1 = h1; // zoom1 = 1; // } // // image new_ref; // // new_ref.img = ipixels1_zoom; // // new_ref.width = wS1; // // new_ref.height = hS1; // ///// Compute ASIFT keypoints // asift_keypoints keys; // // vector< vector< keypointslist > >* keys = new vector< vector< keypointslist > >; // int num_keys = 0; // time_t tstart, tend; // tstart = time(0); // num_keys = compute_asift_keypoints(ipixels1_zoom, wS1, hS1, num_tilts, _showDebug, keys, _siftParam); // tend = time(0); // //Save data // _im_refs.push_back(ipixels1_zoom); // _size_refs.push_back(make_pair(wS1,hS1)); // _zoom_refs.push_back(zoom1); // _num_keys.push_back(num_keys); // _num_tilts.push_back(num_tilts); // _keys.push_back(keys); // _nb_refs++; // cout<<"Reference built in "<< difftime(tend, tstart) << " seconds." << endl; // cout<<" "<< num_keys <<" ASIFT keypoints found in "<< image_path << endl; // return true; } //Image : Gray scale image (image size = w*h) bool ASIFT_matcher::addReference(const vector& image, unsigned int w, unsigned int h, unsigned int num_tilts) { if(image.size()!=w*h) { cerr<<"Error : Input image size doesn't correspond with parameters"< ipixels1 = image; ///// Resize the images to area wS*hW in remaining the apsect-ratio ///// Resize if the resize flag is not set or if the flag is set unequal to 0 float wS = IM_X; float hS = IM_Y; float zoom1=0; int wS1=0, hS1=0; vector ipixels1_zoom; if(_resize_imgs) { cout << "WARNING: The input image is resized to " << wS << "x" << hS << " for ASIFT. " << endl << " But the results will be normalized to the original image size." << endl << endl; float InitSigma_aa = 1.6; float fproj_p, fproj_bg; char fproj_i; float *fproj_x4, *fproj_y4; int fproj_o; fproj_o = 3; fproj_p = 0; fproj_i = 0; fproj_bg = 0; fproj_x4 = 0; fproj_y4 = 0; float areaS = wS * hS; // Resize image 1 float area1 = w1 * h1; zoom1 = sqrt(area1/areaS); wS1 = (int) (w1 / zoom1); hS1 = (int) (h1 / zoom1); int fproj_sx = wS1; int fproj_sy = hS1; float fproj_x1 = 0; float fproj_y1 = 0; float fproj_x2 = wS1; float fproj_y2 = 0; float fproj_x3 = 0; float fproj_y3 = hS1; /* Anti-aliasing filtering along vertical direction */ if ( zoom1 > 1 ) { float sigma_aa = InitSigma_aa * zoom1 / 2; GaussianBlur1D(ipixels1,w1,h1,sigma_aa,1); GaussianBlur1D(ipixels1,w1,h1,sigma_aa,0); } // simulate a tilt: subsample the image along the vertical axis by a factor of t. ipixels1_zoom.resize(wS1*hS1); fproj (ipixels1, ipixels1_zoom, w1, h1, &fproj_sx, &fproj_sy, &fproj_bg, &fproj_o, &fproj_p, &fproj_i , fproj_x1 , fproj_y1 , fproj_x2 , fproj_y2 , fproj_x3 , fproj_y3, fproj_x4, fproj_y4); } else { ipixels1_zoom.resize(w1*h1); ipixels1_zoom = ipixels1; wS1 = w1; hS1 = h1; zoom1 = 1; } ///// Compute ASIFT keypoints asift_keypoints keys; int num_keys = 0; time_t tstart, tend; tstart = time(0); num_keys = compute_asift_keypoints(ipixels1_zoom, wS1, hS1, num_tilts, _showDebug, keys, _siftParam); tend = time(0); //Save data _im_refs.push_back(ipixels1_zoom); _size_refs.push_back(make_pair(wS1,hS1)); _zoom_refs.push_back(zoom1); _num_keys.push_back(num_keys); _num_tilts.push_back(num_tilts); _keys.push_back(keys); _nb_refs++; cout<<"Reference built in "<< difftime(tend, tstart) << " seconds." << endl; cout<<" "<< num_keys <<" ASIFT keypoints found."<< endl; return true; } //Return number of match unsigned int ASIFT_matcher::match(const char* image_path, unsigned int num_tilts) { if(_nb_refs<=0) { cout<<"ASIFT_matcher Error : Trying to match without reference"< ipixels1(iarr1, iarr1 + w1 * h1); // free(iarr1); /*memcheck*/ cimg_library::CImg image; try { image.assign(image_path); } catch(cimg_library::CImgIOException) { std::cerr << "Unable to load image file " << image_path << std::endl; return 0; } //Convert to grayscale cimg_library::CImg gray(image.width(), image.height(), 1, 1, 0); cimg_forXY(image,x,y) { // Separation of channels int R = (int)image(x,y,0,0); int G = (int)image(x,y,0,1); int B = (int)image(x,y,0,2); // Arithmetic addition of channels for gray // int grayValue = (int)(0.33*R + 0.33*G + 0.33*B); // Real weighted addition of channels for gray int grayValueWeight = (int)(0.299*R + 0.587*G + 0.114*B); // saving píxel values into image information // gray(x,y,0,0) = grayValue; gray(x,y,0,0) = grayValueWeight; } vector ipixels1; size_t w1=gray.width(), h1=gray.height(); ipixels1.assign(gray.begin(), gray.end()); std::cout<<"Matching from "<& image, unsigned int w, unsigned int h, unsigned int num_tilts) { if(image.size()!=w*h) { cerr<<"Error : Input image size doesn't correspond with parameters"< ipixels1 = image; ///// Resize the images to area wS*hW in remaining the apsect-ratio ///// Resize if the resize flag is not set or if the flag is set unequal to 0 float wS = IM_X; float hS = IM_Y; float zoom1=0; int wS1=0, hS1=0; vector ipixels1_zoom; if(_resize_imgs) { cout << "WARNING: The input image is resized to " << wS << "x" << hS << " for ASIFT. " << endl << " But the results will be normalized to the original image size." << endl << endl; float InitSigma_aa = 1.6; float fproj_p, fproj_bg; char fproj_i; float *fproj_x4, *fproj_y4; int fproj_o; fproj_o = 3; fproj_p = 0; fproj_i = 0; fproj_bg = 0; fproj_x4 = 0; fproj_y4 = 0; float areaS = wS * hS; // Resize image 1 float area1 = w1 * h1; zoom1 = sqrt(area1/areaS); wS1 = (int) (w1 / zoom1); hS1 = (int) (h1 / zoom1); int fproj_sx = wS1; int fproj_sy = hS1; float fproj_x1 = 0; float fproj_y1 = 0; float fproj_x2 = wS1; float fproj_y2 = 0; float fproj_x3 = 0; float fproj_y3 = hS1; /* Anti-aliasing filtering along vertical direction */ if ( zoom1 > 1 ) { float sigma_aa = InitSigma_aa * zoom1 / 2; GaussianBlur1D(ipixels1,w1,h1,sigma_aa,1); GaussianBlur1D(ipixels1,w1,h1,sigma_aa,0); } // simulate a tilt: subsample the image along the vertical axis by a factor of t. ipixels1_zoom.resize(wS1*hS1); fproj (ipixels1, ipixels1_zoom, w1, h1, &fproj_sx, &fproj_sy, &fproj_bg, &fproj_o, &fproj_p, &fproj_i , fproj_x1 , fproj_y1 , fproj_x2 , fproj_y2 , fproj_x3 , fproj_y3, fproj_x4, fproj_y4); } else { ipixels1_zoom.resize(w1*h1); ipixels1_zoom = ipixels1; wS1 = w1; hS1 = h1; zoom1 = 1; } ///// Compute ASIFT keypoints asift_keypoints keys; int num_keys = 0; time_t tstart, tend; tstart = time(0); num_keys = compute_asift_keypoints(ipixels1_zoom, wS1, hS1, num_tilts, _showDebug, keys, _siftParam); tend = time(0); cout<< "Keypoints computation accomplished in " << difftime(tend, tstart) << " seconds." << endl; cout<<" "<< num_keys <<" ASIFT keypoints found."<< endl; //// Match ASIFT keypoints _total_num_matchings=0; for(unsigned int i = 0; i<_nb_refs;i++) { int num_matchings = 0; matchingslist matchings; cout << "Matching the keypoints..." << endl; tstart = time(0); try { num_matchings = compute_asift_matches(num_tilts, _num_tilts[i], w, h, _size_refs[i].first, _size_refs[i].second, _showDebug, keys, _keys[i], matchings, _siftParam); } catch(const bad_alloc& ba) { cerr<<"ERROR: ASIFT_matcher::match - "; cerr << ba.what() << endl; } // cout<< _keys[i].size()<< " " << _keys[i][0].size() <<" "<< _keys[i][0][0].size()< upLe, doRi; //UpLeft / DownRight //Initialisation for(unsigned int i=0;i<_matchings.size();i++) { if(getNbMatchs()[i]!=0) { upLe = make_pair(_matchings[i][0].first.x,_matchings[i][0].first.y); doRi = make_pair(_matchings[i][0].first.x,_matchings[i][0].first.y); } } //Compute ROI for(unsigned int i=0;i<_matchings.size();i++) { for(unsigned int j=0;j<_matchings[i].size();j++) { keypoint kp = _matchings[i][j].first; if(kp.xdoRi.first) doRi.first=kp.x; if(kp.y>doRi.second) doRi.second=kp.y; } } x=upLe.first; //Système de coordonée ? (devrait etre bon) y=upLe.second; h=doRi.second-y; w=doRi.first-x; return true; } //Return true if successfull bool ASIFT_matcher::computeCenter(int& cx, int& cy) const { if(getNbMatch()==0) { cerr<<"Error : cannot compute Center without matchs"< > kp_euc_dist; if(computeCenter(cx,cy)) { // cout<<"Center : "< temp_euc_dist; for(unsigned int j=0;j<_matchings[i].size();j++) { keypoint kp = _matchings[i][j].first; euc_dist =sqrt((kp.x-cx)*(kp.x-cx)+(kp.y-cy)+(kp.y-cy)); dist_avg+=euc_dist; temp_euc_dist.push_back(euc_dist); } total_kp += _matchings[i].size(); kp_euc_dist.push_back(temp_euc_dist); } dist_avg/=total_kp; // cout<<"Dist avg: "< filtered_match; for(unsigned int i=0;i<_matchings.size();i++) { matchingslist new_match; for(unsigned int j=0;j<_matchings[i].size();j++) { euc_dist =kp_euc_dist[i][j]; if(euc_distx << " " << _zoom_refs[j]*ptr->y << " " << _zoom_refs[j]*ptr->scale << " " << ptr->angle; for (int ii = 0; ii < (int) VecLength; ii++) { file_key1 << " " << ptr->vec[ii]; } file_key1 << std::endl; } } } // file_key1< size_tmp; if (ref_file.is_open()) { std::getline(ref_file, line); std::string::size_type sz; // _nb_refs = std::stoi(line, &sz); //C++11 _nb_refs = atoi(line.c_str()); _keys = std::vector(_nb_refs); _num_keys = std::vector< int >(_nb_refs); _size_refs= std::vector< pair >(_nb_refs); _num_tilts = std::vector< int >(_nb_refs,1); _zoom_refs = std::vector(_nb_refs,1); for(unsigned int i = 0; i<_nb_refs;i++) { std::getline(ref_file, line); std::stringstream iss(line); std::getline(iss,tmp,' '); _num_keys[i]=atoi(tmp.c_str()); std::getline(iss,tmp,' '); if(VecLength!=atoi(tmp.c_str())) { std::cerr<<"Error VecLength doesn't correspond..."< vkps(1,list); asift_keypoints akps(1,vkps); _keys[i]=akps; // std::getline(ref_file, line); } } else { std::cerr << "Unable to open the file :"<