點選連結→【數字圖像處理】簡單實踐彙總
文章目錄
-
-
- 1. RBG轉HSI理論
- 2. RBG轉HSI代碼
- 3. HSI轉RBG,提取紅色
- 4. 效果
-
1. RBG轉HSI理論
- H:色調(Hue);
- S:飽和度(Saturation);
- I:亮度(Intensity);
-
公式:
亮 度 : I = 1 3 ( R + G + B ) 飽 和 度 : S = I − 3 ( R + G + B ) [ min ( R , G , B ) ] 色 調 : H = arccos { [ ( R − G ) + ( R − B ) ] / 2 [ ( R − G ) 2 + ( R − B ) ( G − B ) ] 1 / 2 } 亮度:I = \frac { 1 } { 3 } ( R + G + B ) \\ 飽和度:S = I - \frac { 3 } { ( R + G + B ) } [ \min ( R , G , B ) ] \\ 色調:H = \arccos \left\{\frac { [ ( R - G ) + ( R - B ) ] / 2 } { \left[ ( R - G ) ^ { 2 } + ( R - B ) ( G - B ) \right] ^ { 1 / 2 } } \right\} 亮度:I=31(R+G+B)飽和度:S=I−(R+G+B)3[min(R,G,B)]色調:H=arccos{[(R−G)2+(R−B)(G−B)]1/2[(R−G)+(R−B)]/2}
2. RBG轉HSI代碼
#define H_RANGE_1 25
#define H_RANGE_2 300
Mat srcImage = imread(SRC_IMAGE, 1);
imshow(WIMDOW_NAME, srcImage);
Mat img_HSI;
img_HSI.create(srcImage.rows, srcImage.cols, CV_8UC3);
Mat img_Out;
img_Out.create(srcImage.rows, srcImage.cols, CV_8UC3);
//srcImage to img_HSI
for (int i = 0; i < srcImage.rows; i++) {
for (int j = 0; j < srcImage.cols; j++) {
double b = (double)srcImage.at<Vec3b>(i, j)[0] / 255;
double g = (double)srcImage.at<Vec3b>(i, j)[1] / 255;
double r = (double)srcImage.at<Vec3b>(i, j)[2] / 255;
double H, S, I;
double num = 0.5 * ((r - g) + (r - b));
double den = sqrt((r - g) * (r - g) + (r - b) * (g - b));
if (den == 0)
{
H = 0;
}
else
{
double theta = acos(num / den);
H = 360 * theta / (PI * 2);
if (b > g)
{
H = 360 - H;
}
}
double minRGB = min(min(r, g), b);
den = r + g + b;
if (den == 0)
{
S = 0;
}
else
{
S = 1 - 3.0 * minRGB / den;
}
I = den / 3.0;
img_HSI.at<Vec3b>(i, j)[0] = H / 360 * 255;
img_HSI.at<Vec3b>(i, j)[1] = S * 255;
img_HSI.at<Vec3b>(i, j)[2] = I * 255;
}
}
imshow("HSI", img_HSI);
3. HSI轉RBG,提取紅色
注意: 因為白色的色調也在紅色範圍,是以需要用飽和度來排除白色
//img_HSI to img_Out
for (int i = 0; i < srcImage.rows; i++) {
for (int j = 0; j < srcImage.cols; j++) {
double H = (double)img_HSI.at<Vec3b>(i, j)[0] / 255 * 360;
double S = (double)img_HSI.at<Vec3b>(i, j)[1] / 255;
double I = (double)img_HSI.at<Vec3b>(i, j)[2] / 255;
double R = 0, G = 0, B = 0;
if (H >= H_RANGE_1 && H < H_RANGE_2)
{
H = 0;
S = 0;
I = 0;
}
if (S < 0.2) //用飽和度排除白色
{
H = 0;
S = 0;
I = 0;
}
if (H > 0 && H < 120)
{
B = I * (1 - S);
R = I * (1 + (S * cos(H * PI / 180)) / (cos((60 - H) * PI / 180)));
G = 3 * I - (R + B);
}
else if (H >= 120 && H < 240)
{
H = H - 120;
R = I * (1 - S);
G = I * (1 + (S * cos(H * PI / 180)) / (cos((60 - H) * PI / 180)));
B = 3 * I - (R + G);
}
else if (H >= 240 && H < 360)
{
H = H - 240;
G = I * (1 - S);
B = I * (1 + (S * cos(H * PI / 180)) / (cos((60 - H) * PI / 180)));
R = 3 * I - (G + B);
}
img_Out.at<Vec3b>(i, j)[0] = B * 255;
img_Out.at<Vec3b>(i, j)[1] = G * 255;
img_Out.at<Vec3b>(i, j)[2] = R * 255;
}
}
imshow("Out", img_Out);