点击链接→【数字图像处理】简单实践汇总
1. RBG转HSI理论
- H:色调(Hue);
- S:饱和度(Saturation);
- I:亮度(Intensity);
- 公式:
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);