OpenCV(图像饱和度)

news/2024/9/22 12:55:51/文章来源:https://www.cnblogs.com/keye/p/18425175

目录
  • 1. 图像饱和度
  • 2. 调整饱和度的基本原理
  • 3. 示例
    • 3.1 对 RGB 图像进行饱和度的调整。
    • 3.2 对 RGB 图像进行饱和度的调整。
  • 4. 调整饱和度的影响



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 减少饱和度。



本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/801474.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用GPU 加速 Polars:高效解决大规模数据问题

Polars 最近新开发了一个可以支持 GPU 加速计算的执行引擎。这个引擎可以对超过 100GB 的数据进行交互式操作能。本文将详细讨论 Polars 中DF的概念、GPU 加速如何与 Polars DF协同工作,以及使用新的 CUDA 驱动执行引擎可能带来的性能提升。 https://avoid.overfit.cn/post/b…

我的网站集成ElasticSearch初体验

最近,我给我的网站(https://www.xiandanplay.com/)尝试集成了一下es来实现我的一个搜索功能,因为这个是我第一次了解运用elastic,所以如果有不对的地方,大家可以指出来,话不多说,先看看我的一个大致流程 这里我采用的sdk的版本是Elastic.Clients.Elasticsearch, Ver…

Flipper Zero极客的便携式多功能工具设备

官网:Flipper Zero — 极客的便携式多功能工具设备 Flipper Zero是近两年比较热门的硬件工具,官方固件主要涵盖的功能为Sub-Ghz,125kHz,NFC,红外。 基本信息资料都可以在官方网站找到比较详细的文档解释。本篇主要是一个基础入门,这系列也是给自己学习此硬件一个上手研究…

C盘扩容免费工具

1.diskgenius 下载 https://www.diskgenius.cn/download.php 解压即可使用,无需安装 2.下载 安装Windows_PE环境 https://www.diskgenius.cn/help/windows_aik_adk_installnotes.php?Version=0A000000&Build=22631&Lang=936 官方软件,安全五毒 3.运行diskgenius ,点…

Leetcode 2464. 有效分割中的最少子数组数目

1.题目基本信息 1.1.题目描述 给定一个整数数组 nums。 如果要将整数数组 nums 拆分为 子数组 后是 有效的,则必须满足: 每个子数组的第一个和最后一个元素的最大公约数 大于 1,且 nums 的每个元素只属于一个子数组。 返回 nums 的 有效 子数组拆分中的 最少 子数组数目。如果…

debian 系统服务器搭建

在VMWare中安装Debian12.5虚拟机后, 需要开始进行一些设置:1. 先设置网络模式为桥接模式, 这样和主机在同一个局域网,方便后续ssh连接 2. 第1步设置后,重启Debian,登录后, 查看IP和Mac地址, 192.168.31.16,00:0c:29:6c:31:e6 3. 设置路由器,固定IP: 192.168.31.105。 …

初识算法

持续更新数据结构与算法专题,欢迎关注.......1.1 什么是算法? 定义 在数学和计算机科学领域,算法是一系列有限的严谨指令,通常用于解决一类特定问题或执行计算In mathematics and computer science, an algorithm (/ˈlɡərɪəm/) is a finite sequence of rigorous inst…

解锁Java线程池:实战技巧与陷阱规避

线程池作为初学者常感困惑的一个领域,本次“巧手打字通课堂”将深入剖析其中几个最为普遍的误区。专业在线打字练习网站-巧手打字通,只输出有价值的知识。一 前言 线程池作为初学者常感困惑的一个领域,本次“巧手打字通课堂”将深入剖析其中几个最为普遍的误区。为了更清晰地…

FFmpeg开发笔记(五十四)使用EasyPusher实现移动端的RTSP直播

​之前的文章《利用RTMP协议构建电脑与手机的直播Demo》介绍了如何使用RTMP Streamer实现完整的RTMP直播流程,另一篇文章《利用SRT协议构建手机APP的直播Demo》介绍了如何使用SRT Streamer实现完整的SRT直播流程,接下来介绍如何使用EasyPusher-Android实现完整的RTSP直播流程…

小飞机配置

小飞机配置把两个文件的文件复制到小飞机的安装路径中小飞机路径:打开文件所在的位置将MSI Afterburner中的文件复制找到RTSS安装路径RTSS设置中文小飞机监控设置选择自己需要显示内容进行OSD显示

Spring原理基础

Spring 高级 1 容器与Bean 1.1 接口容器 1.1.1 BeanFactory是什么 @SpringBootApplication public class ShowApplication {public static void main(String[] args) {ConfigurableApplicationContext context = SpringApplication.run(ShowApplication.class, args);/*** 1、…

springboot+vite 商品管理

SpringBoot + Vue3 +MySql5.7 +JDK8 一、 SpringBoot项目搭建 1 SpringBoot概述 1.1 SpringBoot 概念 SpringBoot提供了一种快速使用Spring的方式,基于约定优于配置的思想,可以让开发人员不必在配置与逻 辑业务之间进行思维的切换,全身心的投入到逻辑业务的代码编写中,从而…