Advertisement
Guest User

Untitled

a guest
Dec 16th, 2018
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.02 KB | None | 0 0
  1. #include <opencv2/core/core.hpp>
  2. #include <opencv2/imgcodecs/imgcodecs.hpp>
  3. #include <vector>
  4.  
  5. using namespace cv;
  6. using namespace std;
  7.  
  8.  
  9. Vec3b find_nearest_color(vector<Vec3b>& palette, Vec3b& color, Vec3f& weights) {
  10.     Vec3b palette_color;
  11.     Vec3b nearest_color;
  12.     float color_dist;
  13.     float min_color_dist = 3 * 255;
  14.     Vec3b diff;
  15.  
  16.     vector<Vec3b>::iterator it;
  17.     for (it = palette.begin(); it != palette.end(); ++it) {
  18.         palette_color = *it;
  19.         absdiff(color, palette_color, diff);
  20.         color_dist = weights[0] * diff[0]
  21.             + weights[1] * diff[1]
  22.             + weights[2] * diff[2];
  23.         if (color_dist < min_color_dist) {
  24.             min_color_dist = color_dist;
  25.             nearest_color = palette_color;
  26.         }
  27.     }
  28.     return nearest_color;
  29. }
  30.  
  31.  
  32. void dither(Mat& _img, vector<Vec3b>& palette) {
  33.     // accept only char type matrices
  34.     CV_Assert(_img.depth() == CV_8U);
  35.  
  36.     Mat_<Vec3b> img = _img;
  37.  
  38.     Vec3b color;
  39.     Vec3b nearest_color;
  40.     Vec3i err, d0, d1, d2, d3;
  41.     Vec3f weights = Vec3f(0.11, 0.59, 0.30);
  42.  
  43.     int i, j;
  44.     uchar *p, *p1;
  45.     for (i = 0; i < img.rows - 1; ++i) {
  46.         p = img.ptr<uchar>(i);
  47.         p1 = img.ptr<uchar>(i+1);
  48.         for (j = 1; j < img.cols - 1; ++j) {
  49.             //color = img(i, j);
  50.             memcpy(&color, p+j*3, 3);
  51.             nearest_color = find_nearest_color(palette, color, weights);
  52.             err = (Vec3i)color - (Vec3i)nearest_color;
  53.             //img(i, j) = nearest_color;
  54.             memcpy(p+j*3, &nearest_color, 3);
  55.  
  56.             //d0 = (Vec3i)img(i, j + 1) +     Vec3i(err[0] * 7 >> 4, err[1] * 7 >> 4, err[2] * 7 >> 4);
  57.             d0 = Vec3i(*(p + (j + 1) * 3), *(p + 1 + (j + 1) * 3), *(p + 2 + (j + 1) * 3)) +    Vec3i(err[0] * 7 >> 4, err[1] * 7 >> 4, err[2] * 7 >> 4);
  58.             //d1 = (Vec3i)img(i + 1, j - 1) + Vec3i(err[0] * 3 >> 4, err[1] * 3 >> 4, err[2] * 3 >> 4);
  59.             d1 = Vec3i(*(p1 + (j - 1) * 3), *(p1 + 1 + (j - 1) * 3), *(p1 + 2 + (j - 1) * 3)) + Vec3i(err[0] * 3 >> 4, err[1] * 3 >> 4, err[2] * 3 >> 4);
  60.             //d2 = (Vec3i)img(i + 1, j) +     Vec3i(err[0] * 5 >> 4, err[1] * 5 >> 4, err[2] * 5 >> 4);
  61.             d2 = Vec3i(*(p1 + j * 3), *(p1 + 1 + j * 3), *(p1 + 2 + j * 3)) +                   Vec3i(err[0] * 5 >> 4, err[1] * 5 >> 4, err[2] * 5 >> 4);
  62.             //d3 = (Vec3i)img(i + 1, j + 1) + Vec3i(err[0]     >> 4, err[1]     >> 4, err[2]     >> 4);
  63.             d3 = Vec3i(*(p1 + (j + 1) * 3), *(p1 + 1 + (j + 1) * 3), *(p1 + 2 + (j + 1) * 3)) + Vec3i(err[0]     >> 4, err[1]     >> 4, err[2]     >> 4);
  64.  
  65.             //img(i, j + 1) = Vec3b(saturate_cast<uchar>(d0[0]), saturate_cast<uchar>(d0[1]), saturate_cast<uchar>(d0[2]));
  66.             memcpy(p + (j + 1) * 3, &Vec3b(saturate_cast<uchar>(d0[0]), saturate_cast<uchar>(d0[1]), saturate_cast<uchar>(d0[2])), 3);
  67.             //img(i + 1, j - 1) = Vec3b(saturate_cast<uchar>(d1[0]), saturate_cast<uchar>(d1[1]), saturate_cast<uchar>(d1[2]));
  68.             memcpy(p1 + (j - 1) * 3, &Vec3b(saturate_cast<uchar>(d1[0]), saturate_cast<uchar>(d1[1]), saturate_cast<uchar>(d1[2])), 3);
  69.             //img(i + 1, j) = Vec3b(saturate_cast<uchar>(d2[0]), saturate_cast<uchar>(d2[1]), saturate_cast<uchar>(d2[2]));
  70.             memcpy(p1 + j * 3, &Vec3b(saturate_cast<uchar>(d2[0]), saturate_cast<uchar>(d2[1]), saturate_cast<uchar>(d2[2])), 3);
  71.             //img(i + 1, j + 1) = Vec3b(saturate_cast<uchar>(d3[0]), saturate_cast<uchar>(d3[1]), saturate_cast<uchar>(d3[2]));
  72.             memcpy(p1 + (j + 1) * 3, &Vec3b(saturate_cast<uchar>(d3[0]), saturate_cast<uchar>(d3[1]), saturate_cast<uchar>(d3[2])), 3);
  73.         }
  74.     }
  75.     _img = img;
  76.  
  77. }
  78.  
  79. int main() {
  80.  
  81.     Mat img;
  82.     img = imread("source.jpg", IMREAD_COLOR);
  83.  
  84.     vector<Vec3b> palette;
  85.     palette.push_back(Vec3b(189, 203, 189));
  86.     palette.push_back(Vec3b(148, 93, 0));
  87.     palette.push_back(Vec3b(8, 12, 123));
  88.     palette.push_back(Vec3b(8, 60, 123));
  89.     palette.push_back(Vec3b(8, 125, 123));
  90.     palette.push_back(Vec3b(8, 125, 8));
  91.     palette.push_back(Vec3b(123, 125, 8));
  92.     palette.push_back(Vec3b(123, 12, 8));
  93.     palette.push_back(Vec3b(123, 12, 57));
  94.     palette.push_back(Vec3b(123, 12, 123));
  95.     palette.push_back(Vec3b(123, 125, 123));
  96.     palette.push_back(Vec3b(8, 12, 8));
  97.     palette.push_back(Vec3b(99, 101, 99));
  98.     palette.push_back(Vec3b(49, 48, 49));
  99.  
  100.     dither(img, palette);
  101.     imwrite("dithered.png", img);
  102.  
  103.     return 0;
  104. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement