/src/Chapter07/Histogrem-EMD.cpp

https://github.com/yourtion/LearningOpenCV · C++ · 134 lines · 95 code · 25 blank · 14 comment · 8 complexity · 49915da65e2ec0977d218a4c06017539 MD5 · raw file

  1. //
  2. // Histogrem-EMD.cpp
  3. // LearningOpenCV
  4. //
  5. // Created by YourtionGuo on 7/28/16.
  6. // Copyright © 2016 Yourtion. All rights reserved.
  7. //
  8. #include <iostream>
  9. #include <highgui.h>
  10. #include <cv.h>
  11. int main(int argc, const char * argv[]) {
  12. IplImage *src1, *src2;
  13. if (argc == 3 && ((src1 = cvLoadImage(argv[1], 1)) != 0) && ((src2 = cvLoadImage(argv[2], 1)) != 0)) {
  14. // HSV image and decompose into separate planes
  15. IplImage* hsv1 = cvCreateImage( cvGetSize(src1), 8, 3 );
  16. cvCvtColor( src1, hsv1, CV_BGR2HSV);
  17. IplImage* h_plane1 = cvCreateImage( cvGetSize(src1), 8, 1 );
  18. IplImage* s_plane1 = cvCreateImage( cvGetSize(src1), 8, 1 );
  19. IplImage* v_plane1 = cvCreateImage( cvGetSize(src1), 8, 1 );
  20. IplImage* planes1[] = { h_plane1, s_plane1 };
  21. cvCvtPixToPlane( hsv1, h_plane1, s_plane1, v_plane1, 0 );
  22. IplImage* hsv2 = cvCreateImage( cvGetSize(src2), 8, 3 );
  23. cvCvtColor( src2, hsv2, CV_BGR2HSV);
  24. IplImage* h_plane2 = cvCreateImage( cvGetSize(src2), 8, 1 );
  25. IplImage* s_plane2 = cvCreateImage( cvGetSize(src2), 8, 1 );
  26. IplImage* v_plane2 = cvCreateImage( cvGetSize(src2), 8, 1 );
  27. IplImage* planes2[] = { h_plane2, s_plane2 };
  28. cvCvtPixToPlane( hsv2, h_plane2, s_plane2, v_plane2, 0 );
  29. // Build the histogram amd compute
  30. int h_bins = 30, s_bins = 32;
  31. CvHistogram *hist1, *hist2;
  32. {
  33. int hist_size[] = { h_bins, s_bins };
  34. float h_ranges[] = { 0, 180 };
  35. float s_ranges[] = { 0, 255 };
  36. float* ranges[] = { h_ranges, s_ranges };
  37. hist1 = cvCreateHist( 2, hist_size, CV_HIST_ARRAY, ranges, 1 );
  38. hist2 = cvCreateHist( 2, hist_size, CV_HIST_ARRAY, ranges, 1 );
  39. }
  40. cvCalcHist( planes1, hist1, 0, 0 );
  41. cvNormalizeHist( hist1, 1.0 );
  42. cvCalcHist( planes2, hist2, 0, 0 );
  43. cvNormalizeHist( hist2, 1.0 );
  44. // Get signature using EMD
  45. CvMat *sig1,*sig2;
  46. int numrows = h_bins * s_bins;
  47. sig1 = cvCreateMat(numrows, 3, CV_32FC1);
  48. sig2 = cvCreateMat(numrows, 3, CV_32FC1);
  49. // Create image to visualize
  50. int scale = 10;
  51. IplImage* hist_img1 = cvCreateImage( cvSize(h_bins*scale, s_bins*scale), 8, 3);
  52. cvZero( hist_img1 );
  53. IplImage* hist_img2 = cvCreateImage( cvSize(h_bins*scale, s_bins*scale), 8, 3);
  54. cvZero( hist_img2 );
  55. float max_value1 = 0;
  56. cvGetMinMaxHistValue( hist1, 0, &max_value1, 0, 0 );
  57. float max_value2 = 0;
  58. cvGetMinMaxHistValue( hist2, 0, &max_value2, 0, 0 );
  59. // Fill
  60. for ( int h = 0; h < h_bins; h ++ ) {
  61. for ( int s = 0; s < s_bins ; s++ ) {
  62. float bin_val1 = cvQueryHistValue_2D( hist1, h, s );
  63. float bin_val2 = cvQueryHistValue_2D( hist2, h, s );
  64. // Image
  65. int intensity1 = cvRound( bin_val1 * 255 / max_value1 );
  66. cvRectangle(hist_img1,
  67. cvPoint( h*scale, s*scale ),
  68. cvPoint( (h+1)*scale-1, (s+1)*scale-1 ),
  69. CV_RGB(intensity1, intensity1, intensity1),
  70. CV_FILLED
  71. );
  72. int intensity2 = cvRound( bin_val2 * 255 / max_value2 );
  73. cvRectangle(hist_img2,
  74. cvPoint( h*scale, s*scale ),
  75. cvPoint( (h+1)*scale-1, (s+1)*scale-1 ),
  76. CV_RGB(intensity2, intensity2, intensity2),
  77. CV_FILLED
  78. );
  79. // Signature
  80. cvSet2D(sig1, h*s_bins+s, 0, cvScalar(bin_val1)); // bin value
  81. cvSet2D(sig1, h*s_bins+s, 1, cvScalar(h)); // Coord 1
  82. cvSet2D(sig1, h*s_bins+s, 2, cvScalar(s)); // Coord 2
  83. cvSet2D(sig2, h*s_bins+s, 0, cvScalar(bin_val2)); // bin value
  84. cvSet2D(sig2, h*s_bins+s, 1, cvScalar(h)); // Coord 1
  85. cvSet2D(sig2, h*s_bins+s, 2, cvScalar(s)); // Coord 2
  86. }
  87. }
  88. cvNamedWindow( "Source - 1", 1 );
  89. cvShowImage( "Source - 1", src1 );
  90. cvNamedWindow( "H-S Histogrem - 1", 1 );
  91. cvShowImage( "H-S Histogrem - 1", hist_img1 );
  92. cvNamedWindow( "Source - 2", 1 );
  93. cvShowImage( "Source - 2", src2 );
  94. cvNamedWindow( "H-S Histogrem - 2", 1 );
  95. cvShowImage( "H-S Histogrem - 2", hist_img2 );
  96. float emd = cvCalcEMD2( sig1, sig2, CV_DIST_L2);
  97. printf("EMD : %f ;", emd);
  98. cvWaitKey();
  99. cvReleaseImage( &src1 );
  100. cvReleaseImage( &hist_img1 );
  101. cvReleaseHist( &hist1 );
  102. cvReleaseMat( &sig1 );
  103. cvReleaseImage( &src2 );
  104. cvReleaseImage( &hist_img2 );
  105. cvReleaseHist( &hist2 );
  106. cvReleaseMat( &sig2 );
  107. }
  108. return 0;
  109. }