当前位置: 首页 > news >正文

[C++][opencv]基于opencv实现photoshop算法色相和饱和度调整

【测试环境】

vs2019

opencv==4.8.0

【效果演示】

【核心实现代码】

HSL.hpp

#ifndef OPENCV2_PS_HSL_HPP_
#define OPENCV2_PS_HSL_HPP_#include "opencv2/core.hpp"
using namespace cv;namespace cv {enum HSL_COLOR
{HSL_ALL,HSL_RED,HSL_YELLOW,HSL_GREEN,HSL_CYAN,HSL_BLUE,HSL_MAGENTA,
};/*** Class of HSL parameters for one channel*/
class HSLChannel {
public:int hue;          //色度调整值,     数据范围:  [-180, 180]int saturation;   //饱和度调整值,数据范围:  [-100, 100]int brightness;   //明度调整值,    数据范围:  [-100, 100]int   colorIndex;  //color index: 0 = RED, 1 = YELLOW, 2 = GREENfloat left_left;  //hue range left-leftfloat left;       //hue range leftfloat right;	  //hue range rightfloat right_right;//hue range right-rightbool defined;     //HSLChannel();virtual ~HSLChannel();void calcDefined();void setColorIndex(int index);bool match(float hue);void adjust(int h, float *delta_hsb);
};/*** Class of HSL*/
class HSL {
public:HSL();virtual ~HSL();HSLChannel channels[7];int adjust(InputArray src, OutputArray dst);
};} /* namespace cv */#endif /* OPENCV2_PS_HSL_HPP_ */

 HSL.cpp

#include "HSL.hpp"
#include "ColorSpace.hpp"
#include <math.h>#define CLIP_RANGE(value, min, max)  ( (value) > (max) ? (max) : (((value) < (min)) ? (min) : (value)) )
#define COLOR_RANGE(value)  CLIP_RANGE(value, 0, 255)namespace cv {HSLChannel::HSLChannel()
{hue = 0;saturation = 0;brightness = 0;defined = false;setColorIndex(0);
}HSLChannel::~HSLChannel()
{}void HSLChannel::setColorIndex(int index)
{int data[][4] = {{  0,   0, 360, 360},{315, 345,  15,  45},{ 15,  45,  75, 105},{ 75, 105, 135, 165},{135, 165, 195, 225},{195, 225, 255, 285},{255, 285, 315, 345}};if (index < 0 ) index = 0;if (index > 6 ) index = 6;colorIndex = index;left_left = data[index][0];left      = data[index][1];right     = data[index][2];right_right = data[index][3];
}void HSLChannel::calcDefined()
{if ( hue != 0 || saturation != 0 || brightness != 0 ) {defined = true;return;}defined = false;
}bool  HSLChannel::match(float hue)
{if ( left < right ) {if ( hue >= left_left && hue <= right_right )return true;} else {if ( hue >=left_left && hue <= 360 )return true;if ( hue >=0 && hue <= right_right )return true;}return false;
}void HSLChannel::adjust(int h, float *delta_hsb)
{if (colorIndex == 0 ) {delta_hsb[0] += hue;delta_hsb[1] += saturation;delta_hsb[2] += brightness;return;}if ( left < right ) {if ( h >= left_left && h <= right_right ) {if ( h >=left && h <= right) {delta_hsb[0] += hue;delta_hsb[1] += saturation;delta_hsb[2] += brightness;return;}if ( h >=left_left && h <= left && left > left_left) {delta_hsb[0] += hue * (h - left_left) / (left - left_left);delta_hsb[1] += saturation * (h - left_left) / (left - left_left);delta_hsb[2] += brightness * (h - left_left) / (left - left_left);return;}if ( h >=right && h <= right_right && right_right > right) {delta_hsb[0] += hue * (right_right - h) / (right_right - right);delta_hsb[1] += saturation * (right_right - h) / (right_right - right);delta_hsb[2] += brightness * (right_right - h) / (right_right - right);return;}}} else {if ( h >=left && h <= 360 ) {delta_hsb[0] += hue;delta_hsb[1] += saturation;delta_hsb[2] += brightness;return;}if ( h >=0 && h <= right ) {delta_hsb[0] += hue;delta_hsb[1] += saturation;delta_hsb[2] += brightness;return;}if ( h >=left_left && h <= left && left > left_left) {delta_hsb[0] += hue * (h - left_left) / (left - left_left);delta_hsb[1] += saturation * (h - left_left) / (left - left_left);delta_hsb[2] += brightness * (h - left_left) / (left - left_left);return;}if ( h >=right && h <= right_right && right_right > right) {delta_hsb[0] += hue * (right_right - h) / (right_right - right);delta_hsb[1] += saturation * (right_right - h) / (right_right - right);delta_hsb[2] += brightness * (right_right - h) / (right_right - right);return;}}
}//----------------------------------------------------------
//HSL classHSL::HSL()
{for (int i = 0; i < 7; i++)channels[i].setColorIndex(i);
}HSL::~HSL()
{
}int HSL::adjust(InputArray src, OutputArray dst)
{Mat input = src.getMat();if( input.empty() ) {return -1;}dst.create(src.size(), src.type());Mat output = dst.getMat();const uchar *in;uchar *out;int width = input.cols;int height = input.rows;int channel_count = input.channels();float hsb[3];float delta_hsb[3];//calculate definedfor (int i = 0; i < 7; i++)channels[i].calcDefined();//scan pixels of imagefor (int y = 0; y < height; y ++) {in = input.ptr<uchar>(y);out = output.ptr<uchar>(y);for (int x = 0; x < width; x ++) {//RGB to HSL conversionBGR2HSB(in, hsb);//adjust each channeldelta_hsb[0] = delta_hsb[1] = delta_hsb[2] = 0;for (int i = 0; i < 7; i++) {if ( channels[i].defined ) {channels[i].adjust(hsb[0], delta_hsb);}}//adjust huehsb[0] = int(hsb[0] + delta_hsb[0]) % 360;if ( hsb[0] <  0 ) hsb[0] += 360;//adjust saturationdelta_hsb[1] = CLIP_RANGE(delta_hsb[1], -100, 100);if ( delta_hsb[1] < 0) {hsb[1] = hsb[1] * (1 + delta_hsb[1] / 100.0);} else {hsb[1] = hsb[1] + ( 1 - hsb[1] ) * delta_hsb[1] / 100.0; //saturation increasehsb[2] = hsb[2] + ( 1 - hsb[2] ) * delta_hsb[1] / 100.0; //brightness increase}//adjust brightnessdelta_hsb[2] = CLIP_RANGE(delta_hsb[2], -100, 100);if ( delta_hsb[2] < 0) {hsb[2] = hsb[2] * (1 + delta_hsb[2] / 100.0);} else {hsb[2] = hsb[2] + ( 1 - hsb[2] ) * delta_hsb[2] / 100.0; //brightness increasehsb[1] = hsb[1] - hsb[1]  * delta_hsb[2] / 100.0; //saturation decrease}//save to outputHSB2BGR(hsb, out);//move to next pixelin += 3;out += 3;for (int c = 0; c < channel_count - 3; c++) {*out++ = *in++;}}}return 0;
}} /* namespace cv */

【完整演示源码下载】

https://download.csdn.net/download/FL1623863129/88600796

【参考文献】

1 https://blog.csdn.net/c80486/article/details/52505546

相关文章:

[C++][opencv]基于opencv实现photoshop算法色相和饱和度调整

【测试环境】 vs2019 opencv4.8.0 【效果演示】 【核心实现代码】 HSL.hpp #ifndef OPENCV2_PS_HSL_HPP_ #define OPENCV2_PS_HSL_HPP_#include "opencv2/core.hpp" using namespace cv;namespace cv {enum HSL_COLOR {HSL_ALL,HSL_RED,HSL_YELLOW,HSL_GREEN,HS…...

Github 2024-08-16Java开源项目日报 Top10

根据Github Trendings的统计,今日(2024-08-16统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Java项目10TypeScript项目1Ruby项目1Apache Dubbo: 高性能的Java开源RPC框架 创建周期:4441 天开发语言:Java协议类型:Apache License 2.0St…...

AI学习记录 - torch 的 matmul和dot的关联,也就是点乘和点积的联系

有用大佬们点点赞 1、两个一维向量点积 &#xff0c;求 词A 与 词A 之间的关联度 2、两个词向量之间求关联度&#xff0c;求 : 词A 与 词A 的关联度 5 词A 与 词B 的关联度 11 词B 与 词A 的关联度 11 词B 与 词B 的关联度 25 刚刚好和矩阵乘法符合&#xff1a; 3、什么是…...

leetcode 885. Spiral Matrix III

题目链接 You start at the cell (rStart, cStart) of an rows x cols grid facing east. The northwest corner is at the first row and column in the grid, and the southeast corner is at the last row and column. You will walk in a clockwise spiral shape to visi…...

mysql windows安装与远程连接配置

安装包在主页资源中 一、安装(此安装教程为“mysql-installer-community-5.7.41.0.msi”安装教程&#xff0c;安装到win10环境) 保持默认选项&#xff0c;点击”Next“。 点开第一行加号展开一路展开找到“MySQL Server 5,7,41 - X64”点击选中点击一下中间只想右侧的箭头看到…...

子网掩码是什么以及子网掩码相关计算

子网掩码 (Subnet Mask) 又称网络掩码 (Netmask)&#xff0c;告知主机或路由设备&#xff0c;地址的哪一部分是网络号&#xff0c;包括子网的网络号部分&#xff0c;哪一部分是主机号部分。 子网掩码使用与IP地址相同的编址格式&#xff0c;即32 bit—4个8位组的32位长格式。…...

仿RabbitMQ实现消息队列

前言&#xff1a;本项目是仿照RabbitMQ并基于SpringBoot Mybatis SQLite3实现的消息队列&#xff0c;该项目实现了MQ的核心功能&#xff1a;生产者、消费者、中间人、发布、订阅等。 源码链接&#xff1a;仿Rabbit MQ实现消息队列 目录 前言&#xff1a;本项目是仿照Rabbi…...

SpringBoot教程(二十三) | SpringBoot实现分布式定时任务之xxl-job

SpringBoot教程&#xff08;二十三&#xff09; | SpringBoot实现分布式定时任务之xxl-job 简介一、前置条件&#xff1a;需要搭建调度中心1、先下载调度中心源码2、修改配置文件3、启动项目4、进行访问5、打包部署&#xff08;上正式&#xff09; 二、SpringBoot集成Xxl-Job1.…...

微前端架构的数据持久化策略与实践

微前端架构通过将一个大型前端应用拆分成多个小型、自治的子应用&#xff0c;提升了开发效率和应用的可维护性。然而&#xff0c;数据持久化作为应用的基础需求&#xff0c;在微前端架构中实现起来面临着一些挑战。本文将详细介绍在微前端架构下实现数据持久化的策略、技术和最…...

讲解 狼人杀中的买单双是什么意思

买单双这个概念通常出现在有第三方的板子中 比如 咒狐板子 丘比特板子 咒狐板子 第一天狼队只要推掉预言家 第二天就可以与咒狐协商绑票 推出其他好人 以及丘比特板子 如果拉出一个人狼链 那么如果孤独再连一个狼人 那么 狼队第一天就可以直接派人上去拿警徽&#xff0c;这样…...

回归分析系列5-贝叶斯回归

07贝叶斯回归 7.1 简介 贝叶斯回归将贝叶斯统计的思想应用于回归分析中&#xff0c;通过先验分布和似然函数来推断后验分布。在贝叶斯回归中&#xff0c;模型参数被视为随机变量&#xff0c;并且有自己的分布。通过贝叶斯公式&#xff0c;可以更新这些参数的分布&#xff0c;…...

oracle 数据中lsnrctl 是干啥的

突然发现lsnrctl stop 之后&#xff0c;依然可以启动数据库 就感觉怪怪的&#xff0c;一直以为这个是数据库的守护进程&#xff0c;原来不是。。。。 lsnrctl 是 Oracle 监听器控制实用程序的命令行界面工具&#xff0c;用于管理 Oracle Net 服务监听器。监听器是 Oracle 网络…...

Linux进程--进程地址空间

文章目录 一、进程地址空间1.想当然的内存2.实际的内存1.什么是地址空间2.地址空间和内存3.为什么要区分两种内存 一、进程地址空间 1.想当然的内存 我们在之前的学习中了解过内存的概念&#xff0c;所以变量都要存在内存中我们的程序才能跑起来&#xff0c;那么我们肯定也见…...

C语言传递指针给函数

C 语言允许您传递指针给函数&#xff0c;只需要简单地声明函数参数为指针类型即可。 下面的实例中&#xff0c;我们传递一个无符号的 long 型指针给函数&#xff0c;并在函数内改变这个值 实例1&#xff1a;获取系统的时间值 能接受指针作为参数的函数&#xff0c;也能接受数…...

探索 Kubernetes 持久化存储之 Rook Ceph 初窥门径

在 Kubernetes 生态系统中&#xff0c;持久化存储是支撑业务应用稳定运行的基石&#xff0c;对于维护整个系统的健壮性至关重要。对于选择自主搭建 Kubernetes 集群的运维架构师来说&#xff0c;挑选合适的后端持久化存储解决方案是关键的选型决策。目前&#xff0c;Ceph、Glus…...

今日(2024 年 8 月 13 日)科技新闻

我国成功发射卫星互联网高轨卫星&#xff1a;该卫星的成功发射将助力我国卫星互联网的发展。中国首台中子全散射谱仪运行 3 年成果丰硕&#xff1a;由粤港科技合作打造的多物理谱仪&#xff0c;在中国散裂中子源上运行 3 年来&#xff0c;已完成 300 多项用户实验。该谱仪的关键…...

Unity大场景切换进行异步加载时,如何设计加载进度条,并配置滑动条按照的曲线给定的速率滑动

一、异步加载场景的过程 1、异步加载场景用到的API LoadSceneAsync 2、异步加载的参数说明 &#xff08;1&#xff09;默认参数&#xff1a;SceneManagement.LoadSceneAsync(“SceneName”); AsyncOperation task SceneManager.LoadSceneAsync("SceneName");&a…...

Selenium + Python 自动化测试16(Python基础复习)

我们的目标是&#xff1a;按照这一套资料学习下来&#xff0c;大家可以独立完成自动化测试的任务。 上一篇我们讨论了使用模块化测试的测试模型&#xff0c;从某一程度也反映出熟练掌握一门编程语言的重要性。 为了后续进一步深入学习。本篇文章主要做下Python基础知识的复习。…...

2024新型数字政府综合解决方案(六)

新型数字政府综合解决方案通过融合人工智能、大数据、区块链和云计算技术&#xff0c;构建了一个全方位智能化的政务平台&#xff0c;旨在提升政府服务的效率、透明度和公众参与度。该方案实现了跨部门的数据互联互通与实时更新&#xff0c;利用先进的数据分析和自动化处理技术…...

vscode的C/C++环境配置和调试技巧

目录 1.背景 2.下载编译器 3.配置环境变量 4.安装C/C插件 5.写C语言代码并且编译成功 5.1文件操作 5.2对于两个窗口的解释 5.3C语言编译环境配置 6.创建执行文件 7.编译运行过程 8.写其他的代码的解决方案一 9.写其他的代码的解决方案二 10.同时编译多个.c文件 10…...

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下&#xff0c;虚拟教学实训宛如一颗璀璨的新星&#xff0c;正发挥着不可或缺且日益凸显的关键作用&#xff0c;源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例&#xff0c;汽车生产线上各类…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明

AI 领域的快速发展正在催生一个新时代&#xff0c;智能代理&#xff08;agents&#xff09;不再是孤立的个体&#xff0c;而是能够像一个数字团队一样协作。然而&#xff0c;当前 AI 生态系统的碎片化阻碍了这一愿景的实现&#xff0c;导致了“AI 巴别塔问题”——不同代理之间…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。

1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj&#xff0c;再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台

🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...

如何在网页里填写 PDF 表格?

有时候&#xff0c;你可能希望用户能在你的网站上填写 PDF 表单。然而&#xff0c;这件事并不简单&#xff0c;因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件&#xff0c;但原生并不支持编辑或填写它们。更糟的是&#xff0c;如果你想收集表单数据&#xff…...

在Ubuntu24上采用Wine打开SourceInsight

1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖

在Vuzix M400 AR智能眼镜的助力下&#xff0c;卢森堡罗伯特舒曼医院&#xff08;the Robert Schuman Hospitals, HRS&#xff09;凭借在无菌制剂生产流程中引入增强现实技术&#xff08;AR&#xff09;创新项目&#xff0c;荣获了2024年6月7日由卢森堡医院药剂师协会&#xff0…...

Mysql8 忘记密码重置,以及问题解决

1.使用免密登录 找到配置MySQL文件&#xff0c;我的文件路径是/etc/mysql/my.cnf&#xff0c;有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...

MySQL JOIN 表过多的优化思路

当 MySQL 查询涉及大量表 JOIN 时&#xff0c;性能会显著下降。以下是优化思路和简易实现方法&#xff1a; 一、核心优化思路 减少 JOIN 数量 数据冗余&#xff1a;添加必要的冗余字段&#xff08;如订单表直接存储用户名&#xff09;合并表&#xff1a;将频繁关联的小表合并成…...

解析奥地利 XARION激光超声检测系统:无膜光学麦克风 + 无耦合剂的技术协同优势及多元应用

在工业制造领域&#xff0c;无损检测&#xff08;NDT)的精度与效率直接影响产品质量与生产安全。奥地利 XARION开发的激光超声精密检测系统&#xff0c;以非接触式光学麦克风技术为核心&#xff0c;打破传统检测瓶颈&#xff0c;为半导体、航空航天、汽车制造等行业提供了高灵敏…...