美颜

美颜的基本算法流程:

1.用具有保边效果的滤波算法对图像进行模糊处理

2.用肤色检测算法保护非皮肤区域

3.将模糊后的图像和原图进行图像融合

4.对融合后的图像进行锐化处理

一些算法的代码实现:

色彩平衡

InitLookupTable() {
  for (int i = 0; i < 256; i++) {
    highlights_add[i] = shadows_sub[255 - i] = (1.075 - 1 / ((double)i / 16.0 + 1));
    midtones_add[i] = midtones_sub[i] = 0.667 * (1 - (((double)i - 127.0) / 127.0)*(((double)i - 127.0) / 127.0));
    shadows_add[i] = highlights_sub[i] = 0.667 * (1 - (((double)i - 127.0) / 127.0)*(((double)i - 127.0) / 127.0));
  }
}

ColorBalance(cv::Mat& src, int value) {
  cv::Mat dst(src.size(), CV_8UC3);
  int red, green, blue;
  unsigned char r_lookup[256], g_lookup[256], b_lookup[256];
  for (int i = 0; i < 256; i++) {
    red = i;
    green = i;
    blue = i;
    red += (int)(0.0 * shadows_sub[red] + value * midtones_add[red] + 0.0 * highlights_sub[red]);
    red = FMax(0, FMin(0xFF, red));

    green += (int)(0.0 * shadows_sub[green] + value * midtones_add[green] + 0.0 * highlights_sub[green]);
    green = FMax(0, FMin(0xFF, green));

    blue += (int)(0.0 * shadows_sub[blue] + value * midtones_add[blue] + 0.0 * highlights_sub[blue]);
    blue = FMax(0, FMin(0xFF, blue));

    r_lookup[i] = (unsigned char)red;
    g_lookup[i] = (unsigned char)green;
    b_lookup[i] = (unsigned char)blue;
  }

  for (int row = 0; row < src.rows; row++) {
    for (int col = 0; col < src.cols; col++) {
      dst.at<cv::Vec3b>(row, col)[0] = b_lookup[src.at<cv::Vec3b>(row, col)[0]];
      dst.at<cv::Vec3b>(row, col)[1] = g_lookup[src.at<cv::Vec3b>(row, col)[1]];
      dst.at<cv::Vec3b>(row, col)[2] = r_lookup[src.at<cv::Vec3b>(row, col)[2]];
    }
  }
  cv:imshow("colorbalance", dst);
}

对数变换

LogCurve(cv::Mat &src, double value) {
  cv::Mat dst(src.size(), CV_32FC3);
  for (int row = 0; row < src.rows; row++) {
    for (int col = 0; col < src.cols; col++) {
      dst.at<cv::Vec3f>(row, col)[0] = (log(1.0 + (value - 1.0) *(src.at<cv::Vec3b>(row, col)[0])) / log(value));
      dst.at<cv::Vec3f>(row, col)[1] = (log(1.0 + (value - 1.0) *(src.at<cv::Vec3b>(row, col)[1])) / log(value));
      dst.at<cv::Vec3f>(row, col)[2] = (log(1.0 + (value - 1.0) *(src.at<cv::Vec3b>(row, col)[2])) / log(value));
    }
  }
  cv::normalize(dst, dst, 0, 255, CV_MINMAX);
  cv::convertScaleAbs(dst, dst);
  cv::imshow("logcurve", dst);
}

posted @ 2017-08-03 16:07  mvision  阅读(389)  评论(0编辑  收藏  举报