[c++]opencv实现RGB和HSI的相互转换
公式
HSI彩色模型就是色调(hub)、饱和度(saturation)、亮度(intensity)
- 色调:描述纯色(纯黄色、纯蓝色之类)的颜色属性
- 饱和度:描述一种纯色被白光稀释的程度
- 亮度:即强度(类似灰度级的感觉)
以下公式来源论文《Color image enhancement with exact HSI color model》
RGB转HSI
I
=
R
+
G
+
B
3
I=\frac{R+G+B}{3}
I=3R+G+B
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\}
H={θ,360∘−θ, if B≤G if B>G其中θ=cos−1{[(R−G)2+(R−B)(G−B)]1/221[(R−G)+(R−B)]}
S
=
1
−
3
min
(
R
,
G
,
B
)
R
+
G
+
B
S=1-\frac{3\min (R, G, B)}{R+G+B}
S=1−R+G+B3min(R,G,B)
HSI转RGB
-
0
∘
≤
H
<
12
0
∘
0^{\circ} \leq H<120^{\circ}
0∘≤H<120∘
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} BRG=I(1−S)=I[1+cos(60∘−H)ScosH]=3I−(R+B) -
12
0
∘
≤
H
<
24
0
∘
120^{\circ} \leq H<240^{\circ}
120∘≤H<240∘
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} HRGB=H−240∘=I(1−S)=I[1+cos(60∘−H)ScosH]=3I−(R+G) -
24
0
∘
≤
H
<
36
0
∘
240^{\circ} \leq H<360^{\circ}
240∘≤H<360∘
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} HGBR=H−240∘=I(1−S)=I[1+cos(60∘−H)ScosH]=3I−(G+B)
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;
}

更多推荐


所有评论(0)