shape_example.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. /*
  2. * shape_context.cpp -- Shape context demo for shape matching
  3. */
  4. #include "opencv2/shape.hpp"
  5. #include "opencv2/imgcodecs.hpp"
  6. #include "opencv2/highgui.hpp"
  7. #include "opencv2/imgproc.hpp"
  8. #include <opencv2/core/utility.hpp>
  9. #include <iostream>
  10. #include <string>
  11. using namespace std;
  12. using namespace cv;
  13. static void help()
  14. {
  15. printf("\n"
  16. "This program demonstrates a method for shape comparison based on Shape Context\n"
  17. "You should run the program providing a number between 1 and 20 for selecting an image in the folder ../data/shape_sample.\n"
  18. "Call\n"
  19. "./shape_example [number between 1 and 20, 1 default]\n\n");
  20. }
  21. static vector<Point> simpleContour( const Mat& currentQuery, int n=300 )
  22. {
  23. vector<vector<Point> > _contoursQuery;
  24. vector <Point> contoursQuery;
  25. findContours(currentQuery, _contoursQuery, RETR_LIST, CHAIN_APPROX_NONE);
  26. for (size_t border=0; border<_contoursQuery.size(); border++)
  27. {
  28. for (size_t p=0; p<_contoursQuery[border].size(); p++)
  29. {
  30. contoursQuery.push_back( _contoursQuery[border][p] );
  31. }
  32. }
  33. // In case actual number of points is less than n
  34. int dummy=0;
  35. for (int add=(int)contoursQuery.size()-1; add<n; add++)
  36. {
  37. contoursQuery.push_back(contoursQuery[dummy++]); //adding dummy values
  38. }
  39. // Uniformly sampling
  40. cv::randShuffle(contoursQuery);
  41. vector<Point> cont;
  42. for (int i=0; i<n; i++)
  43. {
  44. cont.push_back(contoursQuery[i]);
  45. }
  46. return cont;
  47. }
  48. int main(int argc, char** argv)
  49. {
  50. string path = "data/shape_sample/";
  51. cv::CommandLineParser parser(argc, argv, "{help h||}{@input|1|}");
  52. if (parser.has("help"))
  53. {
  54. help();
  55. return 0;
  56. }
  57. int indexQuery = parser.get<int>("@input");
  58. if (!parser.check())
  59. {
  60. parser.printErrors();
  61. help();
  62. return 1;
  63. }
  64. if (indexQuery < 1 || indexQuery > 20)
  65. {
  66. help();
  67. return 1;
  68. }
  69. cv::Ptr <cv::ShapeContextDistanceExtractor> mysc = cv::createShapeContextDistanceExtractor();
  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, 0, 0, INTER_LINEAR_EXACT);
  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, 0, 0, INTER_LINEAR_EXACT);
  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, 0, 0, INTER_LINEAR_EXACT);
  108. imshow("BEST MATCH", bestToShow);
  109. moveWindow("BEST MATCH", sz2Sh.width+50,0);
  110. waitKey();
  111. return 0;
  112. }