Ajout d'un filtre de distance par écart type

This commit is contained in:
Unknown 2018-07-25 16:29:51 +02:00
parent 075a79e60d
commit e17412e672
7 changed files with 152 additions and 26 deletions

View file

@ -308,12 +308,12 @@ bool ASIFT_matcher::match(vector<float>& image, unsigned int w, unsigned int h,
return true; return true;
} }
void ASIFT_matcher::computeROI(int& x, int& y, unsigned int& h, unsigned int& w) const bool ASIFT_matcher::computeROI(int& x, int& y, unsigned int& h, unsigned int& w) const
{ {
if(getNbMatch()==0) if(getNbMatch()==0)
{ {
cerr<<"Error : cannot compute ROI without matchs"<<endl; cerr<<"Error : cannot compute ROI without matchs"<<endl;
return; return false;
} }
pair<int,int> upLe, doRi; //UpLeft / DownRight pair<int,int> upLe, doRi; //UpLeft / DownRight
@ -348,12 +348,117 @@ void ASIFT_matcher::computeROI(int& x, int& y, unsigned int& h, unsigned int& w)
h=doRi.second-y; h=doRi.second-y;
w=doRi.first-x; w=doRi.first-x;
// x=zoom*upLe.first; //Système de coordonée ? (devrait etre bon) return true;
// y=zoom*upLe.second;
// h=zoom*(doRi.second-upLe.second);
// w=zoom*(doRi.first-upLe.first);
} }
bool ASIFT_matcher::computeCenter(int& cx, int& cy) const
{
if(getNbMatch()==0)
{
cerr<<"Error : cannot compute Center without matchs"<<endl;
return false;
}
unsigned int total_kp =0;
cx=0;cy=0;
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;
cx+=kp.x;
cy+=kp.y;
}
total_kp += _matchings[i].size();
}
cx/=total_kp;
cy/=total_kp;
return true;
}
//Filter keypoint which are far (Euclidian distance) from the center.
//Not optimized
//threshold : 1-68%/2-95%/3-99%
bool ASIFT_matcher::distFilter(int threshold=2)
{
cout<<"filtering keypoint..."<<endl;
if(getNbMatch()==0)
{
cerr<<"Error : cannot filter points without matchs"<<endl;
return false;
}
//Compute standard deviation
int cx, cy;
unsigned int total_kp =0;
unsigned int euc_dist, dist_avg =0, dist_var=0, std_dev;
vector< vector< int > > kp_euc_dist;
if(computeCenter(cx,cy))
{
// cout<<"Center : "<<cx<<" / "<<cy<<endl;
//Compute means/average distance to center + euclidian distances to center for each keypoint
for(unsigned int i=0;i<_matchings.size();i++)
{
vector<int> 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: "<<dist_avg<<endl;
//Compute variance
for(unsigned int i=0;i<_matchings.size();i++)
{
for(unsigned int j=0;j<_matchings[i].size();j++)
{
euc_dist =kp_euc_dist[i][j];
dist_var+=(euc_dist-dist_avg)*(euc_dist-dist_avg);
}
}
dist_var/=total_kp;
//Compute standard deviation
std_dev=sqrt(dist_var);
// cout<<"Standard Deviation : "<<std_dev<<endl;
//Filter
vector< matchingslist > 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_dist<dist_avg+threshold*std_dev)
{
new_match.push_back(_matchings[i][j]);
}
}
filtered_match.push_back(new_match);
_num_matchings[i]=new_match.size();
}
//Save filtered matchs
_matchings = filtered_match;
return true;
}
return false;
}
//Debugging function
void ASIFT_matcher::print() const void ASIFT_matcher::print() const
{ {
for(unsigned int i=0; i< _keys.size();i++) for(unsigned int i=0; i< _keys.size();i++)

View file

@ -39,12 +39,13 @@ public:
bool addReference(const char* image, unsigned int num_tilts=1); bool addReference(const char* image, unsigned int num_tilts=1);
bool match(const char* image, unsigned int num_tilts =1); bool match(const char* image, unsigned int num_tilts =1);
bool match(vector<float>& image, unsigned int w, unsigned int h, unsigned int num_tilts =1); bool match(vector<float>& image, unsigned int w, unsigned int h, unsigned int num_tilts =1);
void print() const; void print() const; //Debugging function
void computeROI(int& x, int& y, unsigned int& h, unsigned int& w) const; bool computeROI(int& x, int& y, unsigned int& h, unsigned int& w) const; //Compute the bounding rectangle of the keypoints
bool computeCenter(int& cx, int& cy) const;
bool distFilter(int threshold); //Filter keypoint which are far (Euclidian distance) from the center.
void setResizeImg(bool resize_imgs){ _resize_imgs=resize_imgs;} void setResizeImg(bool resize_imgs){ _resize_imgs=resize_imgs;}
void showDebug(bool showDebug){ _showDebug=showDebug;} void showDebug(bool showDebug){ _showDebug=showDebug;}
const vector < unsigned int >& getNbMatchs() const{ return _num_matchings;} const vector < unsigned int >& getNbMatchs() const{ return _num_matchings;}
unsigned int getNbMatch() const; unsigned int getNbMatch() const;
const vector< matchingslist >& getMatch() const{ return _matchings;} const vector< matchingslist >& getMatch() const{ return _matchings;}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 KiB

After

Width:  |  Height:  |  Size: 184 KiB

Before After
Before After

View file

@ -2,13 +2,14 @@
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
if ((argc !=2) && (argc != 3) && (argc != 4)) { if ((argc <2) || (argc > 5)) {
std::cerr << " ******************************************************************************* " << std::endl std::cerr << " ******************************************************************************* " << std::endl
<< " *************************** ASIFT image matching **************************** " << std::endl << " *************************** ASIFT image matching **************************** " << std::endl
<< " ******************************************************************************* " << std::endl << " ******************************************************************************* " << std::endl
<< "Usage: " << argv[0] << " imgIn.png [Tilt number option] [Resize option: 0/1] " << std::endl << "Usage: " << argv[0] << " imgIn.png [Tilt number option] [Filter option] [Resize option] " << std::endl
<< "- imgIn.png: input image (in PNG format). " << std::endl << "- imgIn.png: input image (in PNG format). " << std::endl
<< "- [Tilt number option: 1..(32+ ?)] : 8: Recommended / 1: no tilt. " << std::endl << "- [Tilt number option: 1..(32+ ?)] : 7: Recommended / 1: no tilt. " << std::endl
<< "- [Filter option: 0..3]. Standard deviation filter coeff (1-68%/2-95%/3-99%). 0: no filtering. " << std::endl
<< "- [Resize option: 0/1]. 1: input images resize to 800x600 (default). 0: no resize. " << std::endl << "- [Resize option: 0/1]. 1: input images resize to 800x600 (default). 0: no resize. " << std::endl
<< " ******************************************************************************* " << std::endl << " ******************************************************************************* " << std::endl
<< " ********************* Jean-Michel Morel, Guoshen Yu, 2010 ******************** " << std::endl << " ********************* Jean-Michel Morel, Guoshen Yu, 2010 ******************** " << std::endl
@ -36,12 +37,12 @@ int main(int argc, char **argv)
vector<float> ipixels1_zoom; vector<float> ipixels1_zoom;
int flag_resize = 1; int flag_resize = 1;
if (argc == 4) if (argc == 5)
{ {
flag_resize = atoi(argv[3]); flag_resize = atoi(argv[4]);
} }
if ((argc==2) || (argc == 3) || (flag_resize != 0)) if (flag_resize != 0)
{ {
cout << "WARNING: The input images is resized to " << wS << "x" << hS << " for ASIFT. " << endl cout << "WARNING: The input images is resized to " << wS << "x" << hS << " for ASIFT. " << endl
<< " But the results will be normalized to the original image size." << endl << endl; << " But the results will be normalized to the original image size." << endl << endl;
@ -101,6 +102,7 @@ int main(int argc, char **argv)
zoom1 = 1; zoom1 = 1;
} }
std::string refData[] = { std::string refData[] = {
"book_training/train_image_000.png", "book_training/train_image_000.png",
"book_training/train_image_001.png"}; "book_training/train_image_001.png"};
@ -111,14 +113,23 @@ int main(int argc, char **argv)
time_t tstart, tend; time_t tstart, tend;
tstart = time(0); tstart = time(0);
matcher.addReference(refData[0].c_str(), 8);
matcher.addReference(refData[1].c_str(), 8);
// matcher.print(); // matcher.print();
// matcher.match(refData[3].c_str(), 4); // matcher.match(refData[3].c_str(), 4);
if(argc>2) if(argc>2)
{
matcher.addReference(refData[0].c_str(), atoi(argv[2]));
matcher.addReference(refData[1].c_str(), atoi(argv[2]));
matcher.match(ipixels1_zoom, wS1, hS1, atoi(argv[2])); matcher.match(ipixels1_zoom, wS1, hS1, atoi(argv[2]));
}
else else
{
matcher.addReference(refData[0].c_str(), 7);
matcher.addReference(refData[1].c_str(), 7);
matcher.match(ipixels1_zoom, wS1, hS1); matcher.match(ipixels1_zoom, wS1, hS1);
}
if(argc>3 && atoi(argv[3])>0)
matcher.distFilter(atoi(argv[3]));
tend = time(0); tend = time(0);
@ -130,17 +141,13 @@ int main(int argc, char **argv)
cout<<" "<<NbMatch[i]<<endl; cout<<" "<<NbMatch[i]<<endl;
} }
int x =0,y=0; int x,y,cx,cy;
unsigned int h=1,w=1; unsigned int h,w;
matcher.computeROI(x,y,h,w);
float *opixelsASIFT = new float[w1*h1]; float *opixelsASIFT = new float[w1*h1];
/////////////////////////////////////////////////////////////////// Copy image to output /////////////////////////////////////////////////////////////////// Copy image to output
for(int j = 0; j < (int) h1; j++) for(int j = 0; j < (int) h1; j++)
for(int i = 0; i < (int) w1; i++) opixelsASIFT[j*w1+i] = ipixels1[j*w1+i]; for(int i = 0; i < (int) w1; i++) opixelsASIFT[j*w1+i] = ipixels1[j*w1+i];
//////////////////////////////////////////////////////////////////// Draw ROI
draw_square(opixelsASIFT, zoom1*x, zoom1*y, zoom1*w, zoom1*h, 255, w1, h1);
//////////////////////////////////////////////////////////////////// Draw matches //////////////////////////////////////////////////////////////////// Draw matches
int point_size = 2; int point_size = 2;
@ -152,6 +159,19 @@ int main(int argc, char **argv)
draw_square(opixelsASIFT, (int) (zoom1*ptrH->first.x), (int) (zoom1*ptrH->first.y), point_size, point_size, 255, w1, h1); draw_square(opixelsASIFT, (int) (zoom1*ptrH->first.x), (int) (zoom1*ptrH->first.y), point_size, point_size, 255, w1, h1);
} }
} }
//////////////////////////////////////////////////////////////////// Draw ROI
if(matcher.computeROI(x,y,h,w))
draw_square(opixelsASIFT, zoom1*x, zoom1*y, zoom1*w, zoom1*h, 255, w1, h1);
//////////////////////////////////////////////////////////////////// Draw Center
if(matcher.computeCenter(cx,cy))
{
draw_square(opixelsASIFT, zoom1*(cx-6), zoom1*(cy-6), zoom1*12, zoom1*12, 160, w1, h1);
draw_line(opixelsASIFT, zoom1*cx, zoom1*(cy-6), zoom1*cx, zoom1*(cy+6), 255, w1, h1);
draw_line(opixelsASIFT, zoom1*(cx-6), zoom1*cy, zoom1*(cx+6), zoom1*cy, 255, w1, h1);
}
///////////////////////////////////////////////////////////////// Save imgOut ///////////////////////////////////////////////////////////////// Save imgOut
write_png_f32("./results/res.png", opixelsASIFT, w1, h1, 1); write_png_f32("./results/res.png", opixelsASIFT, w1, h1, 1);