OpenCV(图像饱和度)



1. 图像饱和度

饱和度(Saturation)指的是颜色的纯度或浓度,决定了颜色的鲜艳程度。高饱和度的颜色看起来更加鲜艳,而低饱和度的颜色则显得灰暗或淡化。饱和度主要与色彩空间中的色调(Hue)和亮度(Lightness/Brightness)相区分。

在处理图像时,常见的色彩空间包括:

  • RGB:通过红色 (Red)、绿色 (Green) 和蓝色 (Blue) 这三种原色组合形成其他颜色。
  • HSV(Hue, Saturation, Value):色调、饱和度和亮度。这个色彩空间更加接近人类的感知方式,饱和度在这里作为一个独立的维度。


2. 饱和度调整的原理

为了调整图像的饱和度,通常我们会将图像从 RGB 色彩空间转换到 HSV 色彩空间,因为在 HSV 中,饱和度(S)是一个独立的维度。我们可以只修改饱和度而不影响色调和亮度,然后将图像转换回 RGB 色彩空间。



3. 示例

3.1 对 RGB 图像进行饱和度的调整。

#include <opencv2/opencv.hpp>
#include <iostream>

// 调整饱和度的函数
void adjustSaturation(cv::Mat& src, cv::Mat& dst, double saturationScale) {
    // 将RGB图像转换为HSV色彩空间
    cv::Mat hsv;
    cv::cvtColor(src, hsv, cv::COLOR_BGR2HSV);

    // 遍历图像,调整饱和度
    for (int i = 0; i < hsv.rows; ++i) {
        for (int j = 0; j < hsv.cols; ++j) {
            // 获取每个像素的HSV值
            cv::Vec3b& pixel = hsv.at<cv::Vec3b>(i, j);
            
            // 读取饱和度(S),它在0到255之间
            int saturation = pixel[1];
            
            // 根据给定的缩放因子调整饱和度
            saturation = cv::saturate_cast<uchar>(saturation * saturationScale);
            
            // 将新的饱和度值赋给像素
            pixel[1] = saturation;
        }
    }

    // 将HSV图像转换回RGB色彩空间
    cv::cvtColor(hsv, dst, cv::COLOR_HSV2BGR);
}

int main() {
    // 读取原始图像
    cv::Mat src = cv::imread("input.jpg");
    if (src.empty()) {
        std::cerr << "Error: Could not open image file." << std::endl;
        return -1;
    }

    // 输出图像
    cv::Mat dst;

    // 调整饱和度,缩放因子为1.5,意味着增加50%的饱和度
    double saturationScale = 1.5;
    adjustSaturation(src, dst, saturationScale);

    // 显示结果
    cv::imshow("Original Image", src);
    cv::imshow("Saturation Adjusted Image", dst);

    // 等待按键退出
    cv::waitKey(0);
    return 0;
}

代码说明:

  1. 输入和输出图像:通过 cv::imread() 函数读取输入图像,并通过 cv::imwrite() 保存处理后的图像。

  2. 色彩空间转换:使用 cv::cvtColor() 函数将 RGB 图像转换为 HSV 色彩空间,方便操作饱和度。

  3. 饱和度调整:在 HSV 色彩空间中,遍历每个像素并调整其饱和度(第二个通道值)。为了避免超出范围,使用 cv::saturate_cast<uchar>() 来保证饱和度值在 0 到 255 之间。

  4. 转换回 RGB:处理完成后,使用 cv::cvtColor() 将图像从 HSV 色彩空间转换回 RGB 并进行显示和保存。


3.2 对 RGB 图像进行饱和度的调整。

#include <opencv2/opencv.hpp>
#include <iostream>

// 调整饱和度函数
cv::Mat adjustSaturation(const cv::Mat& inputImage, double scale) {
    // 将输入图像转换为HSV颜色空间
    cv::Mat hsvImage;
    cv::cvtColor(inputImage, hsvImage, cv::COLOR_BGR2HSV);

    // 分离HSV通道
    std::vector<cv::Mat> hsvChannels;
    cv::split(hsvImage, hsvChannels);

    // 调整饱和度 (S 通道)
    hsvChannels[1].convertTo(hsvChannels[1], -1, scale, 0);

    // 合并通道
    cv::merge(hsvChannels, hsvImage);

    // 将HSV图像转换回BGR颜色空间
    cv::Mat outputImage;
    cv::cvtColor(hsvImage, outputImage, cv::COLOR_HSV2BGR);

    return outputImage;
}

int main() {
    // 读取图像
    cv::Mat inputImage = cv::imread("input.jpg");
    if (inputImage.empty()) {
        std::cerr << "无法读取图像!" << std::endl;
        return -1;
    }

    // 调整饱和度,scale > 1 增加饱和度,scale < 1 减少饱和度
    double saturationScale = 1.5;  // 增加50%的饱和度
    cv::Mat adjustedImage = adjustSaturation(inputImage, saturationScale);

    // 显示结果
    cv::imshow("Original Image", inputImage);
    cv::imshow("Saturation Adjusted Image", adjustedImage);

    // 保存结果
    cv::imwrite("adjusted_image.jpg", adjustedImage);

    cv::waitKey(0);
    return 0;
}

代码说明:

  1. cvtColor(inputImage, hsvImage, cv::COLOR_BGR2HSV): 将输入图像从BGR转换到HSV颜色空间。

  2. split(hsvImage, hsvChannels): 将HSV图像分割为3个通道(H、S、V)。

  3. hsvChannels[1].convertTo(hsvChannels[1], -1, scale, 0): 对S通道应用比例缩放来调整饱和度。

  4. merge(hsvChannels, hsvImage): 合并调整后的HSV通道。

  5. cvtColor(hsvImage, outputImage, cv::COLOR_HSV2BGR): 将调整后的HSV图像转换回BGR颜色空间。



4. 调整饱和度的效果

  • 增大饱和度:提高饱和度可以使颜色更加鲜艳和浓烈。
  • 减小饱和度:降低饱和度则会使图像的颜色趋向灰色,最终饱和度为 0 时,图像变为灰度图像。

你可以通过 saturationScale 参数来控制饱和度的增加或减少,值大于 1 增加饱和度,值小于 1 减少饱和度。



posted @ 2024-09-22 12:53  做梦当财神  阅读(115)  评论(0编辑  收藏  举报