Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Compute the histogram of a given image and of its prediction errors. If the pixel being processed is at coordinate (0,0), consider
- predicting based on just the pixel at (-1,0);
- predicting based on just the pixel at (0,1);
- predicting based on the average of the pixels at (-1,0), (-1,1), and (0,1).
- Compute the entropy for each one of the predictors in the previous exercise. Which predictor will compress better?
- Written by Eugene Khvedchenya <ekhvedchenya@gmail.com>
- */
- #include <opencv2/opencv.hpp>
- #include <iostream>
- #include <iterator>
- int predict_by_previous_pixel_in_row(const cv::Mat_<unsigned char>& img, int row, int col)
- {
- if (col > 0)
- return img(row, col - 1);
- return 0;
- }
- int predict_by_previous_pixel_in_col(const cv::Mat_<unsigned char>& img, int row, int col)
- {
- if (row > 0)
- return img(row - 1, col);
- return 0;
- }
- int predict_by_2prev_pixels_in_row(const cv::Mat_<unsigned char>& img, int row, int col)
- {
- if (col > 1)
- return ((int)img(row, col - 2) + (int)img(row, col - 1)) / 2;
- else
- return 0;
- }
- int predict_by_neighbours(const cv::Mat_<unsigned char>& img, int row, int col)
- {
- if (col > 0 && row > 0)
- {
- int a = img(row, col - 1);
- int b = img(row - 1, col - 1);
- int c = img(row - 1, col);
- int s = a + b + c;
- float m = s / 3.0f;
- return (int)m;
- }
- else
- return 0;
- }
- int predict_by_gradient(const cv::Mat_<unsigned char>& img, int row, int col)
- {
- if (col > 0 && row > 0)
- {
- int a = img(row, col - 1);
- int b = img(row - 1, col - 1);
- int c = img(row - 1, col);
- int gx = a - b;
- int gy = c - b;
- return (int)(b + (gx + gy) / 2.0f);
- }
- else
- {
- return 0;
- }
- }
- cv::Mat_<int> predict(const cv::Mat_<unsigned char>& source, int (*predict_function)(const cv::Mat_<unsigned char>& img, int row, int col) )
- {
- cv::Mat_<int> error;
- error.create(source.size());
- for (int row = 0; row < source.rows; row++)
- {
- for (int col = 0; col < source.cols; col++)
- {
- int actual = source(row, col);
- int predicted = predict_function(source, row, col);
- error(row, col) = predicted - actual;
- }
- }
- return error;
- }
- void calcHist(const cv::Mat& source, float& entropy, float& stdDev)
- {
- cv::Mat_<int> tmp;
- source.convertTo(tmp, CV_32S);
- std::map<int, int> histTable;
- for (int row = 0; row < tmp.rows; row++)
- for (int col = 0; col < tmp.cols; col++)
- histTable[ tmp(row, col) ]++;
- float entropySum = 0;
- std::vector<float> elements;
- for (auto it = histTable.begin(); it != histTable.end(); ++it)
- {
- float binValue = it->second;
- elements.push_back(binValue);
- float p = binValue / (float)(source.rows * source.cols);
- entropySum += p * log(p);
- }
- cv::Scalar m,d;
- cv::meanStdDev(elements, m, d);
- entropy = -entropySum;
- stdDev = d.val[0];
- }
- void testPredictor(cv::Mat input, int (*predict_function)(const cv::Mat_<unsigned char>& img, int row, int col))
- {
- cv::Mat_<int> predicted = predict(input, predict_function);
- float entropy, deviation;
- calcHist(predicted, entropy, deviation);
- std::cout << "Std.Dev. " << deviation << std::endl;
- std::cout << "Entropy: " << entropy << std::endl;
- std::cout << std::endl;
- }
- int main(int argc, const char * argv[])
- {
- if (argc != 2)
- {
- std::cout << "Usage:" << std::endl;
- std::cout << argv[0] << " <image>" << std::endl;
- return 1;
- }
- std::string imageFile(argv[1]);
- cv::Mat_<unsigned char> sourceGray = cv::imread(imageFile, CV_LOAD_IMAGE_GRAYSCALE);
- float entropy, deviation;
- calcHist(sourceGray, entropy, deviation);
- std::cout << "Source:" << std::endl;
- std::cout << "Std.Dev. " << deviation << std::endl;
- std::cout << "Entropy: " << entropy << std::endl;
- std::cout << std::endl;
- std::cout << "predict_by_previous_pixel_in_row:" << std::endl;
- testPredictor(sourceGray, predict_by_previous_pixel_in_row);
- std::cout << "predict_by_previous_pixel_in_col:" << std::endl;
- testPredictor(sourceGray, predict_by_previous_pixel_in_col);
- std::cout << "predict_by_2prev_pixels_in_row:" << std::endl;
- testPredictor(sourceGray, predict_by_2prev_pixels_in_row);
- std::cout << "predict_by_neighbours:" << std::endl;
- testPredictor(sourceGray, predict_by_neighbours);
- std::cout << "predict_by_gradient:" << std::endl;
- testPredictor(sourceGray, predict_by_gradient);
- std::cout << std::endl;
- cv::waitKey(-1);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement