# 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.
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;