Advertisement
BloodAxe

Eugene

Jan 27th, 2013
278
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2. Compute the histogram of a given image and of its prediction errors. If the pixel being processed is at coordinate (0,0), consider
  3. predicting based on just the pixel at (-1,0);
  4. predicting based on just the pixel at (0,1);
  5. predicting based on the average of the pixels at (-1,0), (-1,1), and (0,1).
  6. Compute the entropy for each one of the predictors in the previous exercise. Which predictor will compress better?
  7.  
  8. Written by Eugene Khvedchenya <ekhvedchenya@gmail.com>
  9. */
  10.  
  11. #include <opencv2/opencv.hpp>
  12. #include <iostream>
  13. #include <iterator>
  14.  
  15. int predict_by_previous_pixel_in_row(const cv::Mat_<unsigned char>& img, int row, int col)
  16. {
  17.     if (col > 0)
  18.         return img(row, col - 1);
  19.     return 0;
  20. }
  21.  
  22. int predict_by_previous_pixel_in_col(const cv::Mat_<unsigned char>& img, int row, int col)
  23. {
  24.     if (row > 0)
  25.         return img(row - 1, col);
  26.     return 0;
  27. }
  28.  
  29. int predict_by_2prev_pixels_in_row(const cv::Mat_<unsigned char>& img, int row, int col)
  30. {
  31.     if (col > 1)
  32.         return ((int)img(row, col - 2) + (int)img(row, col - 1)) / 2;
  33.     else
  34.         return 0;
  35. }
  36.  
  37. int predict_by_neighbours(const cv::Mat_<unsigned char>& img, int row, int col)
  38. {
  39.     if (col > 0 && row > 0)
  40.     {
  41.         int a = img(row, col - 1);
  42.         int b = img(row - 1, col - 1);
  43.         int c = img(row - 1, col);
  44.         int s = a + b + c;
  45.        
  46.         float m = s / 3.0f;
  47.         return (int)m;
  48.     }
  49.     else
  50.         return 0;
  51. }
  52.  
  53. int predict_by_gradient(const cv::Mat_<unsigned char>& img, int row, int col)
  54. {
  55.     if (col > 0 && row > 0)
  56.     {
  57.         int a = img(row, col - 1);
  58.         int b = img(row - 1, col - 1);
  59.         int c = img(row - 1, col);
  60.                
  61.         int gx = a - b;
  62.         int gy = c - b;
  63.  
  64.         return (int)(b + (gx + gy) / 2.0f);
  65.     }
  66.     else
  67.     {
  68.         return 0;
  69.     }
  70. }
  71.  
  72. cv::Mat_<int> predict(const cv::Mat_<unsigned char>& source, int (*predict_function)(const cv::Mat_<unsigned char>& img, int row, int col) )
  73. {
  74.     cv::Mat_<int> error;
  75.     error.create(source.size());
  76.  
  77.     for (int row = 0; row < source.rows; row++)
  78.     {
  79.         for (int col = 0; col < source.cols; col++)
  80.         {
  81.             int actual    = source(row, col);
  82.             int predicted = predict_function(source, row, col);
  83.  
  84.             error(row, col) = predicted - actual;
  85.         }
  86.     }
  87.    
  88.     return error;
  89. }
  90.  
  91. void calcHist(const cv::Mat& source, float& entropy, float& stdDev)
  92. {
  93.     cv::Mat_<int> tmp;
  94.     source.convertTo(tmp, CV_32S);
  95.    
  96.     std::map<int, int> histTable;
  97.    
  98.     for (int row = 0; row < tmp.rows; row++)
  99.         for (int col = 0; col < tmp.cols; col++)
  100.             histTable[ tmp(row, col) ]++;
  101.  
  102.     float entropySum = 0;
  103.    
  104.     std::vector<float> elements;
  105.    
  106.     for (auto it = histTable.begin(); it != histTable.end(); ++it)
  107.     {
  108.         float binValue = it->second;
  109.        
  110.         elements.push_back(binValue);
  111.        
  112.         float p = binValue / (float)(source.rows * source.cols);
  113.         entropySum += p * log(p);
  114.     }
  115.    
  116.     cv::Scalar m,d;
  117.     cv::meanStdDev(elements, m, d);
  118.  
  119.     entropy = -entropySum;
  120.     stdDev = d.val[0];
  121. }
  122.  
  123. void testPredictor(cv::Mat input, int (*predict_function)(const cv::Mat_<unsigned char>& img, int row, int col))
  124. {
  125.     cv::Mat_<int> predicted = predict(input, predict_function);
  126.    
  127.     float entropy, deviation;
  128.  
  129.     calcHist(predicted, entropy, deviation);
  130.     std::cout << "Std.Dev. " << deviation << std::endl;
  131.     std::cout << "Entropy: " << entropy << std::endl;
  132.     std::cout << std::endl;
  133.  
  134. }
  135.  
  136. int main(int argc, const char * argv[])
  137. {
  138.     if (argc != 2)
  139.     {
  140.         std::cout << "Usage:" << std::endl;
  141.         std::cout << argv[0] << " <image>" << std::endl;
  142.         return 1;
  143.     }
  144.  
  145.     std::string imageFile(argv[1]);
  146.  
  147.     cv::Mat_<unsigned char> sourceGray = cv::imread(imageFile, CV_LOAD_IMAGE_GRAYSCALE);
  148.  
  149.     float entropy, deviation;
  150.     calcHist(sourceGray, entropy, deviation);
  151.  
  152.  
  153.     std::cout << "Source:" << std::endl;
  154.     std::cout << "Std.Dev. " << deviation << std::endl;
  155.     std::cout << "Entropy: " << entropy << std::endl;
  156.     std::cout << std::endl;
  157.    
  158.     std::cout << "predict_by_previous_pixel_in_row:" << std::endl;
  159.     testPredictor(sourceGray, predict_by_previous_pixel_in_row);
  160.    
  161.     std::cout << "predict_by_previous_pixel_in_col:" << std::endl;
  162.     testPredictor(sourceGray, predict_by_previous_pixel_in_col);
  163.  
  164.     std::cout << "predict_by_2prev_pixels_in_row:" << std::endl;
  165.     testPredictor(sourceGray, predict_by_2prev_pixels_in_row);
  166.  
  167.     std::cout << "predict_by_neighbours:" << std::endl;
  168.     testPredictor(sourceGray, predict_by_neighbours);
  169.  
  170.     std::cout << "predict_by_gradient:" << std::endl;
  171.     testPredictor(sourceGray, predict_by_gradient);
  172.  
  173.  
  174.     std::cout << std::endl;
  175.  
  176.     cv::waitKey(-1);
  177.     return 0;
  178. }
Advertisement
Advertisement
Advertisement
RAW Paste Data Copied
Advertisement