思路与代码
RGB 转换为 HSI 的计算步骤如下:
首先归一化三通道值 :
r
=
R
R
+
G
+
B
r = \frac{R}{R+G+B}
r=R+G+BR
g
=
G
R
+
G
+
B
g = \frac{G}{R+G+B}
g=R+G+BG
b
=
B
R
+
G
+
B
b = \frac{B}{R+G+B}
b=R+G+BB
接下来,计算 HSI 图像的亮度 I I I:
I = R + G + B 3 I = \frac{R+G+B}{3} I=3R+G+B
然后,计算饱和度 S S S:
S = 1 − 3 R + G + B ⋅ min ( R , G , B ) S = 1 - \frac{3}{R+G+B} \cdot \min(R,G,B) S=1−R+G+B3⋅min(R,G,B)
最后,计算色相 H H H:
H = { θ if B ≤ G 2 π − θ if B > G H = \begin{cases} \theta & \text{if } B \leq G \\ 2\pi - \theta & \text{if } B > G \end{cases} H={θ2π−θif B≤Gif B>G
其中 θ \theta θ为:
θ = arccos ( 1 2 [ ( R − G ) + ( R − B ) ] ( R − G ) 2 + ( R − B ) ( G − B ) ) \theta = \arccos (\frac{\frac{1}{2}[(R-G)+(R-B)]}{\sqrt{(R-G)^2+(R-B)(G-B)}}) θ=arccos((R−G)2+(R−B)(G−B)21[(R−G)+(R−B)])
如果把 θ \theta θ带入 H H H的式子中则是如下形式
H = { cos − 1 ( 1 2 [ ( R − G ) + ( R − B ) ] ( R − G ) 2 + ( R − B ) ( G − B ) ) if B ≤ G 2 π − cos − 1 ( 1 2 [ ( R − G ) + ( R − B ) ] ( R − G ) 2 + ( R − B ) ( G − B ) ) if B > G H = \begin{cases} \cos^{-1}\left(\frac{\frac{1}{2}[(R-G)+(R-B)]}{\sqrt{(R-G)^2+(R-B)(G-B)}}\right) & \text{if } B \leq G \\ 2\pi - \cos^{-1}\left(\frac{\frac{1}{2}[(R-G)+(R-B)]}{\sqrt{(R-G)^2+(R-B)(G-B)}}\right) & \text{if } B > G \end{cases} H=⎩ ⎨ ⎧cos−1((R−G)2+(R−B)(G−B)21[(R−G)+(R−B)])2π−cos−1((R−G)2+(R−B)(G−B)21[(R−G)+(R−B)])if B≤Gif B>G
注:色相值 H H H 是以弧度制表示的
相关的matlab代码大概是这样的
im = imread('1.jpg'); %读入原图
image = imnoise(im,'salt & pepper',0.02);
% 归一化RGB值
normalized_image = double(image) / 255;
% 提取RGB通道
R = normalized_image(:, :, 1);
G = normalized_image(:, :, 2);
B = normalized_image(:, :, 3);
% 计算亮度(Intensity)
I = (R + G + B) / 3;
% 计算饱和度(Saturation)
S = 1 - min(min(R, G), B) ./ I;
% 计算色调(Hue)
H = acos((0.5 * ((R - G) + (R - B))) ./ sqrt((R - G).^2 + (R - B) .* (G - B)));
H(B > G) = 2 * pi - H(B > G);
H = H / (2 * pi);
% 合并HSI通道
hsi_image = cat(3, H, S, I);
但是确实很麻烦,因此可以去matlab官网下载一些有这个功能的工具包(或者说叫做代码集),我下的是下图这个,但是不代表别的不能用(去官网下载要注册账号的):
这是使用了转换函数的简化代码:
clear;
I = imread('3.png'); %读入原图
im = imnoise(I,'salt & pepper',0.01);
hsi_image = rgb2hsi(im);
% 显示原始图像
subplot(2, 2, 1);
imshow(im);
title('原始图像');
% 显示转换后的HSI图像
subplot(2, 2, 2);
imshow(hsi_image);
title('HSI图像');
% 使用平均值滤波器,此处是3*3邻域的
filter = ones(3,3)/9;
h = imfilter(hsi_image, filter);
subplot(2, 2, 3);
imshow(h);
title('HSI降噪完的HSI图像');
hh = hsi2rgb(h);
subplot(2, 2, 4);
imshow(hh);
title('HSI降噪后的RGB图像');
放一下降噪前后的大图对比一下:
HSI转RGB
随后将HSV转换为RGB图像,依旧是依据公式,计算公式如下
R = { I ( 1 − S ) if h < 2 π 3 I [ 1 + S cos ( h − 2 π 3 ) ÷ cos ( π 3 − h ) ] if 2 π 3 ≤ h < 4 π 3 I ( 1 − S ) if h ≥ 4 π 3 R = \begin{cases} I(1-S) & \text{if } h < \frac{2\pi}{3} \\ I\left[1+S\cos\left(h - \frac{2\pi}{3}\right) \div \cos\left(\frac{\pi}{3}-h\right)\right] & \text{if } \frac{2\pi}{3} \leq h < \frac{4\pi}{3} \\ I(1-S) & \text{if } h \geq \frac{4\pi}{3} \end{cases} R=⎩ ⎨ ⎧I(1−S)I[1+Scos(h−32π)÷cos(3π−h)]I(1−S)if h<32πif 32π≤h<34πif h≥34π
G = { I [ 1 + S cos ( h ) ÷ cos ( π 3 − h ) ] if h < 2 π 3 I ( 1 − S ) if 2 π 3 ≤ h < 4 π 3 I [ 1 + S cos ( h − 4 π 3 ) ÷ cos ( π 3 − h ) ] if h ≥ 4 π 3 G = \begin{cases} I\left[1+S\cos\left(h\right) \div \cos\left(\frac{\pi}{3}-h\right)\right] & \text{if } h < \frac{2\pi}{3} \\ I(1-S) & \text{if } \frac{2\pi}{3} \leq h < \frac{4\pi}{3} \\ I\left[1+S\cos\left(h - \frac{4\pi}{3}\right) \div \cos\left(\frac{\pi}{3}-h\right)\right] & \text{if } h \geq \frac{4\pi}{3} \end{cases} G=⎩ ⎨ ⎧I[1+Scos(h)÷cos(3π−h)]I(1−S)I[1+Scos(h−34π)÷cos(3π−h)]if h<32πif 32π≤h<34πif h≥34π
B = { I [ 1 + S cos ( h + 2 π 3 ) ÷ cos ( π 3 − h ) ] if h < 2 π 3 I [ 1 + S cos ( h − 2 π 3 ) ÷ cos ( π 3 − h ) ] if 2 π 3 ≤ h < 4 π 3 I ( 1 − S ) if h ≥ 4 π 3 B = \begin{cases} I\left[1+S\cos\left(h + \frac{2\pi}{3}\right) \div \cos\left(\frac{\pi}{3}-h\right)\right] & \text{if } h < \frac{2\pi}{3} \\ I\left[1+S\cos\left(h - \frac{2\pi}{3}\right) \div \cos\left(\frac{\pi}{3}-h\right)\right] & \text{if } \frac{2\pi}{3} \leq h < \frac{4\pi}{3} \\ I(1-S) & \text{if } h \geq \frac{4\pi}{3} \end{cases} B=⎩ ⎨ ⎧I[1+Scos(h+32π)÷cos(3π−h)]I[1+Scos(h−32π)÷cos(3π−h)]I(1−S)if h<32πif 32π≤h<34πif h≥34π
其中, H H H、 S S S 和 I I I 分别表示 HSI 图像的色相(色调)、饱和度和亮度
在计算 RGB 像素值之前,需要将 HSI 中的色相值转换为弧度制。
相关matlab代码放在下方,因为是自己写的,可能会因疏忽有错,不如直接用上面下载的工具集代码
% 读入HSI图像(是上面代码保存的)
hsi_image = imread('HSI降噪图.jpg');
% 将HSI图像转换为double类型
hsi_image = im2double(hsi_image);
% 分离出HSI图像的各个通道
hue_channel = hsi_image(:,:,1) * 2 * pi;
saturation_channel = hsi_image(:,:,2);
intensity_channel = hsi_image(:,:,3);
% 将HSI通道转换为RGB通道
red_channel = zeros(size(hue_channel));
green_channel = zeros(size(hue_channel));
blue_channel = zeros(size(hue_channel));
% 计算RGB通道的值
for i = 1:size(hue_channel, 1)
for j = 1:size(hue_channel, 2)
if hue_channel(i,j) >= 0 && hue_channel(i,j) < 2/3*pi
blue_channel(i,j) = intensity_channel(i,j) * (1 - saturation_channel(i,j));
red_channel(i,j) = intensity_channel(i,j) * (1 + (saturation_channel(i,j) * cos(hue_channel(i,j))) / cos(pi/3 - hue_channel(i,j)));
green_channel(i,j) = 3 * intensity_channel(i,j) - (red_channel(i,j) + blue_channel(i,j));
elseif hue_channel(i,j) >= 2/3*pi && hue_channel(i,j) < 4/3*pi
hue_channel(i,j) = hue_channel(i,j) - 2/3*pi;
red_channel(i,j) = intensity_channel(i,j) * (1 - saturation_channel(i,j));
green_channel(i,j) = intensity_channel(i,j) * (1 + (saturation_channel(i,j) * cos(hue_channel(i,j))) / cos(pi/3 - hue_channel(i,j)));
blue_channel(i,j) = 3 * intensity_channel(i,j) - (red_channel(i,j) + green_channel(i,j));
else
hue_channel(i,j) = hue_channel(i,j) - 4/3*pi;
green_channel(i,j) = intensity_channel(i,j) * (1 - saturation_channel(i,j));
blue_channel(i,j) = intensity_channel(i,j) * (1 + (saturation_channel(i,j) * cos(hue_channel(i,j))) / cos(pi/3 - hue_channel(i,j)));
red_channel(i,j) = 3 * intensity_channel(i,j) - (green_channel(i,j) + blue_channel(i,j));
end
end
end
% 将RGB通道合成为RGB图像
rgb_image = cat(3, red_channel, green_channel, blue_channel);
% 显示RGB图像
imshow(rgb_image);
imwrite(rgb_image,'降噪后的RGB图.jpg','jpg');