上次我們開始進行數字圖像處理這門課程的實驗,直到現在才抽空出來寫寫文章,記錄一下知識點。介紹一下,使用Matlab對數字圖像的簡單處理。
1、 讀取與顯示輸入圖像:
%輸入圖像和顯示圖像
function []=readShow()
ima=imread('test.jpg'); %輸入圖像
imshow(ima); %顯示圖像
end
顯示輸出圖像 --> readShow()
輸出結果如下:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI0NXYFhGd192UvwVe0lmdhJ3ZvwFM38CXlZHbvN3cpR2Lc1TPB10QGtWUCpEMJ9CXsxWam9CXwADNvwVZ6l2c052bm9CXUJDT1wkNhVzLcRnbvZ2LcZXUYpVd1kmYr50MZV3YyI2cKJDT29GRjBjUIF2LcRHelR3LcJzLctmch1mclRXY39DN0UTMxgTNzEDOxATM1EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
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)
輸入和輸入出結果如下:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI0NXYFhGd192UvwVe0lmdhJ3ZvwFM38CXlZHbvN3cpR2Lc1TPB10QGtWUCpEMJ9CXsxWam9CXwADNvwVZ6l2c052bm9CXUJDT1wkNhVzLcRnbvZ2LcZXUYpVd1kmYr50MZV3YyI2cKJDT29GRjBjUIF2LcRHelR3LcJzLctmch1mclRXY39DN0UTMxgTNzEDOxATM1EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
縮小到原圖像的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)雖說自己按照了算法編寫出了程式,但是以自己的水準來說,想當堂完成達到盡善盡美的程度仍稍顯不足。此外,即便是課堂上聽懂了老師講解的知識,算法轉化為代碼也不是說可以立馬進行轉換。再者加上有時并沒透徹了解知識點,課後又将時間花上了自學其他知識上,使得實驗過程中有點稍顯吃力,盡管相信自己去花時間研究一定能透徹了解。