opencv学习4——HSV与RGB的转换

在进行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;
}

 

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值