http://www.cnblogs.com/tornadomeet/archive/2012/03/20/2408086.html
关于形态学的实验需要对二值图像进行减噪处理,图像形态学中的腐蚀和膨胀能很好的解决此问题。如果在腐蚀和膨胀操作前,对灰度图像做一次滤波,减噪效果将更明显。
腐蚀的具体操作是:用一个结构元素(一般是3×3的大小)扫描图像中的每一个像素,用结构元素中的每一个像素与其覆盖的像素做“与”操作,如果都为1,则该像素为1,否则为0。膨胀的具体操作是:用一个结构元素(一般是3×3的大小)扫描图像中的每一个像素,用结构元素中的每一个像素与其覆盖的像素做“与”操作,如果都为0,则该像素为0,否则为1。
腐蚀的作用是消除物体边界点,使目标缩小,可以消除小于结构元素的噪声点;膨胀的作用是将与物体接触的所有背景点合并到物体中,使目标增大,可添补目标中的空洞。
开运算是先腐蚀后膨胀的过程,可以消除图像上细小的噪声,并平滑物体边界。
闭运算时先膨胀后腐蚀的过程,可以填充物体内细小的空洞,并平滑物体边界。
MATLAB中基本知识点:
1.对二值化图像进行形态学处理(bwmorph)
函数调用格式:
BW=bwmorph(I,operation);
BW=bwmorph(I,operation,n);
Operation:
‘bothat’:闭包运算,即先腐蚀,在膨胀,然后减去原图像;
‘branchpoints’:找出骨架的分支结点
‘endpoints’:找出骨架端点
‘bridge’:做连接运算;
‘clean’:去除孤立的亮点;
‘close’:进行二值闭运算(先膨胀后腐蚀);
‘diag’:采用对角线填充来去除8邻域的背景;
‘dilate’:采用结构元素ones(3)做膨胀运算;
‘erode’:采用结构元素ones(3)作腐蚀运算;
‘fill’:填充孤立的黑点;
‘hbreak’:断开H形连接;
‘Majority’:若像素的8邻域中有大于或等于5的元素为1,则像素为1,否则为0;
‘open’:执行二值开运算(先腐蚀后膨胀);
‘remove’:去掉内点,即若像素的4邻域都为1,则像素为0;
‘shrink’n=inf:做收缩运算,这样没有孔的物体收缩为一个点,而含孔的物体收缩为一个相连的环,环的位置在孔和物体外边缘的中间,收缩运算保持欧拉数不变,
‘skel’n=inf:
‘spur’:去除物体小的分支;
‘thicken’n=inf;对物体进行粗化,即对物体的外边缘增加像素,知道原来为连接的物体按照8邻域被连接起来。粗化保持欧拉数不变。
‘thin’n=inf:对物体进行细化,使得没有孔的物体收缩为最小连接棒,而含有孔的物体收缩为一个连接的环,同样细化保持欧拉数不变。
‘tophat’:用原图减去开运算后的图像;
2.
格式:BW2
作用:删除二值图像BW中面积小于P的对象,默认情况下使用8邻域。
算法:
(1)Determine
(2)Compute
(3)Remove
3.matlab函数bwarea──计算对象面积
格式:total
作用:估计二值图像中对象的面积。
注:该面积和二值图像中对象的像素数目不一定相等。
3、matlab函数imclearborder──边界对象抑制
格式:IM2
作用:抑制和图像边界相连的亮对象。若IM是二值图,imclearborder将删除和图像边界相连的对象。默认情况conn=8。
注:For
算法:
(1)Mask
(2)Marker
4、matlab函数bwboundaries──获取对象轮廓
格式:B
作用:获取二值图中对象的轮廓,和OpenCV中cvFindContours函数功能类似。B是一个P×1的cell数组,P为对象个数,每个cell
5、matlab函数imregionalmin──获取极小值区域
格式:BW
作用:寻找图像I的极小值区域(regional
Regional
6、matlab函数bwulterode──距离变换的极大值
格式:BW2
作用:终极腐蚀。寻找二值图像BW的距离变换图的区域极大值(regional
7、regionprops统计被标记的区域的面积分布,显示区域总数。
函数regionprops语法规则为:STATS
该函数用来测量标注矩阵L中每一个标注区域的一系列属性。
L中不同的正整数元素对应不同的区域,例如:L中等于整数1的元素对应区域1;L中等于整数2的元素对应区域2;以此类推。
返回值STATS是一个
Properties可以是由逗号分割的字符串列表、包含字符
'Area'
'BoundingBox'
'Centroid'
'MajorAxisLength'
'MinorAxisLength'
'Eccentricity'
'Orientation'
'Image'
'FilledImage'
'FilledArea'
'ConvexHull'
'ConvexImage'
'ConvexArea'
'EulerNumber'
'Extrema'
'EquivDiameter'
'Solidity'
'Extent'
'PixelIdxList'
'PixelList'
提醒
使用逗号分割列表语法:当你基于regionprops函数的输出作算法设计时,使用逗号分割列表语法就凸显出其非常的价值。例如:对于一个存储标量的属性,可以利用此语法创建一个包含图像中不同区域内此属性值的向量。例如以下两句是等价的:
stats(1).Area,
stats.Area
因此,可以使用下面的方法创建相应的向量:
regionprops(L,'Area');
allArea
基于特定原则的区域选择:当你要基于特定准则条件选择某个区域时,将函数
idx
计算性能考虑:大多数的属性测量计算时间都非常地少,除了那些非常依赖于图像L中区域个数和像素个数的属性。例如:
'ConvexHull'
另外建议一次性计算所有属性值,因为分开计算和一起计算时间相差无几!
使用二值图像工作:在调用regionprops之前必须将二值图像转变为标注矩阵。两个函数可以做到:
L
注意:虽然这两个函数从同一二值图像产生不同的标注矩阵,但是它们是等效的!例如:给出如下的二值矩阵BW,
1
bwlabel
mylabel
double
mylabel2
mylabel2
regionprops
regionprops函数的扩展思路:在regionprops函数的基础上,你可以使用它提供的基本数据来扩展它的功能,将区域的曲率数据和骨架数据作为它的另外属性值来开发,从而希望
它能用来做更细致的特征提取。
%% imdilate膨胀
clc
clear
A1=imread('.\images\dipum_images_ch09\Fig0906(a)(broken-text).tif');
info=imfinfo('.\images\dipum_images_ch09\Fig0906(a)(broken-text).tif')
B=[0 1 0
1 1 1
0 1 0];
A2=imdilate(A1,B);%图像A1被结构元素B膨胀
A3=imdilate(A2,B);
A4=imdilate(A3,B);
subplot(221),imshow(A1);
title('imdilate膨胀原始图像');
subplot(222),imshow(A2);
title('使用B后1次膨胀后的图像');
subplot(223),imshow(A3);
title('使用B后2次膨胀后的图像');
subplot(224),imshow(A4);
title('使用B后3次膨胀后的图像');
%imdilate图像膨胀处理过程运行结果如下:
<img src="https://img-blog.csdn.net/20150511101157664?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGFuZ2IyMDE0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
%% imerode腐蚀
clc
clear
A1=imread('.\images\dipum_images_ch09\Fig0908(a)(wirebond-mask).tif');
subplot(221),imshow(A1);
title('腐蚀原始图像');
%strel函数的功能是运用各种形状和大小构造结构元素
se1=strel('disk',5);%这里是创建一个半径为5的平坦型圆盘结构元素
A2=imerode(A1,se1);
subplot(222),imshow(A2);
title('使用结构原始disk(5)腐蚀后的图像');
se2=strel('disk',10);
A3=imerode(A1,se2);
subplot(223),imshow(A3);
title('使用结构原始disk(10)腐蚀后的图像');
se3=strel('disk',20);
A4=imerode(A1,se3);
subplot(224),imshow(A4);
title('使用结构原始disk(20)腐蚀后的图像');
%图像腐蚀处理过程运行结果如下:
<img src="https://img-blog.csdn.net/20150511101025028?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGFuZ2IyMDE0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
%% 开运算和闭运算
clc
clear
f=imread('.\images\dipum_images_ch09\Fig0910(a)(shapes).tif');
%se=strel('square',5');%方型结构元素
se=strel('disk',5');%圆盘型结构元素
imshow(f);%原图像
title('开闭运算原始图像')
%运行结果如下:
<img src="https://img-blog.csdn.net/20150511101045230?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGFuZ2IyMDE0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
%开运算数学上是先腐蚀后膨胀的结果
%开运算的物理结果为完全删除了不能包含结构元素的对象区域,平滑
%了对象的轮廓,断开了狭窄的连接,去掉了细小的突出部分
fo=imopen(f,se);%直接开运算
figure,subplot(221),imshow(fo);
title('直接开运算');
%闭运算在数学上是先膨胀再腐蚀的结果
%闭运算的物理结果也是会平滑对象的轮廓,但是与开运算不同的是,闭运算
%一般会将狭窄的缺口连接起来形成细长的弯口,并填充比结构元素小的洞
fc=imclose(f,se);%直接闭运算
subplot(222),imshow(fc);
title('直接闭运算');
foc=imclose(fo,se);%先开后闭运算
subplot(223),imshow(foc);
title('先开后闭运算');
fco=imopen(fc,se);%先闭后开运算
subplot(224),imshow(fco);
title('先闭后开运算');
%开闭运算结果如下:
<img src="https://img-blog.csdn.net/20150511101101345?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGFuZ2IyMDE0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
%先膨胀再腐蚀
fse=imdilate(f,se);%膨胀
%gcf为得到当前图像的句柄,当前图像是指例如PLOT,TITLE,SURF等
%get函数为得到物体的属性,get(0,'screensize')为返回所有物体screensize属性值
%set函数为设置物体的属性
figure,set(gcf,'outerposition',get(0,'screensize'));%具体目的是设置当前窗口的大小
subplot(211),imshow(fse);
title('使用disk(5)先膨胀后的图像');
fes=imerode(fse,se);
subplot(212),imshow(fes);
title('使用disk(5)先膨胀再腐蚀后的图像');
%先膨胀后腐蚀图像如下:
<img src="https://img-blog.csdn.net/20150511101316569?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGFuZ2IyMDE0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
%先腐蚀再膨胀
fse=imerode(f,se);
figure,set(gcf,'outerposition',get(0,'screensize'))
subplot(211),imshow(fse);
title('使用disk(5)先腐蚀后的图像');
fes=imdilate(fse,se);
subplot(212),imshow(fes);
title('使用disk(5)先腐蚀再膨胀后的图像');
%先腐蚀后膨胀的图像如下:
<img src="https://img-blog.csdn.net/20150511101331576?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGFuZ2IyMDE0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
%% imopen imclose在指纹上的应用
clc
clear
f=imread('.\images\dipum_images_ch09\Fig0911(a)(noisy-fingerprint).tif');
se=strel('square',3);%边长为3的方形结构元素
subplot(121),imshow(f);
title('指纹原始图像');
A=imerode(f,se);%腐蚀
subplot(122),imshow(A);
title('腐蚀后的指纹原始图像');
%指纹原始图像和腐蚀后的图像结果如下:
<img src="https://img-blog.csdn.net/20150511101349765?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGFuZ2IyMDE0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
fo=imopen(f,se);
figure,subplot(221),imshow(fo);
title('使用square(3)开操作后的图像');
fc=imclose(f,se);
subplot(222),imshow(fc);
title('使用square闭操作后的图像');
foc=imclose(fo,se);
subplot(223),imshow(foc);
title('使用square(3)先开后闭操作后的图像')
fco=imopen(fc,se);
subplot(224),imshow(fco);
title('使用square(3)先闭后开操作后的图像');
%指纹图像开闭操作过程结果如下:
<img src="https://img-blog.csdn.net/20150511101217629?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGFuZ2IyMDE0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
%% bwhitmiss击中或击不中变换
clc
clear
f=imread('.\images\dipum_images_ch09\Fig0913(a)(small-squares).tif');
imshow(f);
title('击中或不击中原始图像');
%击中或不击中原始图像显示结果如下:
<img src="https://img-blog.csdn.net/20150511101425458?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGFuZ2IyMDE0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
B1=strel([0 0 0;0 1 1;0 1 0]);%击中:要求击中所有1的位置
B2=strel([1 1 1;1 0 0;1 0 0]);%击不中,要求击不中所有1的位置
B3=strel([0 1 0;1 1 1;0 1 0]);%击中
B4=strel([1 0 1;0 0 0;0 0 0]);%击不中
B5=strel([0 0 0;0 1 0;0 0 0]);%击中
B6=strel([1 1 1;1 0 0;1 0 0]);%击不中
g=imerode(f,B1)&imerode(~f,B2)%利用定义来实现击中或击不中
figure,subplot(221),imshow(g);
title('定义实现组1击中击不中图像');
g1=bwhitmiss(f,B1,B2);
subplot(222),imshow(g1);
title('结构数组1击中击不中后的图像');
g2=bwhitmiss(f,B3,B4);
subplot(223),imshow(g2);
title('结构数组2击中击不中的图像');
g3=bwhitmiss(f,B5,B6);
subplot(224),imshow(g3);
title('结构数组3击中击不中的图像');
%击中击不中变换后图像如下:
<img src="https://img-blog.csdn.net/20150511101443648?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGFuZ2IyMDE0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
%%makelut
clc
clear
f=inline('sum(x(:))>=3');%inline是用来定义局部函数的
lut2=makelut(f,2)%为函数f构造一个接收2*2矩阵的查找表
lut3=makelut(f,3)
%% Conway生命游戏
clc
clear
lut=makelut(@conwaylaws,3);
bw1= [0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 1 0 0 0
0 0 0 1 1 1 1 0 0 0
0 0 1 0 0 0 0 1 0 0
0 0 1 0 1 1 0 1 0 0
0 0 1 0 0 0 0 1 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 ];
subplot(221),imshow(bw1,'InitialMagnification','fit');
title('Generation 1');
bw2=applylut(bw1,lut);
subplot(222),imshow(bw2,'InitialMagnification','fit'),
title('Generation 2');
bw3=applylut(bw2,lut);
subplot(223),imshow(bw3,'InitialMagnification','fit');
title('Generation 3');
temp=bw1;
for i=2:100
bw100=applylut(temp,lut);
temp=bw100;
end
subplot(224),imshow(bw100,'InitialMagnification','fit')
title('Generation 100');
%显示Generation结果如下:
<img src="https://img-blog.csdn.net/20150511101505488?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGFuZ2IyMDE0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
%% getsequence
clc
clear
se=strel('diamond',5)
decomp=getsequence(se)%getsequence函数为得到分解的strel序列
decomp(1)
decomp(2)
%% endpoints
clc
clear
f1=imread('.\images\dipum_images_ch09\Fig0914(a)(bone-skel).tif');
subplot(121),imshow(f1);
title('原始形态骨架图像');
g1=endpoints(f1);
%set(gcf,'outerposition',get(0,'screensize'));%运行完后自动生成最大的窗口
subplot(122),imshow(g1);
title('骨架图像的端点图像');
<img src="https://img-blog.csdn.net/20150511101524941?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGFuZ2IyMDE0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
%骨架头像端点检测头像如下:
f2=imread('.\images\dipum_images_ch09\Fig0916(a)(bone).tif');
figure,subplot(121),imshow(f2);
title('原始骨头图像');
g2=endpoints(f2);
subplot(122),imshow(g2);
title('骨头图像端点头像');%结果是没有端点
%骨头头像端点检测图像如下:
<img src="https://img-blog.csdn.net/20150511101352134?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGFuZ2IyMDE0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
%% bwmorph组合常见形态学之细化
clc
clear
f=imread('.\images\dipum_images_ch09\Fig0911(a)(noisy-fingerprint).tif');
subplot(221),imshow(f);
title('指纹图像细化原图');
g1=bwmorph(f,'thin',1);
subplot(222),imshow(g1);
title('指纹图像细化原图');
g2=bwmorph(f,'thin',2);
subplot(223),imshow(g2);
title('指纹图像细化原图');
g3=bwmorph(f,'thin',Inf);
subplot(224),imshow(g3);
title('指纹图像细化原图');
%指纹图像细化过程显示如下:
<img src="https://img-blog.csdn.net/20150511101604674?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGFuZ2IyMDE0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
%% bwmorph组合常见形态学之骨骼化
clc
clear
f=imread('.\images\dipum_images_ch09\Fig0911(a)(noisy-fingerprint).tif');
subplot(131),imshow(f);
title('指纹图像骨骼化原图');
fs=bwmorph(f,'skel',Inf);
subplot(132),imshow(fs);
title('指纹图像骨骼化');
for k=1:5
fs=fs&~endpoints(fs);
end
subplot(133),imshow(fs);
title('指纹图像修剪后骨骼话');
%指纹图像骨骼化过程显示:
<img src="https://img-blog.csdn.net/20150511101625126?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGFuZ2IyMDE0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
%% 使用函数bwlabel标注连通分量
clc
clear
f=imread('.\images\dipum_images_ch09\Fig0917(a)(ten-objects).tif');
imshow(f),title('标注连通分量原始图像');
%其结果显示如下:
<img src="https://img-blog.csdn.net/20150511101453130?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGFuZ2IyMDE0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
[L,n]=bwlabel(f);%L为标记矩阵,n为找到连接分量的总数
[r,c]=find(L==3);%返回第3个对象所有像素的行索引和列索引
rbar=mean(r);
cbar=mean(c);
figure,imshow(f)
hold on%保持当前图像使其不被刷新
for k=1:n
[r,c]=find(L==k);
rbar=mean(r);
cbar=mean(c);
plot(cbar,rbar,'Marker','o','MarkerEdgeColor','k',...
'MarkerFaceColor','k','MarkerSize',10);%这个plot函数用法不是很熟悉
plot(cbar,rbar,'Marker','*','MarkerFaceColor','w');%其中的marker为标记
end
title('标记所有对象质心后的图像');
<img src="https://img-blog.csdn.net/20150511101702129?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGFuZ2IyMDE0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
%% 由重构做开运算
clc
clear
f=imread('.\images\dipum_images_ch09\Fig0922(a)(book-text).tif');
subplot(321),imshow(f);
title('重构原始图像');
fe=imerode(f,ones(51,1));%竖线腐蚀
subplot(322),imshow(fe);
title('使用竖线腐蚀后的结果');
fo=imopen(f,ones(51,1));%竖线做开运算
subplot(323),imshow(fo);
title('使用竖线做开运算结果');
fobr=imreconstruct(fe,f);%fe做标记
subplot(324),imshow(fobr);
title('使用竖线做重构开运算');
ff=imfill(f,'holes');%对f进行孔洞填充
subplot(325),imshow(ff);
title('对f填充孔洞后的图像');
fc=imclearborder(f,8);%清除边界,2维8邻接
subplot(326),imshow(fc);
title('对f清除边界后的图像');
%图像重构过程显示如下:
<img src="https://img-blog.csdn.net/20150511101524392?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGFuZ2IyMDE0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
%% 使用顶帽变换和底帽变换
clc
clear
f=imread('.\images\dipum_images_ch09\Fig0926(a)(rice).tif');
subplot(221),imshow(f);
title('顶帽底帽变换原始图像');
se=strel('disk',10);%产生结构元素
%顶帽变换是指原始图像减去其开运算的图像
%而开运算可用于补偿不均匀的背景亮度,所以用一个大的结构元素做开运算后
%然后用原图像减去这个开运算,就得到了背景均衡的图像,这也叫做是图像的顶帽运算
f1=imtophat(f,se);%使用顶帽变换
subplot(222),imshow(f1);
title('使用顶帽变换后的图像');
%底帽变换是原始图像减去其闭运算后的图像
f2=imbothat(imcomplement(f),se);%使用底帽变换,为什么原图像要求补呢?
%f2=imbothat(f,se);%使用底帽变换
subplot(223),imshow(f2);
title('使用底帽变换后的图像');
%顶帽变换和底帽变换联合起来用,用于增加对比度
f3=imsubtract(imadd(f,imtophat(f,se)),imbothat(f,se));%里面参数好像不合理?
subplot(224),imshow(f3);
title('使用顶帽底帽联合变换后图像');
%顶帽底帽变换过程图像如下:
<img src="https://img-blog.csdn.net/20150511101541786?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGFuZ2IyMDE0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
%%使用开运算和闭运算做形态学平滑
%由于开运算可以除去比结构元素更小的明亮细节,闭运算可以除去比结构元素更小的暗色细节
%所以它们经常组合起来一起进行平滑图像并去除噪声
clc
clear
f=imread('.\images\dipum_images_ch09\Fig0925(a)(dowels).tif');
subplot(221),imshow(f);
title('木钉图像原图');
se=strel('disk',5);%disk其实就是一个八边形
fo=imopen(f,se);%经过开运算
subplot(222),imshow(f);
title('使用半径5的disk开运算后的图像');
foc=imclose(fo,se);
subplot(223),imshow(foc);
title('先开后闭的图像');
fasf=f;
for i=2:5
se=strel('disk',i);
fasf=imclose(imopen(fasf,se),se);
end
subplot(224),imshow(fasf);
title('使用开闭交替滤波后图像');
%使用开运算和闭运算做形态学平滑结果如下:
<img src="https://img-blog.csdn.net/20150511101753750?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGFuZ2IyMDE0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
%% 颗粒分析
clc
clear
f=imread('.\images\dipum_images_ch09\Fig0925(a)(dowels).tif');
sumpixels=zeros(1,36);
for k=0:35
se=strel('disk',k);
fo=imopen(f,se);
sumpixels(k+1)=sum(fo(:));
end
%可以看到,连续开运算之间的表面积会减少
plot(0:35,sumpixels),xlabel('k'),ylabel('surface area');
title('表面积和结构元素半径之间的关系');
%其运算结果如下:
<img src="https://img-blog.csdn.net/20150511102014946?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGFuZ2IyMDE0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
figure,plot(-diff(sumpixels));%diff()函数为差分或者近似倒数,即相邻2个之间的差值
xlabel('k'),ylabel('surface area reduction');
title('减少的表面积和结构元素半径之间的关系');
%其运算结果如下:
<img src="https://img-blog.csdn.net/20150511102031341?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGFuZ2IyMDE0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
%% 使用重构删除复杂图像的背景
clc
clear
f=imread('.\images\dipum_images_ch09\Fig0930(a)(calculator).tif');
subplot(221),imshow(f);
title('灰度级重构原图像');
f_obr=imreconstruct(imerode(f,ones(1,71)),f);
subplot(222),imshow(f_obr);
title('经开运算重构图');
f_o=imopen(f,ones(1,71));
subplot(223),imshow(f_o);
title('经开运算后图');
f_thr=imsubtract(f,f_obr);
subplot(224),imshow(f_thr);
title('顶帽运算重构图')
%使用重构删除复杂图像的背景1:
<img src="https://img-blog.csdn.net/20150511101729692?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGFuZ2IyMDE0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
f_th=imsubtract(f,f_o)
figure,subplot(221),imshow(f_th);
title('经顶帽运算图');
g_obr=imreconstruct(imerode(f_thr,ones(1,11)),f_thr);
subplot(222),imshow(g_obr);
title('用水平线对f_thr经开运算后重构图');
g_obrd=imdilate(g_obr,ones(1,2));
subplot(223),imshow(g_obrd);
title('使用水平线对上图进行膨胀');
f2=imreconstruct(min(g_obrd,f_thr),f_thr);
subplot(224),imshow(f2);
title('最后的重构结果');
%使用重构删除复杂图像的背景2:
<img src="https://img-blog.csdn.net/20150511101757132?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGFuZ2IyMDE0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
其中代码实现部分特别详细: