modules/shape/samples/shape_example.cpp


An example using shape distance algorithm

/*
* shape_context.cpp -- Shape context demo for shape matching
*/
#include " opencv2/shape.hpp "
#include <iostream>
#include <string>
using namespace std ;
using namespace cv ;
static void help()
{
printf( "\n"
"This program demonstrates a method for shape comparison based on Shape Context\n"
"You should run the program providing a number between 1 and 20 for selecting an image in the folder ../data/shape_sample.\n"
"Call\n"
"./shape_example [number between 1 and 20, 1 default]\n\n" );
}
static vector<Point> simpleContour( const Mat & currentQuery, int n=300 )
{
vector<vector<Point> > _contoursQuery;
vector <Point> contoursQuery;
findContours (currentQuery, _contoursQuery, RETR_LIST , CHAIN_APPROX_NONE );
for ( size_t border=0; border<_contoursQuery.size(); border++)
{
for ( size_t p=0; p<_contoursQuery[border].size(); p++)
{
contoursQuery.push_back( _contoursQuery[border][p] );
}
}
// In case actual number of points is less than n
int dummy=0;
for ( int add =( int )contoursQuery.size()-1; add <n; add ++)
{
contoursQuery.push_back(contoursQuery[dummy++]); //adding dummy values
}
// Uniformly sampling
cv::randShuffle (contoursQuery);
vector<Point> cont;
for ( int i=0; i<n; i++)
{
cont.push_back(contoursQuery[i]);
}
return cont;
}
int main( int argc, char ** argv)
{
string path = "data/shape_sample/" ;
cv::CommandLineParser parser(argc, argv, "{help h||}{@input|1|}" );
if (parser. has ( "help" ))
{
help();
return 0;
}
int indexQuery = parser. get < int >( "@input" );
if (!parser. check ())
{
parser. printErrors ();
help();
return 1;
}
if (indexQuery < 1 || indexQuery > 20)
{
help();
return 1;
}
Size sz2Sh(300,300);
stringstream queryName;
queryName<<path<<indexQuery<< ".png" ;
Mat query= imread (queryName.str(), IMREAD_GRAYSCALE );
Mat queryToShow;
resize (query, queryToShow, sz2Sh, 0, 0, INTER_LINEAR_EXACT );
imshow ( "QUERY" , queryToShow);
moveWindow ( "TEST" , 0,0);
vector<Point> contQuery = simpleContour(query);
int bestMatch = 0;
float bestDis=FLT_MAX;
for ( int ii=1; ii<=20; ii++ )
{
if (ii==indexQuery) continue ;
waitKey (30);
stringstream iiname;
iiname<<path<<ii<< ".png" ;
cout<< "name: " <<iiname.str()<<endl;
Mat iiIm= imread (iiname.str(), 0);
Mat iiToShow;
resize (iiIm, iiToShow, sz2Sh, 0, 0, INTER_LINEAR_EXACT );
imshow ( "TEST" , iiToShow);
moveWindow ( "TEST" , sz2Sh. width +50,0);
vector<Point> contii = simpleContour(iiIm);
float dis = mysc->computeDistance( contQuery, contii );
if ( dis<bestDis )
{
bestMatch = ii;
bestDis = dis;
}
std::cout<< " distance between " <<queryName.str()<< " and " <<iiname.str()<< " is: " <<dis<<std::endl;
}
destroyWindow ( "TEST" );
stringstream bestname;
bestname<<path<<bestMatch<< ".png" ;
Mat iiIm= imread (bestname.str(), 0);
Mat bestToShow;
resize (iiIm, bestToShow, sz2Sh, 0, 0, INTER_LINEAR_EXACT );
imshow ( "BEST MATCH" , bestToShow);
moveWindow ( "BEST MATCH" , sz2Sh. width +50,0);
return 0;
}