# 公式

HSI彩色模型就是色调（hub）、饱和度（saturation）、亮度（intensity）

• 色调：描述纯色（纯黄色、纯蓝色之类）的颜色属性
• 饱和度：描述一种纯色被白光稀释的程度
• 亮度：即强度（类似灰度级的感觉）

## RGB转HSI

I = R + G + B 3 I=\frac{R+G+B}{3}
H = { θ ,  if  B ≤ G 36 0 ∘ − θ ,  if  B > G 其 中 θ = cos ⁡ − 1 { 1 2 [ ( R − G ) + ( R − B ) ] [ ( R − G ) 2 + ( R − B ) ( G − B ) ] 1 / 2 } H=\left\{\begin{array}{ll} \theta, & \text { if } B \leq G \\ 360^{\circ}-\theta, & \text { if } B>G \end{array}\right. \\其中 \theta=\cos ^{-1}\left\{\frac{\frac{1}{2}[(R-G)+(R-B)]}{\left[(R-G)^{2}+(R-B)(G-B)\right]^{1 / 2}}\right\}
S = 1 − 3 min ⁡ ( R , G , B ) R + G + B S=1-\frac{3\min (R, G, B)}{R+G+B}

## HSI转RGB

• 0 ∘ ≤ H < 12 0 ∘ 0^{\circ} \leq H<120^{\circ}
B = I ( 1 − S ) R = I [ 1 + S cos ⁡ H cos ⁡ ( 6 0 ∘ − H ) ] G = 3 I − ( R + B ) \begin{aligned} B &=I(1-S) \\ R &=I\left[1+\frac{S \cos H}{\cos \left(60^{\circ}-H\right)}\right] \\ G &=3 I-(R+B) \end{aligned}
• 12 0 ∘ ≤ H < 24 0 ∘ 120^{\circ} \leq H<240^{\circ}
H = H − 24 0 ∘ R = I ( 1 − S ) G = I [ 1 + S cos ⁡ H cos ⁡ ( 6 0 ∘ − H ) ] B = 3 I − ( R + G ) \begin{aligned} H&=H-240^{\circ}\\ R &=I(1-S) \\ G &=I\left[1+\frac{S \cos H}{\cos \left(60^{\circ}-H\right)}\right] \\ B &=3 I-(R+G) \end{aligned}
• 24 0 ∘ ≤ H < 36 0 ∘ 240^{\circ} \leq H<360^{\circ}
H = H − 24 0 ∘ G = I ( 1 − S ) B = I [ 1 + S cos ⁡ H cos ⁡ ( 6 0 ∘ − H ) ] R = 3 I − ( G + B ) \begin{aligned} H &=H-240^{\circ}\\ G & =I(1-S) \\ B &=I\left[1+\frac{S \cos H}{\cos \left(60^{\circ}-H\right)}\right] \\ R &=3 I-(G+B) \end{aligned}

# RGB转HSI代码

Mat RGB2HSI(const Mat & rgb){
Mat hsi(rgb.rows, rgb.cols, rgb.type());
float  H=0, S=0, I=0;
for(int i=0; i < rgb.rows; i++)
for(int j=0; j < rgb.cols; j++){
float B = rgb.at<Vec3b>(i, j)[0] / 255.f,
G = rgb.at<Vec3b>(i, j)[1] / 255.f,
R = rgb.at<Vec3b>(i, j)[2] / 255.f;

float num = (R - G + R - B) / 2,
den = sqrt((R - G) * (R - G) + (R - B) * (G - B)),
theta = acos(num/den);
if(den == 0) H = 0; // 分母不能为0
else H = B <= G ? theta / (2 * MY_PI) : 1 - theta / (2 * MY_PI);

float sum = B + G + R;
if(sum == 0) S = 0;
else S = 1 - 3 * min(min(B, G), R) / sum;

I = sum/3.0;

hsi.at<Vec3b>(i, j)[0] = H*255;
hsi.at<Vec3b>(i, j)[1] = S*255;
hsi.at<Vec3b>(i, j)[2] = I*255;
}
return hsi;
}


# HSI转RGB代码

Mat HSI2RGB(const Mat & hsi){
Mat rgb(hsi.rows, hsi.cols, hsi.type());
float  R=0,G=0,B=0;
for(int i=0; i < hsi.rows; i++)
for(int j=0; j < hsi.cols; j++){
float H = hsi.at<Vec3b>(i, j)[0] / 255.f * 2 * MY_PI,
S = hsi.at<Vec3b>(i, j)[1] / 255.f,
I = hsi.at<Vec3b>(i, j)[2] / 255.f;

if(H < 120.f * MY_PI / 180.f){
B=I*(1-S);
R=I*(1+ S*cos(H)/cos(60.f* MY_PI / 180.f-H));
G=3*I-R-B;
}
else if(H >= 120.f * MY_PI / 180.f && H < 240 * MY_PI / 180.f){
H-=(120.f * MY_PI / 180.f);
R=I*(1-S);
G=I*(1+ S*cos(H)/cos(60.f* MY_PI / 180.f-H));
B=3*I-R-G;
}
else if(H >= 240.f * MY_PI / 180.f){
H-=(240.f * MY_PI / 180.f);
G=I*(1-S);
B=I*(1+ S*cos(H)/cos(60.f* MY_PI / 180.f-H));
R=3*I-B-G;
}

rgb.at<Vec3b>(i, j)[0] = B*255;
rgb.at<Vec3b>(i, j)[1] = G*255;
rgb.at<Vec3b>(i, j)[2] = R*255;
}
return rgb;
}


# 示例

#include<iostream>
#include <opencv2/opencv.hpp>
#define MY_PI 3.1415
using namespace std;
using namespace cv;
Mat RGB2HSI(const Mat & rgb);
Mat HSI2RGB(const Mat & hsi);
int main(int argc, char * argv[]){
Mat img = imread("../image/RGB.jpg");
imshow("origin", img);
waitKey();

Mat hsi = RGB2HSI(img);
imshow("hsi", hsi);
waitKey();

Mat rgb=HSI2RGB(hsi);
imshow("rgb", rgb);
waitKey();
return 0;
}


• 3
点赞
• 12
收藏
• 打赏
• 0
评论
11-21
03-16
01-03 1560
07-08 1万+
08-23 2609
01-31 549
03-01 3万+
03-21
10-24
01-21 360
04-18 7601
12-08 6394

### “相关推荐”对你有帮助么？

• 非常没帮助
• 没帮助
• 一般
• 有帮助
• 非常有帮助

©️2022 CSDN 皮肤主题：大白 设计师：CSDN官方博客

OTZ_2333

¥2 ¥4 ¥6 ¥10 ¥20

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