天天看點

彩色圖像的空間域濾波

(1) RGB彩色空間向HSI彩色空間的轉換:

自定義一個函數,實作RGB彩色空間向HSI彩色空間的轉換,要求該函數的輸入參數為RGB彩色圖像,輸出參數為HSI彩色圖像。

根據RGB彩色空間到HSI彩色空間的轉換公式,編寫函數 RGBtoHSI(pho)

% pho 表示輸入圖像路徑(包括圖像名+字尾)
function hsi = RGBtoHSI(pho)
ima=imread(pho); %讀取輸入圖像
rgb=double(ima); %将圖像轉為雙精度類型
rgb=rgb/255; %歸一化
R=rgb(:,:,1); %提取第1個通道
G=rgb(:,:,2); %提取第2個通道
B=rgb(:,:,3); %提取第3個通道
 
angle=(acos(1/2*((R-G)+(R-B))./sqrt((R-G).^2+(R-B).*(G-B))))*180/pi;
H=angle; %計算H(色調)通道
H(B>G)=360-H(B>G); %将 B>G 對應位置上的值指派為 2*pi - angle
S=1-3./(R+G+B+eps).*min(min(R,G),B); %計算S(色飽和度)通道
I=1/3*(R+G+B+eps); %計算I(亮度)通道
 
hsi=cat(3,H/360,S,I); %合成3個通道,為HSI圖像      

輸入原圖像并進行顯示,将原圖像從RGB彩色空間向HSI彩色空間轉換,顯示HSI彩色空間的圖像 useRGBtoHSI('EXP6.tif')

% pho 表示輸入圖像路徑(包括圖像名+字尾)
function [] = useRGBtoHSI(pho)
ima=imread(pho); %讀入輸入圖像
subplot(121); %設定輸入圖像的顯示位置(1行2列的第1個位置)
imshow(ima); %顯示輸入圖像
title('RGB彩色圖像'); %設定輸入圖像的标題
hsi=RGBtoHSI(pho); %将輸入圖像由RGB空間向HSI空間轉化
subplot(122); %設定輸出圖像的顯示位置(1行2列的第2個位置)
imshow(hsi); %顯示輸出圖像
title('HSI彩色圖像'); %設定輸出圖像的标題
%imwrite(hsi,'EXP6_HSI.tif','tif');      

輸出結果如下:

彩色圖像的空間域濾波

注意:

在編寫程式的過程中運作程式曾出現如下結果:

彩色圖像的空間域濾波

解決:

HSI彩色圖像輸出結果與正确結果的顔色不一樣。思考發現,H通道處并未做歸一化處理,即 H=H/360才是正确值。

(2)HSI彩色空間向RGB彩色空間的轉換:

自定義一個函數,實作HSI彩色空間向RGB彩色空間的轉換,要求該函數的輸入參數為HSI彩色圖像,輸出參數為RGB彩色圖像。

根據HSI彩色空間到RGB彩色空間的轉換公式,編寫函數 HSItoRGB(hsi)

% hsi 表示HSI空間圖像
function rgb = HSItoRGB(hsi)
%ima=imread(pho);
hsi=double(hsi); %轉化為雙精度類型
[r c m]=size(hsi); %計算hsi的行列和次元
H=hsi(:,:,1); %提取H分量
S=hsi(:,:,2); %提取S分量
I=hsi(:,:,3); %提取I分量
H=H*360; %将色調值變為原來的範圍[0°,360°]
R=zeros(r,c); %R分量
G=zeros(r,c); %G分量
B=zeros(r,c); %B分量
 
inv=0<=H & H<120; %RG扇區(inv是H中值在RG扇區的位置)
B(inv)=I(inv).*(1-S(inv)); %根據在RG扇區時的計算公式計算B分量
R(inv)=I(inv).*(1+S(inv).*cosd(H(inv))./cosd(60-H(inv))); %根據在RG扇區時的計算公式計算R分量
G(inv)=3*I(inv)-(R(inv)+B(inv)); %根據在RG扇區時的計算公式計算G分量
 
inv=120<=H & H<240; %GB扇區(inv是H中值在GB扇區的位置)
H(inv)=H(inv)-120;
R(inv)=I(inv).*(1-S(inv)); %根據在GB扇區時的計算公式計算R分量
G(inv)=I(inv).*(1+S(inv).*cosd(H(inv))./cosd(60-H(inv))); %根據在GB扇區時的計算公式計算G分量
B(inv)=3*I(inv)-(R(inv)+G(inv)); %根據在GB扇區時的計算公式計算B分量
 
inv=240<=H & H<360; %BR扇區(inv是H中值在BR扇區的位置)
H(inv)=H(inv)-240;
G(inv)=I(inv).*(1-S(inv)); %根據在BR扇區時的計算公式計算G分量
B(inv)=I(inv).*(1+S(inv).*cosd(H(inv))./cosd(60-H(inv))); %根據在BR扇區時的計算公式計算B分量
R(inv)=3*I(inv)-(G(inv)+B(inv)); %根據在BR扇區時的計算公式計算R分量
 
%将各個分量的灰階級拉伸到256個灰階級上
R=R*255;
G=G*255;
B=B*255;
rgb=cat(3,R,G,B); %合成彩色圖像
rgb=uint8(rgb); %轉為8位無符号整型      

輸入原圖像,将原圖像從RGB彩色空間向HSI彩色空間轉換,顯示HSI彩色空間的圖像,并将該圖像向RGB彩色空間轉化,得到結果進行顯示  useHSItoRGB('EXP6.tif')

% pho 表示輸入圖像路徑(包括圖像名+字尾)
function [] = useHSItoRGB(pho)
hsi=RGBtoHSI(pho); %将輸入圖像轉化為HSI空間彩色圖像
subplot(121); %設定HSI空間彩色圖像的顯示位置(1行2列的第1個位置)
imshow(hsi); %顯示HSI空間彩色圖像
title('HSI彩色圖像'); %設定HSI空間彩色圖像的标題
rgb=HSItoRGB(hsi); %由HSI空間轉化為RGB空間
subplot(122); %設定輸出圖像的顯示位置(1行2列的第2個位置)
imshow(rgb); %顯示輸出圖像
title('RGB彩色圖像'); %設定輸出圖像的标題      

輸出結果如下:

彩色圖像的空間域濾波

注意:

在編寫程式的過程中運作程式曾出現如下結果:

彩色圖像的空間域濾波

不僅如此,其中還出現一些“奇特”的圖檔,觀察原圖像轉為HSI彩色圖像後中H通道的數值,再看看作為實驗2小題輸入的HSI彩色圖像的H通道的數值,就可以發現這兩個通道的數值本應該一樣卻不一樣了。我能想到的原因應該是作為實驗2小題的輸入圖像——HSI彩色圖像是我由RGB轉HSI得到的(輸出儲存),其中儲存的過程中HSI彩色圖像H通道内的值轉化為了256灰階級來呈現(儲存)。是以第2小題的輸入圖像不能由第1小題的輸入結果儲存得到,而是直接使用第1小題的結果作為輸入參數。

解決方法:對原程式進行修改——輸入參數改為轉化後的HSI。

還出現過如下結果:

彩色圖像的空間域濾波

該結果是經上述問題後修改的程式運作的結果,再次檢視原程式,會發現H還未乘以360。

解決方法:對原程式進行修改——H分量乘以360。

接下來說的是:原圖像與由原圖像轉化HSI彩色圖像再轉為RGB彩色圖像的對比,檢視兩者內插補點,判斷RGB——>HSI和HSI——>RGB兩個函數的正确性。

errorAnaly('EXP6.tif')

% pho 表示輸入圖像路徑(包括圖像名+字尾)
% 該函數顯示輸入圖像和其HSI空間圖像、由HSI空間轉化來的RGB圖像、以及原圖像與由HSI空間轉化來的RGB圖像的內插補點圖像
% 觀察在轉化過程是否出現過大誤差
function []=errorAnaly(pho)
ima=imread(pho); %讀入輸入圖像
subplot(221); %設定輸入圖像的顯示位置(2行2列的第1個位置)
imshow(ima); %顯示輸入圖像
title('原圖像'); %設定輸入圖像的标題
 
hsi=RGBtoHSI(pho); %将輸入圖像轉化為HSI空間彩色圖像
subplot(222); %設定HSI空間彩色圖像的顯示位置(2行2列的第2個位置)
imshow(hsi); %顯示HSI空間彩色圖像
title('HSI彩色圖像'); %設定HSI空間彩色圖像的标題
 
rgb=HSItoRGB(hsi); %由HSI空間轉化為RGB空間
subplot(223); %設定輸出圖像的顯示位置(2行2列的第3個位置)
imshow(rgb); %顯示輸出圖像
title('RGB彩色圖像'); %設定輸出圖像的标題
 
erra=ima-rgb; %原圖像與由HSI空間轉化來的RGB圖像的內插補點圖像
subplot(224); %設定內插補點圖像的顯示位置(2行2列的第4個位置)
imshow(erra); %顯示內插補點圖像
title('原圖像與RGB彩色圖像的內插補點'); %設定內插補點圖像的标題      

輸出結果如下:

彩色圖像的空間域濾波

由內插補點圖像可見,原圖像與RGB彩色圖像的“一緻性”,說明兩個函數的正确性。

(3)要求在HSI彩色空間中,實作對含噪圖像EXP6.tif的空間域平滑處理,濾波器為5×5高斯均值濾波器(濾波器模闆如下圖所示),并在RGB彩色空間中顯示處理前後的結果。

輸入圖像在HSI彩色空間中的空間域平滑處理:

使用上次我們介紹到的自定義的空間濾波器,加入5x5高斯均值濾波器,對原函數進行修改補充,如下:

%filter_type 所選擇的濾波器類型。有:3x3高斯均值濾波器、5x5高斯均值濾波器、中值濾波器、最大值濾波器、最小值濾波器
%filter_size 定義濾波器大小,如 filter_size=[3 3];
function ima2 = mySpatialFilter(ima, filter_type, filter_size)
%ima=imread(pho); %根據路徑讀取原圖像
ima=double(ima); %轉化為雙精度類型
[r c]=size(ima); %讀取原圖像的行數和列數
 
%設定高斯均值濾波器隻有3x3或5x5大小的
if strcmp(filter_type, '3x3高斯均值濾波器')
    filter_size=[3 3];
end
 
if strcmp(filter_type, '5x5高斯均值濾波器')
    filter_size=[5 5];
end
m=filter_size(1); %讀取設定的濾波器模闆的大小
n=filter_size(2);
 
rs=r+m-1; %計算邊界填充後的圖像大小(填充模闆大小)
cs=c+n-1;
tIma=zeros(rs,cs); %建立一個邊界填充後的矩陣
tIma((m-1)/2+1:rs-(m-1)/2, (n-1)/2+1:cs-(n-1)/2)=ima; %矩陣中間填充原圖像灰階級
 
%以最鄰近的邊界作為邊界填充的灰階值
%先填充上邊界
for i=1:(m-1)/2
    tIma(i,(n-1)/2+1:cs-(n-1)/2)=ima(1);
end
%填充下邊界
for i=rs-(m-1)/2+1:rs
    tIma(i,(n-1)/2+1:cs-(n-1)/2)=ima(r);
end
%填充左邊界
for i=1:(n-1)/2
    tIma(:,i)=tIma(:,(n-1)/2+1);
end
%填充右邊界
for i=cs-(n-1)/2+1:cs
    tIma(:,i)=tIma(:,cs-(n-1)/2);
end
 
rIma=zeros(rs,cs);
%周遊該矩陣,套用濾波模闆
for i=1:rs-m+1
    for j=1:cs-n+1
        %讀取模闆覆寫處的圖像
        tempIma=tIma(i:i+m-1, j:j+n-1);
        %計算該模闆覆寫的中心位置
        centerR=i+(m-1)/2;
        centerC=j+(m-1)/2;
        switch filter_type
            case '3x3高斯均值濾波器'
                %定義3 x 3的高斯均值濾波器模闆
                module=[1 2 1; 2 4 2; 1 2 1];
                module=module(:)';
                %為鄰域以該模闆為系數進行權重求平均,得出的值指派得鄰域中心
                rIma(centerR,centerC)=module*tempIma(:)/sum(module);
            case '5x5高斯均值濾波器'
                %定義5 x 5的高斯均值濾波器模闆
                module=[1 2 3 2 1; 2 5 6 5 2; 3 6 8 6 3; 2 5 6 5 2; 1 2 3 2 1];
                module=module(:)';
                %為鄰域以該模闆為系數進行權重求平均,得出的值指派得鄰域中心
                rIma(centerR,centerC)=module*tempIma(:)/sum(module);
            case '中值濾波器'
                %為鄰域内的值排序,求得中值,将該值指派給鄰域中心
                tempIma=sort(tempIma(:));
                rIma(centerR,centerC)=tempIma((length(tempIma)+1)/2,1);
            case '最大值濾波器'
                %求鄰域中的最大灰階值,将該值指派給鄰域中心
                rIma(centerR,centerC)=max(tempIma(:));
            case '最小值濾波器'
                %求鄰域中的最小灰階值,将該值指派給鄰域中心
                rIma(centerR,centerC)=min(tempIma(:));
            otherwise
                error('不存在該濾波器');
        end
    end
end
%去除原先填充的邊界,得出最終結果
ima2=rIma((m-1)/2+1:rs-(m-1)/2, (n-1)/2+1:cs-(n-1)/2);
ima2=uint8(ima2);      

将原圖像轉為HSI空間圖像,在HSI空間中對I分量使用5x5高斯均值濾波器,再将HSI空間向RGB空間轉化,顯示結果:

useHSIGS('EXP6.tif')

% pho 表示輸入圖像路徑(包括圖像名+字尾)
% 該函數輸入原圖像,将原圖像轉化為HSI彩色圖像,在HSI空間使用5x5高斯均值濾波器,再将結果轉為RGB輸出
function []=useHSIGS(pho)
ima=imread(pho); %讀取輸入圖像
subplot(121); %設定輸入圖像的顯示位置(1行2列的第1個位置)
imshow(ima); %顯示輸入圖像
title('輸入圖像'); %設定輸入圖像的标題
 
hsi=RGBtoHSI(pho); %将輸入圖像由RGB空間向HSI空間轉化
%在使用5x5高斯均值濾波器前,需要将I分量拉伸到[0 255]灰階區間
%為什麼隻對I分量進行操作呢?I分量與圖像的彩色資訊無關。
%注意差異性:
%RGB空間中的平均是不同彩色的平均
%HIS空間中僅僅是強度的平均,色調H和飽和度S均保持不變
hsi(:,:,3)=mySpatialFilter(hsi(:,:,3)*255,'5x5高斯均值濾波器',[5 5]);
hsi(:,:,3)=hsi(:,:,3)/255; %将I分量再轉回[0 1]區間
rgb=HSItoRGB(hsi); %由HSI空間再轉為RGB空間
 
subplot(122); %顯示輸出圖像
imshow(rgb); %顯示輸出圖像
title('使用5x5高斯均值濾波器的輸出圖像'); %設定輸出圖像的标題      

輸出結果如下:

彩色圖像的空間域濾波

注意:

為什麼在HSI空間使用高斯均值濾波器時隻對I分量進行處理?

I分量與圖像的彩色資訊無關,H&S分量與人感受顔色的方式緊密相連。

注意差異性:

RGB空間中的銳化是不同彩色的平均;

繼續閱讀