• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * shape_context.cpp -- Shape context demo for shape matching
3  */
4 
5 #include "opencv2/shape.hpp"
6 #include "opencv2/imgcodecs.hpp"
7 #include "opencv2/highgui.hpp"
8 #include "opencv2/imgproc.hpp"
9 #include <opencv2/core/utility.hpp>
10 #include <iostream>
11 #include <string>
12 
13 using namespace std;
14 using namespace cv;
15 
help()16 static void help()
17 {
18     printf("\n"
19             "This program demonstrates a method for shape comparisson based on Shape Context\n"
20             "You should run the program providing a number between 1 and 20 for selecting an image in the folder ../data/shape_sample.\n"
21             "Call\n"
22             "./shape_example [number between 1 and 20]\n\n");
23 }
24 
simpleContour(const Mat & currentQuery,int n=300)25 static vector<Point> simpleContour( const Mat& currentQuery, int n=300 )
26 {
27     vector<vector<Point> > _contoursQuery;
28     vector <Point> contoursQuery;
29     findContours(currentQuery, _contoursQuery, RETR_LIST, CHAIN_APPROX_NONE);
30     for (size_t border=0; border<_contoursQuery.size(); border++)
31     {
32         for (size_t p=0; p<_contoursQuery[border].size(); p++)
33         {
34             contoursQuery.push_back( _contoursQuery[border][p] );
35         }
36     }
37 
38     // In case actual number of points is less than n
39     int dummy=0;
40     for (int add=(int)contoursQuery.size()-1; add<n; add++)
41     {
42         contoursQuery.push_back(contoursQuery[dummy++]); //adding dummy values
43     }
44 
45     // Uniformly sampling
46     random_shuffle(contoursQuery.begin(), contoursQuery.end());
47     vector<Point> cont;
48     for (int i=0; i<n; i++)
49     {
50         cont.push_back(contoursQuery[i]);
51     }
52     return cont;
53 }
54 
main(int argc,char ** argv)55 int main(int argc, char** argv)
56 {
57     help();
58     string path = "../data/shape_sample/";
59     int indexQuery = 1;
60     if( argc < 2 )
61     {
62         std::cout<<"Using first image as query."<<std::endl;
63     }
64     else
65     {
66         sscanf( argv[1], "%i", &indexQuery );
67     }
68     cv::Ptr <cv::ShapeContextDistanceExtractor> mysc = cv::createShapeContextDistanceExtractor();
69 
70     Size sz2Sh(300,300);
71     stringstream queryName;
72     queryName<<path<<indexQuery<<".png";
73     Mat query=imread(queryName.str(), IMREAD_GRAYSCALE);
74     Mat queryToShow;
75     resize(query, queryToShow, sz2Sh);
76     imshow("QUERY", queryToShow);
77     moveWindow("TEST", 0,0);
78     vector<Point> contQuery = simpleContour(query);
79     int bestMatch = 0;
80     float bestDis=FLT_MAX;
81     for ( int ii=1; ii<=20; ii++ )
82     {
83         if (ii==indexQuery) continue;
84         waitKey(30);
85         stringstream iiname;
86         iiname<<path<<ii<<".png";
87         cout<<"name: "<<iiname.str()<<endl;
88         Mat iiIm=imread(iiname.str(), 0);
89         Mat iiToShow;
90         resize(iiIm, iiToShow, sz2Sh);
91         imshow("TEST", iiToShow);
92         moveWindow("TEST", sz2Sh.width+50,0);
93         vector<Point> contii = simpleContour(iiIm);
94         float dis = mysc->computeDistance( contQuery, contii );
95         if ( dis<bestDis )
96         {
97             bestMatch = ii;
98             bestDis = dis;
99         }
100         std::cout<<" distance between "<<queryName.str()<<" and "<<iiname.str()<<" is: "<<dis<<std::endl;
101     }
102     destroyWindow("TEST");
103     stringstream bestname;
104     bestname<<path<<bestMatch<<".png";
105     Mat iiIm=imread(bestname.str(), 0);
106     Mat bestToShow;
107     resize(iiIm, bestToShow, sz2Sh);
108     imshow("BEST MATCH", bestToShow);
109     moveWindow("BEST MATCH", sz2Sh.width+50,0);
110 
111     return 0;
112 }
113