第一篇:基于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的交集非空。数学表达式:CAB
腐蚀:一种消除边界点,使边界向内部收缩的过程。利用它可以消除小而且无意义的物体。B对X腐蚀所产生的二值图像E是满足以下条件的点(x,y)的集合:如果B的原点平移到点(x,y),那么B将完全包含于X中。数学表达式:CAB
膨胀处理:一种消除边界点,使边界点向内部收缩的过程。
腐蚀处理:将与物体接触的所有背景点合并到该物体中,使边界向外部扩张的过程。
四、实验步骤
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,令初始阈值为:
TRmaxRmin/2
2)根据当前的阈值T以及图像的各像素的灰度值,将图像像素分成前景与背景两组。
3)分别求出当前前景与背景两组像素的平均灰度值,记为u1和u2。4)求出新阈值:
Tu1u2/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为所有背景像素的平均灰度,则图像的所有像素的平均灰度为uw0u0w1u1。在进行程序运
算时,T的取值可从图像的最小灰度值到图像的最大灰度值依次遍历,当T取某值时,类间方差公式bw0u0uw1u1u能取得最大,此时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)为中心的2121窗口,则Bernsen算法可以描述为:
1Ti,jmaxf(im,jm)minf(im,jm)
2mmnn 图像中各个像素点(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)ks(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的掌握上还是对算法的编程实现上,都有了更深刻的了解与进步。并且对图像处理有了很大的兴趣,希望在今后的学习中能够更加深入的学习。