欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

图像处理相关算法之饱和度调整

程序员文章站 2022-07-14 16:52:12
...

调整饱和度的方法,代码如下:

void AdjustSatuation(cv::Mat &image, float adjust) {
    int width = image.cols, height = image.rows;
    for (int i = 0; i < height; ++i) {
        auto data = image.ptr<cv::Vec3b>(i);
        for (int j = 0; j < width; ++j) {
            float lum = data[j][0] * 0.299f + data[j][1] * 0.587f + data[j][2] * 0.114f;
            float maskB = std::max(0.0f, std::min(data[j][0] - lum, 255.0f)) / 255.0f;
            float maskG = std::max(0.0f, std::min(data[j][1] - lum, 255.0f)) / 255.0f;
            float maskR = std::max(0.0f, std::min(data[j][2] - lum, 255.0f)) / 255.0f;
            float lumMask = (1.0f - (maskB * 0.299f + maskG * 0.587f + maskR * 0.114f)) * adjust;
            data[j][0] = cv::saturate_cast<uchar>(data[j][0] * (1.0f + lumMask) - lum * lumMask);
            data[j][1] = cv::saturate_cast<uchar>(data[j][1] * (1.0f + lumMask) - lum * lumMask);
            data[j][2] = cv::saturate_cast<uchar>(data[j][2] * (1.0f + lumMask) - lum * lumMask);
        }
    }
}

调整前后对比:

图像处理相关算法之饱和度调整
原图
图像处理相关算法之饱和度调整
增加50%饱和度
图像处理相关算法之饱和度调整
减少50%饱和度

其中adjust取值范围为[-1,1]

另一种饱和度调整算法:

void AdjustSatuation(const cv::Mat &src, cv::Mat &dst, int percent) {
    dst.create(src.size(), src.type());
    int width = src.cols, height = src.rows;
    int channels = src.channels();
    if (channels != 3 || src.type() != CV_8UC3) {
        return;
    }
    float ratio1 = 1 / 255.0f;
    float adjust = std::max(std::min(percent, 100), -100) / 100.0f;
    for (int i = 0; i < height; ++i) {
        auto srcData = src.ptr<uchar>(i);
        auto dstData = dst.ptr<uchar>(i);
        for (int j = 0; j < width; ++j) {
            int j3 = j * 3;
            int r = srcData[j3 + 2];
            int g = srcData[j3 + 1];
            int b = srcData[j3];
            int maxV = std::max(r, std::max(g, b));
            int minV = std::min(r, std::min(g, b));
            float delta = (maxV - minV) * ratio1;
            if (delta < 1e-3f) {
                dstData[j3] = b;
                dstData[j3 + 1] = g;
                dstData[j3 + 2] = r;
                continue;
            }
            float value = (maxV + minV) * ratio1;
            float L = value / 2.0f;
            float S = delta / value;
            if (L >= 0.5f) {
                S = delta / (2.0f - value);
            }
            if (percent >= 0) {
                float alpha = 1.0f - adjust;
                if (adjust + S >= 1) {
                    alpha = S;
                }
                alpha = 1.0f / alpha - 1.0f;
                dstData[j3] = cv::saturate_cast<uchar>(b + (b - L * 255.0f) * alpha);
                dstData[j3 + 1] = cv::saturate_cast<uchar>(g + (g - L * 255.0f) * alpha);
                dstData[j3 + 2] = cv::saturate_cast<uchar>(r + (r - L * 255.0f) * alpha);
            }
            else {
                float alpha = 1.0f + adjust;
                dstData[j3] = cv::saturate_cast<uchar>(L * 255.0f + (b - L * 255.0f) * alpha);
                dstData[j3 + 1] = cv::saturate_cast<uchar>(L * 255.0f + (g - L * 255.0f) * alpha);
                dstData[j3 + 2] = cv::saturate_cast<uchar>(L * 255.0f + (r - L * 255.0f) * alpha);
            }
        }
    }
}

调整后的图像结果为:

图像处理相关算法之饱和度调整
增加50%的饱和度
图像处理相关算法之饱和度调整
减少50%的饱和度