基于OpenCV的RGB和HSV色彩空间相互转换C++程序

2024-08-28 14:18

本文主要是介绍基于OpenCV的RGB和HSV色彩空间相互转换C++程序,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

       之所以说基于opencv,由于转换程序用到了一些OpenCV函数及数据类型。
       OpenCV全称:Open Source Computer Vision Library,开源 、免费, 很好很强大。

帮助文档: http://docs.opencv.org/index.html

但凡图像处理软件,都会提供色相、饱和度、明度调整功能,比如常见的PS或者美图秀秀。在调整色相、饱和度、明度时,需要将每个像素点的rgb色彩空间转换到hsv色彩空间,然后做相应计算调整,最后在将计算结果转换回rgb颜色空间进行显示。有关概念及转换公式可以参考: http://zh.wikipedia.org/wiki/HSL%E5%92%8CHSV%E8%89%B2%E5%BD%A9%E7%A9%BA%E9%97%B4,
对于每个颜色向量 (r, g, b),参照转换公式,两个空间的相互转换就十分简单了。
下面为C++转换代码:
struct BGR
{uchar b;uchar g;uchar r;
};struct HSV
{int h;double s;double v;
};bool IsEquals(double val1 , double val2)
{return fabs(val1 - val2) < 0.001;
}// BGR(BGR: 0~255)转HSV(H: [0~360), S: [0~1], V: [0~1])
void BGR2HSV(BGR &bgr, HSV &hsv)
{double b, g, r;double h, s, v;double min, max;double delta;b = bgr.b / 255.0;g = bgr.g / 255.0;r = bgr.r / 255.0;if (r > g){max = MAX(r, b);min = MIN(g, b);}else{max = MAX(g, b);min = MIN(r, b);}v = max;delta = max - min;if (IsEquals(max, 0)){s = 0.0;}else{s = delta / max;}if (max == min){h = 0.0;}else{if (IsEquals(r, max) && g >= b){h = 60 * (g - b) / delta + 0;}else if (IsEquals(r, max) && g < b){h = 60 * (g - b) / delta + 360;}else if (IsEquals(g, max)){h = 60 * (b - r) / delta + 120;}else if (IsEquals(b, max)){h = 60 * (r - g) / delta + 240;}}hsv.h = (int)(h + 0.5);hsv.h = (hsv.h > 359) ? (hsv.h - 360) : hsv.h;hsv.h = (hsv.h < 0) ? (hsv. h + 360) : hsv.h;hsv.s = s;hsv.v = v;
}// HSV转BGR
void HSV2BGR(HSV &hsv, BGR &bgr)
{int h = hsv.h;double s = hsv. s;double v = hsv. v;double b = 0.0;double g = 0.0;double r = 0.0;int flag = (int)abs(h / 60.0);double f = h/60.0 - flag;double p = v * (1 - s);double q = v * (1 - f*s);double t = v * (1 - (1- f)*s);switch (flag){case 0:b = p;g = t;r = v;break;case 1:b = p;g = v;r = q;break;case 2:b = t;g = v;r = p;break;case 3:b = v;g = q;r = p;break;case 4:b = v;g = p;r = t;break;case 5:b = q;g = p;r = v;break;default:break;}int blue = int(b * 255);bgr.b = (blue > 255) ? 255 : blue;bgr.b = (blue < 0) ? 0 : bgr.b;int green = int(g * 255);bgr.g = (green > 255) ? 255 : green;bgr.g = (green < 0) ? 0 : bgr.g;int red = int(r * 255);bgr.r = (red > 255) ? 255 : red;bgr.r = (red < 0) ? 0 : bgr.r;
}int main()
{string imgName = "lena.jpg";Mat img = cv::imread(imgName);Mat tmp = img.clone();if (img.data == NULL){cout<< "Could not open or find the image"<<endl;return -1;}// 色彩空间转换>>自己实现int row = img.rows; int col = img.cols * img.channels(); uchar * pImg = NULL;BGR bgr; HSV hsv;for (int i = 0; i < row; i++) { pImg = img.ptr<uchar>(i);// 遍历时用img.at()效率会降很多, 很耗时 for (int j = 0; j < col; j+=3) {bgr.b = pImg[j]; bgr.g = pImg[j + 1]; bgr.r = pImg[j + 2]; BGR2HSV(bgr, hsv); hsv.h = hsv.h + 60;//调整色相 +60.取值范围为[0, 360) hsv.h = (hsv.h > 359) ? (hsv.h - 360) : hsv.h; hsv.h = (hsv.h < 0)   ? (hsv.h + 360) : hsv.h; HSV2BGR( hsv, bgr); pImg[j] = bgr.b; pImg[j + 1] = bgr.g; pImg[j + 2] = bgr.r; } } imshow("my", img);// 色彩空间转换>>调用OpenCVcvtColor(tmp, tmp, CV_BGR2HSV); vector<Mat> channels; split(tmp, channels); channels[0] += 30;// 调整色相 +30.这里没有做范围判断,opencv的h取值范围为[0, 180) merge(channels, tmp); cvtColor(tmp, tmp, CV_HSV2BGR); imshow("opencv", tmp); cv::waitKey();return 0;
}
ps:main()函数中同时提供了调用opencv函数实现的色相调整功能,主要使用了cvtColor():色彩空间转换、split():通道分离及merge():通道合并等函数。程序使用的opencv版本为210,运行上述程序还需添加opencv头文件引用以及配置相应lib文件。由于程序只是作为验证demo,所以写的有点乱、不够优化。

这篇关于基于OpenCV的RGB和HSV色彩空间相互转换C++程序的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1114998

相关文章

【C++ Primer Plus习题】13.4

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: main.cpp #include <iostream>#include "port.h"int main() {Port p1;Port p2("Abc", "Bcc", 30);std::cout <<

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

C++包装器

包装器 在 C++ 中,“包装器”通常指的是一种设计模式或编程技巧,用于封装其他代码或对象,使其更易于使用、管理或扩展。包装器的概念在编程中非常普遍,可以用于函数、类、库等多个方面。下面是几个常见的 “包装器” 类型: 1. 函数包装器 函数包装器用于封装一个或多个函数,使其接口更统一或更便于调用。例如,std::function 是一个通用的函数包装器,它可以存储任意可调用对象(函数、函数

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

06 C++Lambda表达式

lambda表达式的定义 没有显式模版形参的lambda表达式 [捕获] 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 有显式模版形参的lambda表达式 [捕获] <模版形参> 模版约束 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 含义 捕获:包含零个或者多个捕获符的逗号分隔列表 模板形参:用于泛型lambda提供个模板形参的名

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)

【C++高阶】C++类型转换全攻略:深入理解并高效应用

📝个人主页🌹:Eternity._ ⏩收录专栏⏪:C++ “ 登神长阶 ” 🤡往期回顾🤡:C++ 智能指针 🌹🌹期待您的关注 🌹🌹 ❀C++的类型转换 📒1. C语言中的类型转换📚2. C++强制类型转换⛰️static_cast🌞reinterpret_cast⭐const_cast🍁dynamic_cast 📜3. C++强制类型转换的原因📝

C++——stack、queue的实现及deque的介绍

目录 1.stack与queue的实现 1.1stack的实现  1.2 queue的实现 2.重温vector、list、stack、queue的介绍 2.1 STL标准库中stack和queue的底层结构  3.deque的简单介绍 3.1为什么选择deque作为stack和queue的底层默认容器  3.2 STL中对stack与queue的模拟实现 ①stack模拟实现