皮肤红润全局变换


#include "stdafx.h"
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
using namespace cv;
#define max_uchar(a, b)    (((a) > (b)) ? (a) : (b))
#define min_uchar(a, b)    (((a) < (b)) ? (a) : (b))
// 计算彩色图像均值和标准差
void CompMeanAndVariance(Mat &img, Vec3f &mean3f, Vec3f &variance3f)
{
    int row = img.rows;
    int col = img.cols;
    int total = row * col;
    float sum[3] = { 0.0f };
    // 均值
    uchar *pImg = img.data;
    for (int i = 0; i < row; i++)
    {
        for (int j = 0; j < col; j++)
        {
            sum[0] += pImg[3*j + 0];
            sum[1] += pImg[3*j + 1];
            sum[2] += pImg[3*j + 2];
        }
        pImg += img.step;
    }

    mean3f[0] = sum[0] / total;
    mean3f[1] = sum[1] / total;
    mean3f[2] = sum[2] / total;

    memset(sum, 0, sizeof(sum));
    // 标准差
    pImg = img.data;
    for (int i = 0; i < row; i++)
    {
        for (int j = 0; j < col; j++)
        {
            sum[0] += (pImg[3*j + 0] - mean3f[0]) * (pImg[3*j + 0] - mean3f[0]);
            sum[1] += (pImg[3*j + 1] - mean3f[1]) * (pImg[3*j + 1] - mean3f[1]);
            sum[2] += (pImg[3*j + 2] - mean3f[2]) * (pImg[3*j + 2] - mean3f[2]);
        }
        pImg += img.step;
    }

    variance3f[0] = sqrt(sum[0] / total);
    variance3f[1] = sqrt(sum[1] / total);
    variance3f[2] = sqrt(sum[2] / total);
}

// 颜色转换
void ColorTransfer(Mat &src, Mat &tar, Mat &dst)
{
    Mat srcLab, tarLab;
    Vec3f srcMean3f, tarMean3f;// 源/目标图像均值
    Vec3f srcVariance3f, tarVariance3f;// 源/目标图像标准差
    Vec3f ratioVariance3f;// 标准差比例

    // BGR空间转Lab空间
    cvtColor(src, srcLab, CV_BGR2Lab);
    cvtColor(tar, tarLab, CV_BGR2Lab);
    // 计算当前图像与目标图像均值及标准差
    CompMeanAndVariance(srcLab, srcMean3f, srcVariance3f);
    CompMeanAndVariance(tarLab, tarMean3f, tarVariance3f);

    // 标准差比
    ratioVariance3f[0] = tarVariance3f[0] / srcVariance3f[0];
    ratioVariance3f[1] = tarVariance3f[1] / srcVariance3f[1];
    ratioVariance3f[2] = tarVariance3f[2] / srcVariance3f[2];

    // 计算颜色转换值
    int row = srcLab.rows;
    int col = srcLab.cols;
    uchar *pImg = srcLab.data;
    for (int i = 0; i < row; i++)
    {
        for (int j = 0; j < col; j++)
        {
            pImg[3*j + 0] = (uchar)min_uchar(255, max_uchar(0, ratioVariance3f[0] * (pImg[3*j + 0] - srcMean3f[0]) + tarMean3f[0]));
            pImg[3*j + 1] = (uchar)min_uchar(255, max_uchar(0, ratioVariance3f[1] * (pImg[3*j + 1] - srcMean3f[1]) + tarMean3f[1]));
            pImg[3*j + 2] = (uchar)min_uchar(255, max_uchar(0, ratioVariance3f[2] * (pImg[3*j + 2] - srcMean3f[2]) + tarMean3f[2]));
        }
        pImg += srcLab.step;
    }

    // Lab空间转BGR空间
    cvtColor(srcLab, dst, CV_Lab2BGR);
}

int main()
{
    Mat src = imread("image\\src.jpg");
    Mat tar = imread("image\\tar.jpg");
    imshow("src", src);
    imshow("tar", tar);

    // 调色
    Mat dst;
    //ColorTransfer(src, tar, dst);
    imshow("dst", dst);

    waitKey();
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值