赞
踩
在进行HSV和RGB转换之前大致了解一下两者的区别。
HSV颜色模型是根据颜色的直观特征所创立的一种颜色模型,它的名字就代表了这个模型的三个参数H,S,V。模型为六棱锥,三个参数就在上面不同维度进行表示。模型如下。原图来源百度百科。前者是空间模型,后者是模型概念图
H(Hue):色调。采用角度表示,在模型中为棱锥的底面,因此范围就是0~360度,如图所示,不同的角度规定了不同的颜色。0度表示红色,每隔120度分别为绿色和蓝色,对应三基色RGB,他们两两之间又以60度为间隔加入互补色,由0度逆时针开始分别为黄色,青色和品红色(紫色)。
S(Saturation):饱和度。定义为接近光谱色的程度。取值范围是0~1(图片为IPL_DEPTH_32F类型)或0~255(图片为IPL_DEPTH_8UC类型),饱和度越高颜色越深,白色的饱和度为0,。
V(Value):明度。颜色的明暗程度,范围0~1,0为黑色,1为白色。图片类型不同的情况同S。
RGB模型为三维立体图,模型如下所示。每隔维度的取值范围是0~255,0为黑色,255为白色。
两者之间具有密切的关联,当RGB的模型沿着原点的对角线,即黑色点与白色点的连线为垂直轴观察就会转换至HSV的模型。
RGB->HSV的转换关系如下。
- max=max(R,G,B)
- min=min(R,G,B)
- H= 0 (max=min)
- 60 x (G-R) / (max-min) + 60 (min=B)
- 60 x (B-G) / (max-min) + 180 (min=R)
- 60 x (R-B) / (max-min) + 300 (min=G)
- S = Max - Min
- V = Max
-
或者是
- max=max(R,G,B)
- min=min(R,G,B)
- H = (G-B)/(max-min)* 60 (R = max)
- 120+(B-R)/(max-min)* 60 (G = max)
- 240 +(R-G)/(max-min)* 60 (B = max)
- H+ 360 (H < 0)
- S=(max-min)/max
- V=max(R,G,B)
HSV->RGB的转换关系如下。https://blog.csdn.net/qq_45391763/article/details/103450672
代码如下。
- #include"iostream"
- #include"opencv2/core/core.hpp"
- #include"opencv2/highgui/highgui.hpp"
- #include<opencv2/opencv.hpp>
- #include<math.h>
- using namespace cv;
- using namespace std;
- Mat BGR2HSV(Mat bgrimg){
- int bgrimgcol = bgrimg.cols;
- int bgrimgrow = bgrimg.rows;
- float r, g, b;
- float h, s, v;
- float Max, Min;
- Mat hsvimg = Mat::zeros(bgrimgrow, bgrimgcol, CV_32FC3);
- for (int j = 0; j < bgrimgrow; j++) {
- for (int i = 0; i < bgrimgcol; i++) {
- r = (float)bgrimg.at<Vec3b>(j, i)[2]/255;
- g = (float)bgrimg.at<Vec3b>(j, i)[1]/255;
- b = (float)bgrimg.at<Vec3b>(j, i)[0]/255;
- Max = max(r, max(g, b));
- Min = min(r, min(g, b));
- if (Max == Min) {
- h = 0;
- }
- else if (Min == b) {
- h = 60 * (g - r) / (Max - Min) + 60;
- }
- else if (Min == r) {
- h = 60 * (b - g) / (Max - Min) + 180;
- }
- else if (Min == g) {
- h = 60 * (r - b) / (Max - Min) + 300;
- }
- s = Max - Min;
- v = Max;
- hsvimg.at<Vec3f>(j, i)[0] = h;
- hsvimg.at<Vec3f>(j, i)[1] = s;
- hsvimg.at<Vec3f>(j, i)[2] = v;
- }
- }
- return hsvimg;
- }
- void main(){
- Mat img = imread("ck567.jpg", IMREAD_COLOR);
- Mat out = BGR2HSV(img);
- imshow("sample",out);
- waitKey(0);
- destroyAllWindows();
- }
HSV转换BGR的函数如下
- Mat HSV2BGR(Mat hsvimg){
- int hsvimgcol = hsvimg.cols;
- int hsvimgrow = hsvimg.rows;
- Mat hsv = Mat::zeros(hsvimgrow, hsvimgcol, CV_8UC3);
- float h, s, v;
- double c, h_, x;
- double r, g, b;
- for (int y = 0; y < hsvimgrow; y++) {
- for (int x = 0; x < hsvimgcol; x++) {
- h = hsvimg.at<Vec3f>(y, x)[0];
- s = hsvimg.at<Vec3f>(y, x)[1];
- v = hsvimg.at<Vec3f>(y, x)[2];
- c = s;
- h_ = h / 60;
- x = c * (1 - abs(fmod(h_, 2) - 1));
- r = g = b = v - c;
- if (h_ < 1) {
- r += c;
- g += x;
- }
- else if (h_ < 2) {
- r += x;
- g += c;
- }
- else if (h_ < 3) {
- g += c;
- b += x;
- }
- else if (h_ < 4) {
- g += x;
- b += c;
- }
- else if (h_ < 5) {
- r += x;
- b += c;
- }
- else if (h_ < 6) {
- r += c;
- b += x;
- }
- //以上代码可用switch结构代替
- hsv.at<Vec3b>(y, x)[0] = (uchar)(b * 255);
- hsv.at<Vec3b>(y, x)[1] = (uchar)(g * 255);
- hsv.at<Vec3b>(y, x)[2] = (uchar)(r * 255);
- }
- }
- return hsv;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。