第一篇:基于MATLAB圖像處理報告
基于MATLAB圖像處理報告
一、設計題目
圖片疊加。
二、設計要求
將一幅禮花圖片和一幅夜景圖片做疊加運算,使達到煙花夜景的美圖效果。
三、設計方案
3.1、設計思路
利用matlab強大的圖像處理功能,通過編寫程序,實現對兩幅圖片的像素進行線性運算,利用灰度變換的算法使圖片達到預期的效果。
3.2、軟件介紹
MATLAB是matrix&laboratory兩個詞的組合,意為矩陣工廠(矩陣實驗室)。是由美國mathworks公司發布的主要面對科學計算、可視化以及交互式程序設計的高科技計算環境。它將數值分析、矩陣計算、科學數據可視化以及非線性動態系統的建模和仿真等諸多強大功能集成在一個易于使用的視窗環境中,為科學研究、工程設計以及必須進行有效數值計算的眾多科學領域提供了一種全面的解決方案,并在很大程度上擺脫了傳統非交互式程序設計語言(如C、Fortran)的編輯模式,代表了當今國際科學計算軟件的先進水平。
MATLAB和Mathematica、Maple并稱為三大數學軟件。它在數學類科技應用軟件中在數值計算方面首屈一指。MATLAB可以進行矩陣運算、繪制函數和數據、實現算法、創建用戶界面、連接其他編程語言的程序等,主要應用于工程計算、控制設計、信號處理與通訊、圖像處理、信號檢測、金融建模設計與分析等領域。MATLAB的基本數據單位是矩陣,它的指令表達式與數學、工程中常用的形式十分相似,故用MATLAB來解算問題要比用C,FORTRAN等語言完成相同的事情簡捷得多,并且MATLAB也吸收了像Maple等軟件的優點,使MATLAB成為一個強大的數學軟件。在新的版本中也加入了對C,FORTRAN,C++,JAVA的支持。可以直接調用,用戶也可以將自己編寫的實用程序導入到MATLAB函數庫中方便自己以后調用,此外許多的MATLAB愛好者都編寫了一些經典的程序,用戶直接進行下載就可以用。
3.3、常見簡單程序語句及算法分析
(1)CLC;清零。(2)CLEAR ; 清內存。
(3)r=imread(‘路徑圖片名.jpg’);讀入一幅圖片。(4)imshow(r);顯示圖片r。(5)g=rgb2gray(r);灰度轉變。
(6)%imhist(g);g1=histeq(g);figure,imsho(g1);直方圖均衡化。(7)Imwrite(‘g1,路徑圖片名.jpg’);保存圖片。
3.4、圖片疊加及灰度變換分析
程序1 [m,n,l]=size(C);for i=1:m for j=1:n for k=1:l D(i,j,k)=C(i,j,k)+ B(i,j,k);end end end 此程序的主要功能是對兩幅圖片通過算法來實現疊加的效果,程序中的幾個變量都是像素點的值,通過三個循環使得兩幅圖片對應的值線性相加,最大值應該是以255輸出,超過255也是以255輸出。
程序2 J = imadjust(I,[low_in high_in], [low_out high_out])此程序變換的原理是:如果原圖像f(x, y)的灰度范圍是[m, M],我們希望對圖像的灰度范圍進行線性調整,調整后的圖像g(x, y)的灰度范圍是[n, N],那么下述變換:g(x,y)
N
n
f(x,y)
m
n就可以實現這一要求。MATLAB圖像處理工具箱中提供的imadjust函數,可以實現上述的線性變換對比度調整。
四、設計步驟(1)處理之前,我們先來看看兩幅原圖,一幅是帶有禮花的圖片,另一幅是一幅東方明珠的夜景圖。
圖 1
圖 2 通過圖片我們發現,禮花的圖片非常的亮,而夜景圖則顯得有些灰暗。我們推測,如果讓禮花和夜景的圖片疊加到一起,會不會由于禮花的亮度太大而掩蓋了城市的夜光,達不到我們想要的效果。
(2)打開matlab圖像處理軟件,7.0及以上版本就可以,打開之后,顯示界面如下(我的版本是2012b)。
圖3(3)新建script文件,點擊’New script‘,或點擊’New‘,選擇script。
圖4(4)在打開的界面之中輸入程序。圖片的位置是你所要用的圖片的準確位置,盡量寫詳細點,減少計算機的讀取時間,加快讀取速度。如圖所示。
圖5(5)點擊運行按鈕,即界面上的綠色按鈕。
圖6(6)查看效果,如下圖。
圖7 通過處理后的圖片,我們看到由于禮花太亮,完全將城市的夜景掩蓋住了,效果不是太理想。我們設想加入灰度變換函數,將禮花的圖片變的暗一點,將夜景的亮度提高一點,看看效果怎么樣,加入灰度變換程序,如下圖。
圖8(7)軟件調試后運行程序,如下圖。
圖9 結果顯示加入灰度變換的函數之后,圖片效果較之前好多了,達到了預期的目的。
五、軟件代碼
通過matlab進行圖像處理,代碼如下: clear;clc;A=imread('C:UsersAdministratorDesktop作業禮花.jpg');C=imresize(A,[300,400]);B=imread('C:UsersAdministratorDesktop作業夜景提亮天空中加入禮花.jpg');[m,n,l]=size(C);for i=1:m for j=1:n for k=1:l D(i,j,k)=C(i,j,k)+ B(i,j,k);end end end figure imshow(D);imwrite('C:UsersAdministratorDesktop作業禮花效果圖1.jpg')調試之后的程序代碼如下: clear;clc;A=imread('C:UsersAdministratorDesktop作業禮花.jpg');B=imread('C:UsersAdministratorDesktop作業夜景提亮天空中加入禮花.jpg');A1=imadjust(A,[0,1],[0,0.9]);B1=imadjust(B,[0.3,0.6],[0,1]);C=imresize(A1,[300,400]);[m,n,l]=size(C);for i=1:m for j=1:n for k=1:l D(i,j,k)=C(i,j,k)+ B1(i,j,k);end end end figure imshow(D);imwrite('C:UsersAdministratorDesktop作業禮花效果圖2.jpg')處理后的圖片如下:
圖 10
六、結果分析
通過兩幅圖的對比,發現第二幅圖片較第一幅,效果明顯增強。是由于加入灰度變換函數,使原圖的灰度值發生變化,以達到實際的效果。
效果對比圖11
七、心得體會
通過這次任務,以前在課堂上沒太聽明白怎么回事的東西,通過上網,查資料,以及用軟件處理,通通實踐了一遍,加深了對這門課程的認識和理解。Matlab是一款功能很強大的應用軟件,它不僅可以對圖像進行處理,而且可以進行各種數字計算和符號計算功能,具有繪圖功能,語言體系等等。這次的任務我們樂在其中,喜悅的是看到了成果,內心充滿了滿足感和成就感,就如同看到了圖片中的煙花,有種過年的感覺。不過這些都只是皮毛而已,要想真正地掌握它,還得更進一步地學習理論知識。
參考文獻:
【岡薩雷斯 數字圖像處理(MATLAB版)】[美] RafaelC.Gonzalez RichardE.Woods StevenL.Eddins 著 電子工業出版社。
【數字圖像處理及MATLAB實現】楊杰 主編 電子工業出版社。
第二篇:matlab圖像處理小結
1.function [center, r] = solve_circle(pt1, pt2, pt3)
2.%Effect: solve the circle which across points 'pt1', 'pt2' and 'pt3' 3.%Inputs:
4.%pt1, pt2, pt3: [x, y]
5.%center: the circle center [x0;y0] 6.%r: the radius of the circle 7.%Author: Su dongcai at 2012/1/2 8.A = zeros(2, 2);B = zeros(2, 1);9.[A(1, :), B(1)] = circle2line(pt1, pt2);10.[A(2, :), B(2)] = circle2line(pt2, pt3);11.center = AB;
12.r = norm(pt1'(y2^2 + y2^2)18.%(a-x2)^2 +(b-y2)^2 = r^2 | 19.%Inputs:
20.%pt1, pt2: [x1, y1], [x2, y2] 21.%Outputs:
22.%A: 2[x1-x2, y1-y2]
23.%B:(x1^2 + y1^2)pt2);
26.B = norm(pt1)^2-norm(pt2)^2;
close all;clear;clc;>> i=imread('rice.png');%>> imshow(i);>> background=imopen(i,strel('disk',15));>> i2=imsubtract(i,background);%>> figure,imshow(i2);>> i3=imadjust(i2,stretchlim(i2),[0 1]);%>> figure,imshow(i3);>> level=graythresh(i3);>> bw=im2bw(i3,level);%>> figure,imshow(bw);>> [labeled,numobjects]=bwlabel(bw,4);graindata=regionprops(labeled,'all');
close all;clear;clc;i=imread('rice.png');background=imopen(i,strel('disk',15));i2=imsubtract(i,background);i3=imadjust(i2,stretchlim(i2),[0 1]);level=graythresh(i3);bw=im2bw(i3,level);[labeled,numobjects]=bwlabel(bw,4);data=regionprops(labeled,'all');
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %2006.6.2 close all;clear;clc;>> i=imread('r.jpg');%>> figure,imshow(i);>> imgray=rgb2gray(i);>> figure,imshow(imgray)>> background=imopen(imgray,strel('disk',15));>> i2=imsubtract(imgray,background);%>> figure,imshow(i2);>> i3=imadjust(i2,stretchlim(i2),[0 1]);%>> figure,imshow(i3);>> level=graythresh(i3);>> bw=im2bw(i3,level);%>> figure,imshow(bw);>> imnobord=imclearborder(bw,4);%>> figure,imshow(imnobord);>> [labeled,numobjects]=bwlabel(bw,4);>> rgb_label=label2rgb(labeled,@spring,'c','shuffle');>> figure,imshow(rgb_label);>> graindata=regionprops(labeled,'all');hold on;for k=1:numobjects lab=sprintf('%d',k);text(graindata(k).Centroid(1),graindata(k).Centroid(2),lab,'Color','k');end hold off;%剔除碎米粒
>> idxdown=find([graindata.Area]<150);%剔除碎米粒 little=ismember(labeled,idxdown);figure,imshow(little);
[lab_little,num_little]=bwlabel(little,4);rgb_little=label2rgb(lab_little,@spring,'c','shuffle');figure,imshow(rgb_little);
little_data=regionprops(lab_little,'all');hold on;for k=1:num_little lab=sprintf('%d',k);text(little_data(k).Centroid(1),little_data(k).Centroid(2),lab,'Color','k');end hold off;%>> graindata(idxdown,:)=[];%剔除碎米粒 %剔除連接米粒
>> idxup=find([graindata.Area]>250);%剔除連接米粒 big=ismember(labeled,idxup);figure,imshow(big);
[lab_big,num_big]=bwlabel(big,4);rgb_big=label2rgb(lab_big,@spring,'c','shuffle');figure,imshow(rgb_big);
big_data=regionprops(lab_big,'all');hold on;for k=1:num_big lab=sprintf('%d',k);text(big_data(k).Centroid(1),big_data(k).Centroid(2),lab,'Color','k');end hold off;%>> graindata(numup,:)=[];%剔除連接米粒 %獲取完整米粒
idxsuit=find([graindata.Area]>=150&[graindata.Area]<=250);suit=ismember(labeled,idxsuit);figure,imshow(suit);%獲取完整米粒 [lab_suit,num_suit]=bwlabel(suit,4);suit_data=regionprops(lab_suit,'all');hold on;for k=1:num_suit signature=sprintf('%d',k);text(suit_data(k).Centroid(1),suit_data(k).Centroid(2),signature,'Color','r');end hold off;%獲取完整米粒 whos graindata whos little_data whos big_data whos suit_data
>> graindata >> mean([graindata.Area])>> mean([graindata.Eccentricity])>> mean([graindata.MajorAxisLength])>> mean([graindata.MinorAxisLength])>> mean([graindata.EquivDiameter])>> figure,hist([graindata.Area],20);>> figure,hist([graindata.Eccentricity],20);>> figure,hist([graindata.MajorAxisLength],20);>> figure,hist([graindata.MinorAxisLength],20);>> figure,hist([graindata.EquivDiameter],20);
data=[graindata.Area] data=[graindata.Centroid] data=[graindata.BoundingBox] data=[graindata.SubarrayIdx] data=[graindata.MajorAxisLength] data=[graindata.MinorAxisLength] data=[graindata.Eccentricity] data=[graindata.Orientation] data=[graindata.ConvexHull] data=[graindata.ConvexImage] data=[graindata.ConvexArea] data=[graindata.Image] data=[graindata.FilledImage] data=[graindata.FilledArea] data=[graindata.EulerNumber] data=[graindata.Extrema] data=[graindata.EquivDiameter] data=[graindata.Solidity] data=[graindata.Extent] data=[graindata.PixelIdxList] data=[graindata.PixelList]
Area 計算各個連通區域中的象素總數 BoundingBox 包含相應區域的最小矩形 Centroid 給出每個區域的質心
MajorAxisLength 與區域具有相同標準二階中心矩(又叫標準差)的橢圓的長軸長度 MinorAxisLength 與區域具有相同標準二階中心矩的橢圓的短軸長度 Eccentricity 與區域具有相同標準二階中心矩的橢圓的離心率
Orientation 與區域具有相同標準二階中心矩的橢圓的長軸與x軸的交角 Image 二值圖像,與某區域具有相同大小的邏輯矩陣。
FilledImage 與上相同,唯一區別是這是個做了填充的邏輯矩陣!本例中和上面的沒有區別,只有 區域有空洞時才有明顯差別。
FilledArea 是標量,填充區域圖像中的 on 像素個數
ConvexHull 是p行2列的矩陣,包含某區域的最小凸多邊形 ConvexImage 二值圖像,用來畫出上述的區域最小凸多邊形 ConvexArea 是標量,填充區域凸多邊形圖像中的 on 像素個數 EulerNumber 等于圖像中目標個數減去這些目標中空洞的個數 Extrema 8行2列矩陣,八方向區域極值點
EquivDiameter 是標量,等價直徑:與區域具有相同面積的圓的直徑.計算公式為:sqrt(4*Area/pi)
Solidity 是標量,同時在區域和其最小凸多邊形中的像素比例。計算公式為: Area/ConvexArea,這也是個仿射特征,實際上反映出區域的固靠性程度。
Extent 是標量,同時在區域和其最小邊界矩形中的像素比例。計算公式為:Area除以邊界矩 形面積,這也是個仿射特征,實際上反映出區域的擴展范圍程度。
PixelIdxList p元向量,存儲區域像素的索引下標
PixelList p行ndims(L)列矩陣,存儲上述索引對應的像素坐標 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 基于特定原則的區域選擇
當你要基于特定準則條件選擇某個區域時,將函數 ismember 和 regionprops 聯合使用是很有用處的。例如:創建一個只包含面積大于80的二值圖像,用以下命令
idx = find([stats.Area] > 80);BW2 = ismember(L,idx);regionprops函數的擴展思路
在regionprops函數的基礎上,你可以使用它提供的基本數據來擴展它的功能,比如我就將區域的曲率數據和骨架數據作為它的另外屬性值來開發,從而希望它能用來做更細致的特征提取。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %2006.6.2 P221圖像粒度測定(雪花)>> i=imread('snowflakes.png');>> figure,imshow(i);>> %(2)>> clahei=adapthisteq(i,'numtiles',[10 10]);>> clahei=imadjust(clahei);>> imshow(clahei);>> gi=imadjust(im2double(i),[],[0 1]);>> figure,imshow(gi),title('adjusted grayscale image');>> %(3)>> se=strel('disk',10);>> topi=imtophat(gi,se);>> figure,imshow(topi),title('top-hat image');>> %(4)>> for counter=0:22 remain=imopen(clahei,strel('disk',counter));intensity_area(counter+1)=sum(remain(:));end >> figure,plot(intensity_area,'m-*'),grid on;>> title('sum of opening(pixels)');>> title('sum of opening values in opened image as a function of radius');>> xlabel('radius of opening(pixels)');>> ylabel('pixel value sum of opened objects(intensity)');>> >> >> >> for counter=0:20 remain=imopen(topi,strel('disk',counter));surfarea(counter+1)=sum(remain(:));end >> figure,plot(surfarea,'m-*'),grid on;>> set(gca,'xtick',[0 2 4 6 8 10 12 14 16 18 20]);>> title('surface area of opened objects as a function of radius');>> xlabel('radius of opening(pixels)');>> ylabel('surface area of opened objects(pixels)');>> %(5)>> intensity_area_prime=diff(intensity_area);>> figure,plot(intensity_area_prime,'m-*'),grid on;>> title('Granulometry(size distrubution)of snowflakes');>> set(gca,'xtick',[0 2 4 6 8 10 12 14 16 18 20 22]);>> xlabel('radius of snowflakes(pixels)');>> ylabel('sum of pixel values in snowflakes as a function of radius');>> derivsurfarea=diff(surfarea);>> figure,plot(derivsurfarea,'m-*'),grid on;>> title('granulometry(size distribution)of stars');>> xlabel('radius of stars(pixels)');>> ylabel('loss of pixels between two successive openings');
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %2006.6.2 花椒檢測 clc;clear;close all;i=imread('gj.jpg');imshow(i);icanny=edge(i,'canny');imshow(icanny);se90=strel('line',2,90);se0=strel('line',2,0);bwsdil=imdilate(icanny,[se90 se0]);figure,imshow(bwsdil),title('dilated');ifill=imfill(bwsdil,'holes');figure,imshow(ifill);
%bwero=imerode(bwsdil,[se90 se0]);%figure,imshow(bwero);%i2fill=imfill(bwero,'holes');%figure,imshow(bwero);%imshow(i2fill);
%bwnobord=imclearborder(bwsdil,4);%figure,imshow(bwnobord);bwnobord=imclearborder(ifill,4);figure,imshow(bwnobord);se=strel('disk',5);bwc=imclose(bwnobord,se);bwco=imopen(bwnobord,se);figure,imshow(bwc);figure,imshow(bwco);%mask=bwsdil&bwco;%figure,imshow(mask);clc [labeled,numobjects]=bwlabel(bwco);numobjects
jdata=regionprops(labeled,'all');%jdata
jarea=[jdata.Area];mean(jarea)max(jarea)min(jarea)hist(jarea,255)jdata.Eccentricity %std([jdata.Eccentricity])/(Mean([jdata.Eccentricity])jstd=std([jdata.Eccentricity])jmean=Mean([jdata.Eccentricity])jcv=jstd/jmean
>> std([jdata.Area])/ mean([jdata.Area])%面積的變異系數
>> std([jdata.Eccentricity])/ mean([jdata.Eccentricity])%橢圓的變異系數 >> std([jdata.MajorAxisLength])/ mean([jdata.MajorAxisLength])>> std([jdata.MinorAxisLength])/ mean([jdata.MinorAxisLength])>> std([jdata.EquivDiameter])/ mean([jdata.EquivDiameter])
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %2006.06.06 rice.png close all;clear;clc >> i=imread('rice.png');imshow(i);background=imopen(i,strel('disk',15));figure,imshow(background);i2=imsubtract(i,background);figure,imshow(i2);i3=imadjust(i2,stretchlim(i2),[0 1]);figure,imshow(i3);level=graythresh(i3);bw=im2bw(i3,level);figure,imshow(bw);imnobord=imclearborder(bw);[label,numobjects]=bwlabel(imnobord,4);numobjects rgb_label=label2rgb(label,@spring,'c','shuffle');figure,imshow(rgb_label);graindata=regionprops(label,'all');graindata
>> numdown=find([graindata.Area]<150);>> graindata(numdown,:)=[];>> numup=find([graindata.Area]>250);>> graindata(numup,:)=[];>> graindata
>> std([graindata.Area])/ mean([graindata.Area])%面積的變異系數
>> std([graindata.Eccentricity])/ mean([graindata.Eccentricity])%橢圓的變異系數
>> std([graindata.MajorAxisLength])/ mean([graindata.MajorAxisLength])>> std([graindata.MinorAxisLength])/ mean([graindata.MinorAxisLength])>> std([graindata.EquivDiameter])/ mean([graindata.EquivDiameter])%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %2006.06.06 rice的堊白度檢測 >> clear;close all;clc;>> rgb=imread('r.jpg');>> close all;>> imshow(rgb);>> i=rgb2gray(rgb);>> j=medfilt2(i,[5 5]);>> figure,imshow(i);>> figure,imshow(j);>> imhist(j,256);>> t=0.3;>> v=imadjust(j,[t 1],[],1);>> imhist(v,256);>> t_c=0.6;>> bw_v=im2bw(v,0.01);>> chalk=imadjust(v,[t_c 1],[],1);>> bw_chalk=im2bw(chalk,0.01);>> figure,imshow(v);>> figure,imshow(bw_v);>> figure,imshow(chalk);>> figure,imshow(bw_chalk);>> degree_chalkness=bwarea(bw_chalk)/bwarea(bw_v)*100 >> bw=im2bw(j,t);>> figure,imshow(bw);>> se=(ones(3,3));>> bw1=imerode(bw,se);%兩次腐蝕 >> figure,imshow(bw1);>> bw2=imerode(bw1,se);>> figure,imshow(bw2);
>> [l,num]=bwlabel(bw2);%標記腐蝕后的大米圖像 >> t_chalk=100;%設置堊白面積的下限 >> compare=(l)&(chalk>t_chalk);%>> compare=(bw2)&(bw_chalk>t_chalk);>> [r,c]=find(compare);%標記堊白米粒的位置 >> result=bwselect(l,c,r);%顯示只含有堊白米粒的圖像 >> figure,imshow(result);
>> [l_chalk,num_chalk]=bwlabel(result);%標記堊白米粒圖像,便于計數 >> rate_chalky_grains=num_chalk/num*100;>> rate_chalky_grains
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %2006.6.17 bwmorph函數 >> help bwmorph BWMORPH Perform morphological operations on binary image.BW2 = BWMORPH(BW1,OPERATION)applies a specific morphological operation to the binary image BW1.BW2 = BWMORPH(BW1,OPERATION,N)applies the operation N times.N can be Inf, in which case the operation is repeated until the image no longer changes.OPERATION is a string that can have one of these values: 'bothat' Subtract the input image from its closing 'bridge' Bridge previously unconnected pixels 'clean' Remove isolated pixels(1's surrounded by 0's)'close' Perform binary closure(dilation followed by erosion)'diag' Diagonal fill to eliminate 8-connectivity of background 'dilate' Perform dilation using the structuring element ones(3)'erode' Perform erosion using the structuring element ones(3)'fill' Fill isolated interior pixels(0's surrounded by 1's)'hbreak' Remove H-connected pixels 'majority' Set a pixel to 1 if five or more pixels in its 3-by-3 neighborhood are 1's 'open' Perform binary opening(erosion followed by dilation)'remove' Set a pixel to 0 if its 4-connected neighbors are all 1's, thus leaving only boundary pixels 'shrink' With N = Inf, shrink objects to points;shrink objects with holes to connected rings 'skel' With N = Inf, remove pixels on the boundaries of objects without allowing objects to break apart 'spur' Remove end points of lines without removing small objects completely.'thicken' With N = Inf, thicken objects by adding pixels to the exterior of objects without connected previously unconnected objects 'thin' With N = Inf, remove pixels so that an object without holes shrinks to a minimally connected stroke, and an object with holes shrinks to a ring halfway between the hold and outer boundary 'tophat' Subtract the opening from the input image
Class Support-------------The input image BW1 can be numeric or logical.It must be 2-D, real and nonsparse.The output image BW2 is logical.Examples--------BW1 = imread('circles.png');imview(BW1)BW2 = bwmorph(BW1,'remove');BW3 = bwmorph(BW1,'skel',Inf);imview(BW2)imview(BW3)
See also erode, dilate, bweuler, bwperim.Reference page in Help browser doc bwmorph
BW1 = imread('circles.png');figure,imshow(BW1)BW2 = bwmorph(BW1,'erode');figure,imshow(BW2)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %邊界提取 b=bwmorph(bw,'remove');b=bwperim(bw,8);%又叫邊界象素測定 b=edge(bw,'canny');%又叫邊界提取 %去除孤立象素點
nosinglepixel=bwmorph(bw,'clean');%去除小面積物體
nosmall=bwareaopen(bw,CNN);%閾值處理再取反
bw=~im2bw(i,graythresh(i));
%開運算(消除小物體)與閉運算(填充物體內細小空洞)se=strel('disk',6);iopen=imopen(bw,se);iclose=imclose(bw,se);%腐蝕與膨脹聯合操作 %(1)創建結構元素 se=strel('rectangle',[40 30]);%(2)使用結構元素腐蝕圖像 bw1=imread('circbw.tif');bw2=imerode(bw1,se);imshow(bw2);%(3)逆操作,回復矩形原來大小 bw3=imdilate(bw2,se);figure,imshow(bw3);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %2006.6.18花椒子
%直接對灰度圖進行canny運算 >> i=imread('nut.bmp');>> figure,imshow(i);>> ig=rgb2gray(i);>> figure,imshow(ig);%igcanny=edge(ig,'canny');%igcfill=imfill(igcanny,'hole');igcanny_thresh=edge(ig,'canny',(graythresh(ig)*.1));igcfill=imfill(igcanny_thresh,'hole');>> figure,imshow(igcfill);
%先對灰度圖濾波,再進行canny運算
>> imed=medfilt2(ig);%中值濾波后對圖像邊界有一定的損傷!!>> imedcanny=edge(imed,'canny');>> imedfill=imfill(imedcanny,'hole');>> figure,imshow(imedfill);>> nosmall=bwareaopen(imedfill,150);>> figure,imshow(nosmall);
%注意:若對灰度圖像先拉氏銳化,在canny提取邊界,效果不大好!!%結論:無需拉氏銳化,也不必中值濾波,可直接canny提取邊界!!>> ifill=igcfill|imedfill;>> figure,imshow(ifill);>> nosmall=bwareaopen(ifill,150);>> figure,imshow(nosmall);
%當t=0.55時,閾值處理再canny運算的效果 >> imhist(ig);>> t=0.55;>> v=imadjust(ig,[0 t],[],1);>> vcanny=edge(v,'canny');>> vfill=imfill(vcanny,'hole');>> figure,imshow(vfill);>> ifill=igcfill|vfill;>> figure,imshow(ifill);>> nosmall=bwareaopen(ifill,150);>> figure,imshow(nosmall);
%當t=0.6時,閾值處理再canny運算的效果的效果 >> t=0.6;>> v=imadjust(ig,[0 t],[],1);>> vcanny=edge(v,'canny');>> vfill=imfill(vcanny,'hole');>> figure,imshow(vfill);>> ifill=igcfill|vfill;>> figure,imshow(ifill);>> nosmall=bwareaopen(ifill,150);>> figure,imshow(nosmall);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %處理花椒子
>> i=imread('nut.bmp');%figure,imshow(i);ig=rgb2gray(i);figure,imshow(ig);>> imed=medfilt2(ig);imedcanny=edge(imed,'canny');imedfill=imfill(imedcanny,'hole');%figure,imshow(imedfill);nosmall=bwareaopen(imedfill,150);>> figure,imshow(nosmall);>> [labeled,numobjects]=bwlabel(nosmall,4);>> rgb_label=label2rgb(labeled,@spring,'c','shuffle');%>> figure,imshow(rgb_label);>> nutdata=regionprops(labeled,'all');>> min([nutdata.Solidity])
>> rectangle('Position', [253.5000 207.5000 26.0000 28.0000])%畫矩形
>> rectangle('Position', [250.5000 50.5000 27.0000 26.0000])>> figure,imshow(nutdata(1).Image)%只顯示1號物體的圖像
>> figure,imshow(nutdata(1).ConvexImage)%畫出1號物體的凸多邊形 >> std([nutdata.Eccentricity])/ mean([nutdata.Eccentricity])std([nutdata.Area])/ mean([nutdata.Area])std([nutdata.Solidity])/ mean([nutdata.Solidity])>> std([nutdata.Centroid])/ mean([nutdata.Centroid])std([nutdata.MajorAxisLength])/ mean([nutdata.MajorAxisLength])std([nutdata.MinorAxisLength])/ mean([nutdata.MinorAxisLength])std([nutdata.Orientation])/ mean([nutdata.Orientation])std([nutdata.EquivDiameter])/ mean([nutdata.EquivDiameter])std([nutdata.Extent])/ mean([nutdata.Extent])std([nutdata.Extrema])/ mean([nutdata.Extrema])
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %處理花椒皮 close all;clc;clear;>> i=imread('p.bmp');imshow(i);ig=rgb2gray(i);figure,imshow(ig);imed=medfilt2(ig);imedcanny=edge(imed,'canny');figure,imshow(imedcanny);>> se90=strel('line',2,90);se0=strel('line',2,0);bwsdil=imdilate(imedcanny,[se90 se0]);figure,imshow(bwsdil),title('dilated');ifill=imfill(bwsdil,'holes');figure,imshow(ifill);>> bwero=imerode(ifill,[se90 se0]);>> figure,imshow(bwero);>> nosmall=bwareaopen(bwero,150,4);>> figure,imshow(nosmall);>> nobord=imclearborder(nosmall,4);>> figure,imshow(nobord);>> [labeled,numobjects]=bwlabel(nobord,4);>> numobjects >> pdata=regionprops(labeled,'all');>> max([pdata.Solidity])>> std([pdata.Solidity])/mean([pdata.Solidity])
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %處理混合圖像 >> clear;clc;close all;>> i=imread('m.bmp');%>> figure,imshow(i);>> ig=rgb2gray(i);figure,imshow(ig);imed=medfilt2(ig);%>> figure,imshow(imed);imedcanny=edge(imed,'canny');%>> figure,imshow(imedcanny);>> se90=strel('line',2,90);se0=strel('line',2,0);bwsdil=imdilate(imedcanny,[se90 se0]);%figure,imshow(bwsdil),title('dilated');ifill=imfill(bwsdil,'holes');%figure,imshow(ifill);bwero=imerode(ifill,[se90 se0]);%figure,imshow(bwero);>> nosmall=bwareaopen(bwero,150,4);%figure,imshow(nosmall);nobord=imclearborder(nosmall,4);figure,imshow(nobord);>> [labeled,numobjects]=bwlabel(nobord,4);>> numobjects >> rgb_label=label2rgb(labeled,@spring,'c','shuffle');figure,imshow(rgb_label);>> mexdata=regionprops(labeled,'all');hold on;%以下內容畫在同一figure中 centr=[mexdata.Centroid];%尋找重心位置 nums=1:numobjects;for k = 1:numobjects soli=mexdata(k).Solidity;soli_string=sprintf('%2.2f',soli);%等價于轉字符串 % signal=num2str(nums(k));signal=sprintf('%d',k);%直接使用打印語句打印序號 text(centr(2*k-1),centr(2*k),signal)%按序標記物體
text(centr(2*k-1)-30,centr(2*k)-30,soli_string)%標注每個Solidity值 end
for k=1:numobjects plot(mexdata(k).ConvexHull(:,1),mexdata(k).ConvexHull(:,2),...'b','Linewidth',2)end
%畫出1和2號物體的外接矩形
%>> rectangle('position',[9.5000 224.5000 62.0000 63.0000])%>> rectangle('position',[65.5000 141.5000 34.0000 39.0000])%畫出每個物體的外接矩形 bb=[mexdata.BoundingBox];for k=1:numobjects rectangle('position',[bb(4*k-3)bb(4*k-2)bb(4*k-1)bb(4*k)])end
%>> figure,imshow(mexdata(1).Image)%只顯示1號物體的圖像
%>> figure,imshow(mexdata(1).ConvexImage)%畫出1號物體的凸多邊形 %>> figure,imshow(mexdata(2).Image)%只顯示2號物體的圖像
%>> figure,imshow(mexdata(2).ConvexImage)%畫出2號物體的凸多邊形 %畫出單個物體的凸多邊形的填充圖形 for k=1:numobjects figure,imshow(mexdata(k).ConvexImage)end
%只顯示Solidity>0.92的物體的圖像 >> idx = find([mexdata.Solidity] > 0.92);>> BW2 = ismember(labeled,idx);>> figure,imshow(BW2)
>> mexdata=regionprops(labeled,'all');>> %只顯示Solidity<0.92的物體的圖像 idx = find([mexdata.Solidity] < 0.92);bw2 = ismember(labeled,idx);figure,imshow(bw2)%mexdata.Solidity;
>> numdown=find([mexdata.Solidity]<0.92);mexdata(numdown,:)=[];>> mexdata
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %2006.6.19 %roipoly函數的用法 I = imread('eight.tif');c = [222 272 300 270 221 194];r = [21 21 75 121 121 75];BW = roipoly(I,c,r);imview(I), imview(BW)
%可以使用下面的方法創建相應的向量: regionprops(L,'Area');allArea = [stats.Area];
%創建一個只包含面積大于80的二值圖像 idx = find([stats.Area] > 80);BW2 = ismember(L,idx);
%只顯示某個下標所對應的物體圖像 bw2=ismember(L,N);figure,imshow(bw2);
%在調用regionprops之前必須將二值圖像轉變為標注矩陣 L = bwlabel(BW);%或者
L = double(BW);
%將matlab數據寫到excel中 a=ones(3);success = xlswrite('c:/matlab/work/myworkbook.xls',a,'A2:C4')%將行矩陣轉換為列矩陣 a=[1 2 3 4 5 6];b=transpose(a);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %2006.6.22球形物體的檢測和標識(循環檢測和標識算法)clc;clear;close all;%Step 1: Read image %Step 2: Threshold the image %Step 3: Remove the noise %Step 4: Find the boundaries %Step 5: Determine which objects are round >> RGB = imread('pillsetc.png');imshow(RGB)>> I = rgb2gray(RGB);threshold = graythresh(I);bw = im2bw(I,threshold);imshow(bw)>> % remove all object containing fewer than 30 pixels bw = bwareaopen(bw,30);>> figure,imshow(bw)>> % fill a gap in the pen's cap se = strel('disk',2);bw = imclose(bw,se);>> figure,imshow(bw)>> % fill any holes, so that regionprops can be used to estimate % the area enclosed by each of the boundaries bw = imfill(bw,'holes');>> figure,imshow(bw)>> [B,L] = bwboundaries(bw,'noholes');>> % Display the label matrix and draw each boundary figure,imshow(label2rgb(L, @jet, [.5.5.5]))>> hold on for k = 1:length(B)boundary = B{k};plot(boundary(:,2), boundary(:,1), 'w', 'LineWidth', 2)end >> stats = regionprops(L,'Area','Centroid');>> stats = regionprops(L,'Area','Centroid');threshold = 0.94;% loop over the boundaries for k = 1:length(B)% obtain(X,Y)boundary coordinates corresponding to label 'k' boundary = B{k};% compute a simple estimate of the object's perimeter delta_sq = diff(boundary).^2;perimeter = sum(sqrt(sum(delta_sq,2)));
% obtain the area calculation corresponding to label 'k' area = stats(k).Area;
% compute the roundness metric metric = 4*pi*area/perimeter^2;
% display the results metric_string = sprintf('%2.2f',metric);% mark objects above the threshold with a black circle if metric > threshold centroid = stats(k).Centroid;plot(centroid(1),centroid(2),'ko');end
text(boundary(1,2)-35,boundary(1,1)+13,metric_string,'Color','y',...'FontSize',14,'FontWeight','bold');end >> title(['Metrics closer to 1 indicate that ',...'the object is approximately round']);
第三篇:Matlab圖像處理-圖像景物動態跟蹤
《圖像處理技術》大作業 作業題目
基于圖像的動態景物的監測與跟蹤 作業數據
(1)短視頻背景相同,一個目標運動;(2)短視頻(或5張圖片),背景相同,多個目標運動;(3)驗證數據自己提供(彩色、灰度圖像不限); 作業完成目標
動態目標的定位與跟蹤,并用方框提示并給出運動軌跡 能正確檢測運動目標; 多個目標的識別率;程序設計
1、界面設計:
2、“打開”按鈕功能設計:
打開圖片組的第一張圖片并在左邊顯示:
[name,path]=uigetfile('*.jpg;*.bmp;*.png;*.tif;*.gif','Open Image');file=[path,name];%讀取第一張圖片路徑 axes(handles.image1);%選擇在左窗口顯示 x=imread(file);%讀取第一張圖片 handles.img=x;guidata(hObject,handles);imshow(x);%顯示第一張圖片 global F;%全局變量F F=name(1:end-5);%F為文件名編號前的字符 global N;%全局變量N N=7;%N為圖片組中圖片總數量
3、“播放”按鈕功能設計:
讀取圖片組中所有的圖片,并按一定間隔時間顯示,形成動畫效果: global F;global N;axes(handles.image1);%選擇在左窗口顯示
for i=1:N %循環讀出圖片,形成動畫效果 f=int2str(i);I=strcat(F,f,'.jpg');%聯接文件名 a=imread(I);%讀取圖片 imshow(a);%顯示圖片 axis off %關閉坐標軸
pause(0.8);%每顯示一張圖片暫停0.8秒 end
4、“目標追蹤”按鈕功能設計:
讀取圖片,將圖片轉成二值圖像,利用兩張二值圖像的異或求得目標,在目標圖像中求得目標的邊框與質心,利用求得的邊框畫出目標的位置,利用存儲的質心畫出目標移動軌跡: global F;global N;x=handles.img;axes(handles.image2);%選擇在右窗口顯示 s=size(x);%獲取圖片大小 A=uint8(zeros(s(1),s(2),1,N));s=size(A);%獲取圖片組數組的大小 for i=1:s(4)%循環讀取圖片 t=int2str(i);I=strcat(F,t,'.jpg');a=imread(I);%讀取圖片
A(:,:,:,i)=rgb2gray(a);%轉為灰度圖片 end B=logical(zeros(s(1),s(2),s(3),s(4)));%定義二值矩陣 for f=1:s(4)imshow(A(:,:,:,f));%顯示圖片
level=graythresh(A(:,:,:,f))-30/255;%獲取閾值 B(:,:,:,f)=im2bw(A(:,:,:,f),level);%轉為二值圖像 B(:,:,:,1)=im2bw(A(:,:,:,1),level);B(:,:,:,f)= xor(B(:,:,:,1),B(:,:,:,f));%異或求得目標區域 B(:,:,:,1)= xor(B(:,:,:,1),B(:,:,:,1));B(:,:,:,f)=medfilt2(B(:,:,:,f),[7 7]);%對二值圖像中值濾波
L=bwlabel(B(:,:,:,f));%計算二值圖像的連通區域 stas=regionprops(L,'All');%獲取圖像連通區信息 t=size(stas);%獲取連通區數量 for j=1:t(1)p(f,j,:)=stas(j).BoundingBox;%存儲目標邊框
y(f,j,:)=stas(j).Centroid;%存儲目標位子(質心)%畫出目標邊框
rectangle('Position',p(f,j,:),'LineWidth',2,'LineStyle','--','EdgeColor','r');for k=1:f %以小方點畫出目標軌跡
rectangle('Position',[y(k,j,1),y(k,j,2),2,2],'LineWidth',2,'EdgeColor','b');end end pause(0.8);%每處理一張圖片暫停0.8秒 end
軟件說明
1、圖片組中圖片數量為7張,為RGB圖像,命名時從1~7編號。
2、打開軟件后單擊“打開”按鈕,選中圖片組的第一張圖片,即可在左邊顯示該圖片。
3、單擊“播放”按鈕,可以看到在左邊顯示圖片動畫。
4、單擊“目標跟蹤”按鈕,可以看到在右邊顯示出目標的跟蹤效果。效果圖
1、初始界面:
單目標跟蹤:
2、打開第一張圖片:
3、播放圖片組動畫:
4、目標追蹤,定位目標,顯示軌跡:
多目標跟蹤:
5、打開第一張圖片:
6、播放圖片組動畫:
7、目標追蹤,定位目標,顯示軌跡:
第四篇:MATLAB函數處理圖像實現膨脹腐蝕
MATLAB函數處理圖像實現膨脹腐蝕
一、實驗目的
1、了解二值形態學的基本運算
2、掌握二值圖像膨脹、腐蝕的基本方法
3、編程實現膨脹、腐蝕
二、實驗要求
1、使用imdilate函數進行圖像膨脹,并觀察膨脹后圖像的變化。
2、使用imerode函數進行圖像腐蝕,觀察腐蝕后的圖像變化情況。
三、實驗原理
膨脹:將與物體接觸的所有背景點合并到該物體中,使邊界向外部擴張的過程。利用它可以填補物體中的空洞。B對X膨脹所產生的二值圖像D是滿足以下條件的點(x,y)的集合:如果B的原點平移到點(x,y),那么它與X的交集非空。數學表達式:C?A?B
腐蝕:一種消除邊界點,使邊界向內部收縮的過程。利用它可以消除小而且無意義的物體。B對X腐蝕所產生的二值圖像E是滿足以下條件的點(x,y)的集合:如果B的原點平移到點(x,y),那么B將完全包含于X中。數學表達式:C?A?B
膨脹處理:一種消除邊界點,使邊界點向內部收縮的過程。
腐蝕處理:將與物體接觸的所有背景點合并到該物體中,使邊界向外部擴張的過程。
四、實驗步驟
1.圖像膨脹的Matlab實現:
可以使用imdilate函數進行圖像膨脹,imdilate函數需要兩個基本輸入參數,即待處理的輸入圖像和結構元素對象。結構元素對象可以是strel函數返回的對象,也可以是一個自己定義的表示結構元素鄰域的二進制矩陣。此外,imdilate還可以接受兩個可選參數:PADOPT(padopt)——影響輸出圖片的大小、PACKOPT(packopt).——說明輸入圖像是否為打包的二值圖像(二進制圖像)。步驟1,首先創建一個包含矩形對象的二值圖像矩陣。>> BW=zeros(9,10);>> BW(4:6,4:7)=1 BW = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 步驟2,使用一個3×3的正方形結構元素對象對創建的圖像進行膨脹。>> SE=strel('square',3)SE = Flat STREL object containing 9 neighbors.Neighborhood: 1 1 1 1 1 1 1 1 1 步驟3,將圖像BW和結構元素SE傳遞給imdilate函數。>> BW2=imdilate(BW,SE)BW2 = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 0 0
0 0 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 步驟4,顯示結果。>> imshow(BW,'notruesize')>> imshow(BW2,'notruesize')2.圖像腐蝕的Matlab實現:
可以使用imerode函數進行圖像腐蝕。imerode函數需要兩個基本輸入參數:待處理的輸入圖像以及結構元素對象。此外,imerode函數還可以接受3個可選參數:PADOPT(padopt)——影響輸出圖片的大小、PACKOPT(packopt).——說明輸入圖像是否為打包的二值圖像(二進制圖像)。M——指定原始圖像的行數。以下程序示例說明了如何對某一副具體圖像進行腐蝕操作,腐蝕前后的效果對比如圖末。
步驟1,讀取圖像cameraman.tif(該圖像是Matlab當前目錄下自帶的圖片)>> BW1=imread('cameraman.tif');步驟2,創建一個任意形狀的結構元素對象 >> SE=strel('arbitrary',eye(5));步驟3,以圖像BW1和結構元素SE為參數調用imerode函數進行腐蝕操作。>> BW2=imerode(BW1,SE);步驟4,顯示操作結果 >> imshow(BW1)>> figure,imshow(BW2)
五、實驗代碼及結果
代碼:
imerode函數,該函數能夠實現二值圖像的腐蝕操作; imdilate函數,該函數能夠實現二值圖像的膨脹操作; bw=imread(‘d:image1’)bw=rgb2gray(bw)se1=strel(‘disk’,11);
se2=strel(‘line’,11,90);bw2= imdilate(bw,se2);bw1=imerode(bw,se1);imshow(bw),title(‘原圖’)figure,imshow(bw2), title(‘膨脹后的圖像’)figure,imshow(bw1), title(‘腐蝕后的圖像’)
結果:
原
圖
膨脹后的圖像
腐蝕后的圖像
六、實驗心得體會
通過本次的實驗,我了解了二值形態學的基本運算,掌握了二值圖像膨脹、腐蝕的基本方法,并且會運用編程實現膨脹、腐蝕,本次的實驗目的已經完成,意識到在以后的生活中要了解做事情的目的,注重每一個與細節,認真思考遇到的所有問題,提高自己各方面的能力。感謝尹強老師教會我們理論與實踐知識,也讓我明白了什么是學習,怎么樣學習,為以后的生活奠定的基礎與指引了方向。
第五篇:matlab圖像分割總結報告(定稿)
課程總結報告
題目: 圖像分割程序設計
院 系 電氣與電子工程學院
專 業 xxxx 班 級 研電16xx 學 號 116xxxxxx 姓 名 xx
2016年 11月3日
摘 要:圖像分割是圖像處理與計算機視覺的基本問題之一,是圖像處理圖像分析的關鍵步驟。其中圖像二值化又是圖像分割的重點。本文對全局和局部閾值二值化法的幾種常用的算法和基本自適應閾值二值化進行了綜述。每基于一定理論和算法的圖像二值化方法都有各自不同的優勢和缺點,在實際應用當中應根據不同使用目的和使用標準采取不同的方法以達到最佳效果。本文在MATLAB 編程技術及其GUI 圖形用戶界面設計的基礎上,開發了具有交互式特點的數字圖像處理GUI軟件,界面操作簡單方便,實現了圖像二值化的功能。
關鍵詞:二值化;全局閾值法;局部閾值法;基本自適應閾值法;圖像分割; MATLAB GUI 0 引言
圖像分割技術作為圖像處理領域中極為重要的內容之一,是實現圖像分析和理解的基礎,而圖像二值化又是圖像分割的重點。只有在其基礎上才能對目標進行特征提取和參數測量,使得更高層的圖像分析和理解成為可能。二值化是圖像處理和分析的關鍵技術,也是個經典難題。隨著實際應用的需要,對圖像二值化進行深入的研究,不斷改進原有方法,提出新方法具有重要的意義。圖像二值化
二值化是圖像處理中的一個重要的問題,廣泛應用于圖像分割,圖像增強,圖像識別等領域。根據其運算的范圍不同,圖像的二值化方法可分為全局閾值方法和局部閾值方法。它利用了圖像中要提取的目標物與其背景在灰度特性上的差異,把原圖像變為僅用兩個灰度值表示的圖像目標和背景的二值圖像。其處理思想是,假設一副灰度圖像中的灰度級范圍是(0,255),則圖像中每一點像素的灰度值為f(x,y),f(x,y)∈{0,1,?,255),設閾值為T(0≤T≤255)則:
?0g(x,y)???1f(x,y)?Tf(x,y)?T其中:g(x,y)表示二值化后圖像中各個像素點的值,若g(x,y)=1表示改點為目標;若g(x,y)=0,表示改點為背景。GUI設計
圖形用于界面(GUI)是提供人機交互的工具和方法。MATLAB的GUI為開發者提供了一個不脫離MATLAB的開發環境,有助于MATLAB 程序的GUI集成。
本文設計的程序有以下功能:
1)實現圖像的讀取及顯示其灰度直方圖功能,保存功能及退出時“是否保存處理后圖像”的提醒功能。
2)設計圖形用戶界面,讓用戶能夠對圖像進行全局閾值分割,可選方法
為迭代法、Otsu法及改進的Otsu法,同時顯示該方法選取的閾值。
3)設計圖形用戶界面,讓用戶能夠對圖像進行局部閾值分割,可選方法為Bernsen法、Niblack法及改進的Bernsen法,同時關閉選取閾值的顯示(因為此時每個像素點均有對應的閾值)。
4)編寫程序對圖像進行基本自適應閾值分割,即將用戶所選取的圖像進行分塊后對每塊圖像用Otsu法進行二值化,并實現調整分塊大小時實時顯示處理后的圖像功能。
具體GUI設計的程序代碼及模塊、菜單配置過程不在此贅述。MATLAB中運行相應的m文件,會出現如下圖所示的初始界面:
圖2.1 初始界面
可以看到,在圖像沒有打開之前圖像分割功能是不可選的,這是在GUI編程中考慮到為避免對空白圖像進行二值化可能會產生全黑圖像的錯誤而設計的。
點擊如下選項,可以打開指定圖像,并顯示其對應的灰度直方圖:
圖2.2 “打開”圖像
現在“圖像分割”菜單變為可選,選擇相應算法可以得到不同效果的閾值分割結果圖,相應可選方法如圖:
圖2.3 “圖像分割”菜單
閾值分割完畢后,點擊圖標,可以對處理后的圖像進行保存。若不保存直接選擇“退出”菜單,程序會彈出如下圖所示選框,提醒用戶是否保存已更改的圖片,可以根據用戶需求進行選擇,同時避免了錯誤的發生。
圖2.4 “保存”與“退出” 閾值分割算法與實驗分析
3.1 全局閾值分割
全局閾值法根據文本圖像的直方圖或灰度空間分布確定一個閾值,以此實現灰度文本圖像到二值圖像的轉化。此方法的優點在于算法簡單,對目標和背景明顯分離、直方圖分布呈雙峰的圖像效果良好,但是由于對整幅圖使用一個閾值處理,因此其對輸入圖像有噪聲或不均勻光照等情況抵抗能力差,應用受到極大限制,不能廣泛地應用于實際。典型的全局閾值分割方法有迭代法、Otsu方法等。在此引入光照均勻的圖3.1和光照不均勻的圖3.2,本節將用下述全局閾值方法對其進行處理。
圖3.1 原始圖像1 圖3.2 原始圖像2
3.1.1 迭代法
迭代法的主要思想是利用循環迭代的方法,逐步逼近最佳閾值,其計算步驟主要是:
1)對圖像進行灰度化,找出圖像灰度的最大值和最小值,分別記為Rmax和
Rmin,令初始閾值為:
T??Rmax?Rmin?/2
2)根據當前的閾值T以及圖像的各像素的灰度值,將圖像像素分成前景與背景兩組。
3)分別求出當前前景與背景兩組像素的平均灰度值,記為u1和u2。4)求出新閾值:
T??u1?u2?/2
循環2)-4)步,直到兩組的平均灰度值不再發生新的變化,此時即獲得了所需要的閾值。這種方法運算很簡單,因此處理圖片的速度是很快的。處理光照均勻的圖3.1后,得到閾值為0.5312的圖3.3,可以看到效果還是比較好的;但是在處理光照不均勻的原圖3.2后,得到閾值為0.49393的圖3.4,可見只使用一個閾值,已經沒有辦法兼顧到所有細節情況了。
圖3.3 迭代法處理圖1 圖3.4 迭代法處理圖2 3.1.2 Otsu方法
二值化的算法之一Otsu法,也稱大津法,是全局二值化算法的經典算法之一。它是1979年由Otsu提出的,其基本思想是求取最佳門限閾值,此閾值將圖像灰度直方圖分割成黑白(前景與背景)兩部分,使兩部分類間方差取得最大值,并使類內方差值最小,即類間分離性最大,而類內的相似性最大,因此,Otsu法也稱最大類間方差法。對于某圖像的灰度直方圖,設T為區分前景灰度與背景灰度的二值化閾值,設w0為前景像素所占圖像總像素的比例,令u0為所有前景像素的平均灰度,設w1為背景點數所占圖像總像素的比例,令u1為所有背景像素的平均灰度,則圖像的所有像素的平均灰度為u?w0u0?w1u1。在進行程序運
算時,T的取值可從圖像的最小灰度值到圖像的最大灰度值依次遍歷,當T取某值時,類間方差公式b?w0?u0?u??w1?u1?u?能取得最大,此時T即為二值化
22的最佳閾值。使類間方差最大的二值化意味著錯分概率最小。
同樣,我們采用Otsu算法對圖3.1和圖3.2進行處理,分別得到圖3.5和圖3.6。圖3.5所選閾值為0.49804,可以看到效果依舊很好;圖3.4所選閾值為0.49412,效果很不理想。
圖3.5 Otsu法處理圖1 圖3.6 Otsu法處理圖2 3.1.3 改進的Otsu方法
圖像二值化是建立在物體和背景可以區分的基礎上的,如亮度色調等不同,從而根據這些已知信息分出前背景。而一般的全局二值化如用Otsu方法獲取最優閾值的方法,都是建立在圖像前背景亮度有一定差距的基礎上的,即圖像直方圖有雙峰結構。如果對于一幅亮度不均勻的圖像這種方法就不適用,解決的方法可以把圖像根據整體亮度變化來分成若干小區域,而各區域的直方圖中有兩個峰,這樣就能自適應得時整幅圖都比較好的二值化。但是,這樣對于一些復雜的圖像就難處理,而且可能存在分塊鄰接缺陷,因此,本程序中先將整幅圖的亮度調均勻,然后再用整體二值化就能得到很好的結果。這里使用Retinex算法把圖像的整體亮度調均勻后(此法能很好得將各種照度不均的圖調整成直方圖中明顯有雙峰的均勻圖),再用Otsu方法取閾值二值化。對光照不均勻圖3.2進行處理,得到圖3.7,可見此時的圖像輪廓得到了還原,取得了較好效果。
圖3.7 改進的Otsu法處理圖1
3.1.4 全局閾值法小結
下面,我們對全局閾值法做一些總結。一般說來,全局閾值法想法都比較簡單,實現起來也很高效簡單,但這種也是有代價的。它的適用范圍相對有限,擅長處理簡單圖像,比如目標與背景明顯分離的,直方圖分布呈雙峰的圖像。但是對于光照不均,模糊的文檔及多邊緣的圖像,就會丟失很多的信息。在此引入文本圖像圖3.8。可以看到下半部分是清晰的文字,但是上半部分的表格,則具有淡淡的底,使得字跡看起來變淡了,也就是說模糊了。由于Otsu算法在全局閾值二值化方法中具有很好的評價,在這里僅使用法對其進行處理,來看一看效果。
圖3.8 原始圖像3 使用Otsu方法處理圖3.8,所得閾值為0.7451,處理結果為圖3.9。可以看到,圖中下半部分還是比較清楚的,但是上半部分表中的文字顯示很不理想。對于這種光照均勻地圖像,改進的Otsu方法處理結果如圖3.10,其細節丟失更為嚴重。這正是全局閾值二值化的簡單性所付出的代價。由于該類方法只關心整幅圖像的灰度值分布特征,然后就迅速進行處理它是高度宏觀化的,因而對于局部的變化反映不夠靈敏。因此,使用該方法會丟失圖像的許多細節信息。
圖3.9 Otsu法處理圖2
圖3.10 改進的Otsu法處理圖2 由于全局閾值法的這一缺點,引出了關注細節的局部閾值二化算法。3.2 局部閾值分割
局部閾值法通過定義考察點的鄰域,比較考察點與其鄰域的灰度值來確定當前考察點的閾值。非均勻光照條件等情況雖然影響整體圖像的灰度分布卻不影響局部的圖像性質,使得局部閾值法較全局閾值法有更廣泛的應用。局部閾值法雖然能夠根據局部灰度特性來自適應地選取閾值,有較大的靈活性,但局部閾值存在速度慢,對文本圖像進行二值化處理時,可能導致出現筆畫斷裂現象以及偽影等問題,直接影響后面的識別工作。常用的局部閾值法有Bernsen算法、Niblack算法。
3.2.1 Bernsen算法
Bernsen算法是一種典型的局部閾值算法,其將窗口中各個像素灰度級最大值和最小值的平均值作為一個窗口的中心像素的閾值,因此此方法不存在預定閾值,適應性較全局閾值法廣,不受非均勻光照條件等情況的影響。
設圖像在像素點(i,j)處的灰度值f(i,j),考慮以像素點(i,j)為中心的?2??1???2??1?窗口,則Bernsen算法可以描述為:
???1?T?i,j???maxf(i?m,j?m)?minf(i?m,j?m)?
2????m?????m??????n??????n??? 圖像中各個像素點(i,j)的閾值T對圖像中各個像素點(i,j)用b(i,j)值逐點進行二值化:
?0b(i,j)???1
f(i,j)?T(i,j)
f(i,j)?T(i,j)
在實現算法的過程中會遇到一個不可避免的問題。當一個像素點處于整幅圖像的邊界處,或是其他距圖像邊界不足一個像素點單位的位置時,若以它為中心取的小塊,那么所取得的小塊就會有一部分是缺失的。這里,本文選取的處理方式是對原圖像加邊,新的邊灰度值全賦值為0。
在使用Bernsen算法進行圖像二值化的時候,是需要選擇窗口的大小的,現在結合算法來具體討論該因素的影響。從Bernsen算法求局部閾值公式來看,對于一個固定的像素點(x,y),當窗口尺度很小的時候,該像素點周圍有細微的明暗變化即有少量像素點的灰度變化就會影響到閾值的選取;當窗口尺度變大的時候,更多的像素點會進入到窗口中,原窗口內的像素點只是現在的一部分,對于閾值所產生的影響就相對弱化了,原有的細節就有可能丟失。現引入一幅光照不均但像素點相對較少的圖3.11,這樣改變窗口大小進行測試時可以節約程序運行時間。
圖3.11 原始圖像4 現取窗口為3*3,效果如圖3.12所示。圖中出現了大量斑點噪聲,文字被淹沒了。這是因為窗口選得太小,二值化時像素點附近出現的細微明暗變化都被
圖3.12 Bernsen法處理圖1 圖3.13 Bernsen法處理圖2
識別出來了。將窗口放大為9*9,效果見圖3.13。可以看到,效果好多了,許多斑點狀噪聲消失了,文字變得清楚了,但是字間噪聲沒有完全消除且粗筆狀況也比較明顯的。查閱相關文獻表明,應該選取15*15的窗口,原因是這樣所帶來的噪聲會顯著的減少。同時,處理圖片的時間則相應增加。鑒于此,在此后的處理中,大多取窗口為15*15。對于Bernsen法取窗口為15*15,所得的結果如圖3.14。
圖3.14 Bernsen法處理圖3 下面對圖3.8用Bernsen法進行二值化,看看效果如何。如圖3.15,與Otsu法處理圖2相比,列表中的文字變得相對清晰了,但是列表下方的文字出現了斷筆現象,而且背景噪聲問題同樣不能忽視。
圖3.15 Bernsen法處理圖5 3.2.2 Niblack算法
Niblack方法也是一種應用很廣泛的二值化算法。它根據局部均值和局部標
準差,確定圖像中不同的閾值。在像素點(x,y)的閾值的計算是:
T(x,y)?m(x,y)?k?s(x,y)
其中T(x,y)為閾值,m(x,y)為樣本均值,s(x,y)為標準差,k為參數。對于鄰域的選擇需要滿足能保存局部細節同時抑制噪聲的產生。和Bernsen方法相似,使用Niblack方法進行圖像二值化處理時,窗口大小的選擇也是很重要的。理由相同,如果窗口選得很小,處理速度比較快,但是給二值圖帶來的噪聲也是很嚴重的,導致前景淹沒在噪聲中,無法很容易的辨識;如果窗口選得大,會大幅地降低二值圖中的噪聲,但是處理的時間也變得更長了。窗口一般也取15*15,下面對圖3.8進行分割,結果見圖3.16。
圖3.16 Niblack法處理圖1 使用Niblack方法進行圖像二值化處理,由于需要計算標準差,需要進行平方開方運算,所以速度是比較慢的,我們看一下Bernsen方法,它比方法的速度要快些。但是從處理效果來看,它比Otsu法和Bernsen法效果優秀。不僅列表中文字細節得到了很好地還原,列表下方的文字也沒出現斷筆現象,很清晰,唯一需要改善的就是圖像背景噪聲問題。3.2.3 對局部閾值法的一點思考
由于局部閾值法充分考慮到了每一個像素點及其附近像素點的灰度分布情況,能兼顧圖像的細節變化,因此使用局部閾值二值化方法對圖像進行分割處理,一般說來,會得到更好的效果。很容易這么想,如果對一幅質量很好的圖片進行二值化分割,那么局部閾值法對其進行分割所得的效果應該比全局閾值法的效果好,即使不能更好,至少一樣好。現在看一個例子,引入圖3.17,它足夠簡單,背景與前景相比分離得很明顯。圖3.18是使用Otsu方法進行閾值分割的結果,圖3.17 原始圖像5 圖3.18 Otsu算法處理圖3 圖3.19 Niblack算法處理圖2 而圖3.19是使用Niblack法進行閾值分割的結果。局部閾值法處理效果在這里反而的質量卻降低了,它把沒有文字的空白背景,錯誤地識別成文字像素點。能對付復雜問題的工具,卻不能處理簡單的。回頭看Bernsen法和Niblack法閾值分割處理的結果圖3.15~3.16,也存在相同問題。表格右側空白背景,以及沒有足夠文字填充的一小段空白行,都被錯誤地識別成了前景。這說明,這個問題應該不是偶然出現的,可能是一個共性的問題。為了避免出現這種情況,在進行圖像二值化處理時,當每選取一個小窗口,就應該先進行判定。如果這個小窗口內同時混有前景和背景,那么就進行該中心點的二值化;否則,小窗口內就只含有前景或是只有背景,就不應該進行閾值分割了,而應該采取一種方法去判斷它是屬于背景還是前景。至于具體實現方案,這也是未來對局部閾值分割進行進一步研究的方向。
3.3 基本自適應閾值分割
全局閾值存在的問題是不均勻亮度無法有效分割,解決辦法除了像局部閾值法對圖像每一個像素進行處理外,還可以將整幅圖像化整為零,劃分為許多個小塊,分別進行處理,得到它的閾值。小塊特點是彼此分離沒有重疊,這也是與局部閾值法的區別。那么這個閾值相對于整體的全局閾值來說,就是與相應小塊中的像素更加關聯的,對于局部應該也是更好的。其中每一個小塊,可以簡單的將
它看作一幅圖像,這樣,要得到與這個小塊相關的局部閾值,可以簡單地使用全局閾值值法來對每個小塊做出處理,進行二值化。
我們將圖像劃分成許多小塊,如果稱小塊的長和寬為尺度的話,那么選取時,若尺度太大,對圖像的局部還不夠好;但是若尺度太小,小塊內可能就只有前景或只有背景了,此時的二值化是不合理的。所以,給小塊選擇一個合適的尺度是很講究的,本文目前只能通過不斷嘗試來確定。現引入圖3.20,對其進行基本自適應閾值分割。
圖3.20 原始圖像6 圖3.21 基本自適應閾值處理圖1 經過嘗試,現選用處理效果較好的115*115的分塊對圖3.20進行處理,所得結果如圖3.21所示。我們發現,對于這種水平方向上光照不均的圖像的處理,原圖的細節得到了很好的保留,其處理效果還是很不錯的。
事實上,一幅圖劃分成的子塊是圖像的一部分,它們的閾值應該是有所關聯的。如果就這樣一個個孤立開的話,就會發生閾值灰度躍變的問題,即由于每一個小塊內的各自閾值都相差很大,可能導致塊與塊交界處的圖像像素灰度值不連續,出現明顯間斷或不一致。解決辦法有兩個:要么對這些邊界處的像素點做出處理,要么對這些閾值做出處理。具體實現辦法還沒有一個清晰的框架,只能等課程結束以后對其進行進一步的研究和學習。結束語
本文利用不同算法對不同圖像進行了閾值分割處理,對處理所得到的二值圖進行了比較。對于一些簡單圖像,全局閾值法能很好的保持原圖的主要信息,且實現簡單、運行速度快,但對復雜圖像的處理效果不佳。對于光照不均或較復雜的圖像,局部閾值法可以保留更多細節,但是背景噪聲比較嚴重,且運行速度較慢。基本自適應閾值方法也能對光照不均的圖像進行處理,但是分塊大小的確定還沒有一個準則,只能稱之為半自適應閾值分割。實踐工作中遇到的需要進行二值化的圖像是紛繁復雜的,上面提到的算法尚有許多方面可以改善。本次程序設計,無論在數字圖像處理的理論知識還是MATLAB軟件中GUI的掌握上還是對算法的編程實現上,都有了更深刻的了解與進步。并且對圖像處理有了很大的興趣,希望在今后的學習中能夠更加深入的學習。