使用Matlab進行影象的讀寫、顯示和縮放(最近臨插值和雙線性內插值法)
上次我們開始進行數字影象處理這門課程的實驗,直到現在才抽空出來寫寫文章,記錄一下知識點。介紹一下,使用Matlab對數字影象的簡單處理。
1、 讀取與顯示輸入影象:
%輸入影象和顯示影象
function []=readShow()
ima=imread('test.jpg'); %輸入影象
imshow(ima); %顯示影象
end
顯示輸出影象 --> readShow()
輸出結果如下:
2、點運算:
1) 影象的縮放程式碼,並顯示縮放處理前後的影象
這裡將講解兩種縮放影象的方法:
①最近臨插值
把最近鄰畫素的灰度值賦給每個新位置,程式碼如下:
%Author: DreamBoy %採用最近鄰插值對影象進行縮放處理 %引數n表示縮放倍數 function []=scale1(n) ima=imread('test.jpg'); imshow(ima); title('輸入影象'); ima=double(ima); swh=size(ima); %得到原影象的寬高 sw=swh(:,2); %得到原影象的寬 sh=swh(:,1); %得到原影象的高 dw=ceil(sw * n); %得到 dh=ceil(sh * n); resIma=zeros(dh,dw); for i=1:dh for j=1:dw tx=round(i/n); %縮放後的影象座標在原影象處的位置 ty=round(j/n); if(tx < 1) %如果越界,則進行調整 tx = 1; end if(tx > sh) tx = swh; end if(ty < 1) ty = 1; end if(ty > sw) ty = sw; end resIma(i,j)=ima(tx,ty); %將縮放後的影象座標在原影象處的位置的灰度值賦值給縮放後的影象 end end resIma=uint8(resIma); figure; imshow(resIma); title('輸出影象'); end
放大到原影象的兩倍 --> scale1(2^.5)
輸入和輸入出結果如下:
縮小到原影象的1/4倍 --> scale1(1/2)
輸出結果如下:
②雙線性插值
我們先按要求縮放原影象,得出縮放後的座標,再有縮放後的座標(x,y)求出該座標在原影象上的位置,即(x/n,y/n),即為上圖所示的D點(+u,+v)。其中(u,v)表示小數部分的座標。
設原影象中有4個點,分別為 (,), (,), (,), (,),其中這四點為相鄰點,即
。而圖中D點(+u,+v)為縮放影象所要插入的點。
根據雙線性插值的演算法,先在x方向上進行線性插值,即有
再在y方向上進行線性插值,即有
綜上,有:
根據上述公式,使用Matlab編寫程式,程式碼如下:
%採用雙線性內插值對影象進行縮放處理 %引數n表示縮放的倍數 function []=scale2(n) ima=imread('test.jpg'); %讀取原影象 ima=double(ima); %二維矩陣轉為雙精度型別 swh=size(ima); %獲取原影象的寬高 sh=swh(:,1); %獲取原影象的高 sw=swh(:,2); %獲取原影象的寬 %"加牆" ima2=zeros(sh+2,sw+2); ima2(1,2:sw+1)=ima(1,:); %原影象上邊加牆,灰度值與邊界一致 ima2(sh+2,2:sw+1)=ima(sh,:); %原影象下邊加牆,灰度值與邊界一致 ima2(2:sh+1,2:sw+1)=ima; %將原影象賦值給中心部分 ima2(:,1)=ima2(:,2); %原影象左邊加牆,灰度值與邊界一致 ima2(:,sw+2)=ima2(:,sw+1); %原影象右邊加牆,灰度值與邊界一致 dw=sw*n; %計算縮放後的影象的寬 dh=sh*n; %計算縮放後的影象的高 dw1=round((sw+2)*n); %計算加牆後縮放的影象的寬 dh1=round((sh+2)*n); %計算加牆後縮放的影象的高 resIma1=zeros(dh1,dw1); %建立原影象的矩陣 %從不是“牆”的位置開始計算縮放後的影象的各點灰度值 %考慮縮小影象時,輸入的縮放倍數是小數,需進行取整 start=round(n+1); endI=round(dh+n); endJ=round(dw+n); for i=start:endI for j=start:endJ tx=i/n; %縮放後的影象座標在原影象處的位置 ty=j/n; tdx=tx-floor(tx); %得到小數座標 tdy=ty-floor(ty); %確定臨近四個角的座標 %Q11點 Q11x=tx-tdx; Q11y=ty-tdy; %Q12點 Q12x=tx-tdx; Q12y=Q11y+1; %Q21點 Q21x=Q11x+1; Q21y=Q11y; %Q22點 Q22x=Q11x+1; Q22y=Q11y+1; %根據雙線性內插演算法,算出縮放後的影象在(i,j)點處的灰度值 resIma1(i,j)=tdx*tdy*ima2(Q11x,Q11y)+(1-tdx)*tdy*ima2(Q12x,Q12y)+tdx*(1-tdy)*ima2(Q21x,Q21y)+(1-tdy)*(1-tdx)*ima2(Q22x,Q22y); end end resIma=resIma1(n+1:dh+n,n+1:dw+n); %擷取除牆外的中心部分 resIma=uint8(resIma); imshow(resIma); %顯示縮放後的影象 end
縮小到原影象的1/4倍 --> scale2(1/2)
輸出結果如下:
放大到原影象的兩倍 --> scale2(2^.5)
輸出結果如下:
2) 剪下輸入影象左上角的四分之一,並顯示剪下前後的影象
程式碼如下:
%引數n表示剪下原影象的n
function []=cutIma(n)
ima=imread('test.jpg');
ima=double(ima);
swh=size(ima);
sh=swh(:,1);
sw=swh(:,2);
dh=round(sh*n);
dw=round(sw*n);
resIma=ima(1:dh,1:dw);
resIma=uint8(resIma);
imshow(resIma);
3、 對點運算結構影象的寫入(如儲存在桌面、副檔名為“.jpg”)
程式碼如下:
%Author: DreamBoy
%輸入影象和顯示影象
function []=write()
ima=imread('test.jpg'); %輸入影象
imshow(ima); %顯示影象
imwrite(ima,'output.jpg'); %儲存影象到當前目錄下,並命名為output
end
總結:(1)鍛鍊自學能力,自己研究了兩種縮放影象的方法:最近臨插值和雙線性插值。
(2)全程程式程式碼自行編寫,鍛鍊Matlab的程式設計能力,提高對使用Matlab進行影象處理的能力。
(3)雖說自己按照了演算法編寫出了程式,但是以自己的水平來說,想當堂完成達到盡善盡美的程度仍稍顯不足。此外,即便是課堂上聽懂了老師講解的知識,演算法轉化為程式碼也不是說可以立馬進行轉換。再者加上有時並沒透徹理解知識點,課後又將時間花上了自學其他知識上,使得實驗過程中有點稍顯吃力,儘管相信自己去花時間研究一定能透徹理解。