同样的,暂时对书上已经写得很清楚的知识点不再重复赘述,主要做一些总结,思考以及知识点的梳理和扩展。
介绍一下形态学中的一些基本概念。
介绍一下比较陌生的几个概念,其他的看书就好:
所有像素坐标的集合均不属于集合A,记为 A c A^c Ac,由下式给出:
这个集合称为集合A的补集。
二值图像:
二值图像(Binary Image),按名字来理解只有两个值,0和1,0代表黑,1代表白,或者说0表示背景,而1表示前景。其保存也相对简单,每个像素只需要1Bit就可以完整存储信息。如果把每个像素看成随机变量,一共有N个像素,那么二值图有2的N次方种变化,而8位灰度图有255的N次方种变化,8为三通道RGB图像有255255255的N次方种变化。也就是说同样尺寸的图像,二值图像保存的信息更少。二值图像(binary image),即图像上的每一个像素只有两种可能的取值或灰度等级状态,人们经常用黑白、B&W、单色图像表示二值图像。
二值图像集合:
如果A和B是二值图像,那么C=A∪B仍是二值图像。这里,如 果 A 和B中相应的像素不是前景像素就是背景像素,那么 C中的这个像素就是前景像素。以第一种观点,函数 C由下式给出:
另一方面,运用集合的观点,C由下式给出:
集合运算:
编码:
f = imread('D:\数字图像处理\第九章学习\Fig0903(a).tif');
g = imread('D:\数字图像处理\第九章学习\Fig0903(b).tif');
subplot(2,3,1), imshow(f);title('(a)二值图像 A:');
subplot(2,3,2), imshow(g);title('(b)二值图像 B:');
subplot(2,3,3), imshow(~f);title('(c)A的补集~A:');
subplot(2,3,4), imshow(f|g);title('(d) A和B的并集 A|B:');
subplot(2,3,5), imshow(f&g);title('(e)A和B的交集 A & B:');
subplot(2,3,6), imshow(f&~g);title('(f)A和B的差集 A&~B');
图像(d)是 “ UTK”和 “ GT” 图像的并集,包括来自两幅图像的所有前景像素。相反,两幅图像的交集(图(e))显示了字母 “ UTK”和 “ GT”中重叠的像素。最后,集合的差集图像(图(f))显示了 “ UTK”中除去 “ GT” 像素后的字母。
膨胀:膨胀是在二值图像中“加长”或“变粗”的操作。这种特殊的方式和变粗的程度由一个称为结构元素的集合控制。(实际就是将结构元素的原点与二值图像中的1重叠,将二值图像中重叠部分不是1的值变为1,完成膨胀)。
公式:
图解:
注意:
膨胀函数:
D = imdilate(A,B)
图像膨胀的应用:桥接文字裂缝
编码:
A = imread('D:\数字图像处理\第九章学习\Fig0906(a).tif');
B = [0 1 0; 1 1 1; 0 1 0]; %指定结构元素由0和1组成的矩阵
A2 = imdilate(A, B); %二值图像
subplot(1,2,1), imshow(A);title('(a)包括断开文本的输入图像:');
subplot(1,2,2), imshow(A2);title('(b)膨胀后图像:');
B膨胀A等同于B1先膨胀A,再用B2膨胀之前的结果。
举例:
下面是由1组成的5x5数组的膨胀:
这个结构元能够分解为值为 1 的 5 元素行矩阵和值为 1 的 5 元素列矩阵:
在原结构元中,元素个数为 25; 但在行列分解后,总元素数目仅为 10。这意味着首先用 行结构元膨胀,再用列结构元膨胀,能够比 5x5 的数组膨胀快 2.5 倍。在实践中,速度的增长稍微慢一些,因为在每个膨胀运算中总有些其他开销。然而,由分解执行获得的速度方面的增 长仍然有很大意义。
工具箱函数 strel 用于构造各种形状和大小的结构元。
基本语法:
se = strel(shape, parameters)
shape用于指定希望形状的字符串,parameters是描述形状信息的参数列表。
具体例子参考课本,是基础语法。
腐蚀:与膨胀相反,对二值图像中的对象进行“收缩”或“细化”。(实际上将结构元素的原点覆盖在每一个二值图像的1上,只要二值图像上有0和结构元素的1重叠,那么与原点重叠的值为0)同样由集合与结构元素完成。
公式:
公式解释:
注意:
A2 = imerode(A, se)
图像腐蚀应用:消除图像细节部分
编码:
f = imread('D:\数字图像处理\第九章学习\Fig0908(a).tif');
se = strel('disk', 10);
g = imerode(f, se);
se = strel('disk', 5);
g1 = imerode(f, se);
g2 = imerode(f, strel('disk', 20));
subplot(2,2,1), imshow(f);title('(a)原始图像的尺寸为480x480像素:');
subplot(2,2,2), imshow(g);title('(b)用半径为10的圆形腐蚀:');
subplot(2,2,3), imshow(g1);title('(c)用半径为5的圆形腐蚀:');
subplot(2,2,4), imshow(g2);title('(d)用半径为20的圆形腐蚀');
分析:
假设要除去图a中的细线,但想保留其他结构,可以选取足够小的结构元来匹配中心方块,但较粗的边缘线因太大而无法匹配全部线。图b几乎成功去掉了模板中的细线,图c中一些引线还没有去掉,图d中引线都被去掉了,但是边缘引线也丢失了,所以选取合适的结构元很重要。
开操作:
闭操作:
工具箱函数:
开操作:
C = imopen(A, B)
闭操作:
C = imclose(A, B)
A为二值图像,B为0,1矩阵组成,并且是指定结构元素。
函数imopen 和 imclose 的应用:
编码:
f = imread('D:\数字图像处理\第九章学习\Fig0910(a).tif');
se = strel('square', 40);
fo = imopen(f, se);
fc = imclose(f, se);
foc = imclose(fo, se);
subplot(2,2,1), imshow(f), title('(a)原图');
subplot(2,2,2), imshow(fo), title('(b)开操作');
subplot(2,2,3), imshow(fc), title('(c)闭操作');
subplot(2,2,4), imshow(foc), title('(d) (b)的闭操作结果');
分析:
噪声滤波器:
先开操作再闭操作,构成噪声滤波器。
编码:
f = imread('D:\数字图像处理\第九章学习\Fig0911(a).tif');
se = strel('square', 6);
fo = imopen(f, se);
foc = imclose(fo, se);
subplot(1,3,1), imshow(f), title('(a)带噪声的指纹图像');
subplot(1,3,2), imshow(fo), title('(b)图像的开操作');
subplot(1,3,3), imshow(foc), title('(c)先用开操作,再用闭操作');
击中击不中变换(HMT),HMT变换可以同时探测图像的内部和外部。研究解决目标图像识别和模式识别等领域,在处理目标图像和背景的关系上能够取得更好的效果。
作用:形状检测的基本工具。
公式:
B1是由与一个对象相联系的B元素构成的集合,B1是由与一个对象相联系的B元素构成的集合。
图解:
工具箱函数:
C = bwhitmiss(A, B1, B2)
其中的 C为结果,A为输入图像,B1、B2表示结构元素。
定位图像中物体左上角的像素:
编码:
f = imread('D:\数字图像处理\第九章学习\Fig0913(a).tif');
B1 = strel([0 0 0;0 1 1; 0 1 0]);
B2 = strel([1 1 1;1 0 0;1 0 0]);
g = bwhitmiss(f,B1,B2);
subplot(1,2,1), imshow(f), title('(a)原始图像');
subplot(1,2,2), imshow(g), title('(b)击中、击不中变换的结果');
分析:
工具箱函数 bwmorph 执行许多以膨胀、腐蚀和查找表运算相结合为基础的形态学操作, 调用语法为:
g = bwmorph(f, operation, n);
f 是输入的二值图像,operation 是指定所希望运算的字符串,n 是指定重复次数的正整数。
细化:
f = imread('D:\数字图像处理\第九章学习\Fig0911(a).tif');
g1 = bwmorph(f, 'thin',1);
g2 = bwmorph(f, 'thin',2);
ginf = bwmorph(f,'thin', Inf);
subplot(1,4,1),imshow(f);title('(a)指纹图像:');
subplot(1,4,2),imshow(g1);title('(b)细化一次后的指纹图像:');
subplot(1,4,3),imshow(g2);title('(c)细化两次后的图像:');
subplot(1,4,4),imshow(ginf);title('(d)一直细化到稳定状态的图像:');
f = imread('D:\数字图像处理\第九章学习\Fig0916(a).tif');
fs = bwmorph(f,'skel',Inf);
for k = 1:5
fa = fs & ~endpoints(fs);
end
subplot(1,3,1),imshow(f);title('(a)骨头图像:');
subplot(1,3,2),imshow(fs);title('(b)使用函数 bwmorph 得到的骨豁:');
subplot(1,3,3),imshow(fa);title('(c)使用函数 endpoint 裁剪后的骨豁:');
分析:骨骼化(Gonzalez和 Woods[2008])是另一种减少二值图像中的物体为一组细“笔画”的方法, 这些细骨豁仍保留原始物体形状的重要信息。当 operation 置为 'skel '时,函数 bwmorph 执行骨骼化。令 f 代表图(a)中类似骨头的图像,为了计算骨骼,调用 bwmorph, 令 n=Inf,图(b)显示了骨骼化的结果,与物体的基本形状相似。骨骼化和细化经常产生短的无关的“毛刺” ,有时这被叫做寄生成分。清除(或除去)这些“毛刺”的处理称为裁剪。方法是反复确认并去除端点。通过 5 次去除端点的迭代,得以后处理骨骼化图像 fs,图(c )显示了结果。
工具箱函数:
[L, num] = bwlabel (f, conn)
f 是输入二值图像,coon指定希望的连接方式(不是4连接就是8连接),输出L叫做标记矩阵,函数num则给出找到的连通分量总数。
计算和显示连通分量的质心:
f = imread('D:\数字图像处理\第九章学习\Fig0917(a).tif');
imshow(f);title('(a)标注连通分量原始图像:');
[L,n]=bwlabel(f); %L为标记矩阵,n为找到连接分量的总数
[r,c]=find(L==3); %返回第3个对象所有像素的行索引和列索引
rbar=mean(r);
cbar=mean(c);
figure,imshow(f);title('(b)标记所有对象质心后的图像:');
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(cbar,rbar,'Marker','*','MarkerFaceColor','w'); %其中的marker为标记
end
概述:重构是一种涉及到两幅图像和一个结构元素的形态学变换。一幅图像,即标记,是变换的开始点。另一幅图像是掩膜,用来约束变换过程。结构元素用于定义连接性。
定义:若G是掩膜,f为标记,则从f重构g可以记为 R g R_g Rg(f),由下列的迭代过程定义:
函数:
out = imreconstruct(marker,mask)
masker是标记,mask是掩膜。
在形态学开操作中,腐蚀典型地去除小的物体,且随后的膨胀趋向于恢复保留的物体形状。 然而,这种恢复的精确度取决于形状和结构元之间的相似性。本节讨论的方法,通过重建进行开操作能准确地恢复腐蚀之后的物体形状。用结构元B对图像 G通过重建进行开操作可定义为 :
f = imread('D:\数字图像处理\第九章学习\Fig0917(a).tif');
subplot(3,2,1),imshow(f);title('(a)重构原始图像');
fe=imerode(f,ones(51,1));%竖线腐蚀
subplot(3,2,2),imshow(fe);title('(b)使用竖线腐蚀后的结果');
fo=imopen(f,ones(51,1));%竖线做开运算
subplot(3,2,3),imshow(fo);title('(c)使用竖线做开运算结果');
fobr=imreconstruct(fe,f);%fe做标记
subplot(3,2,4),imshow(fobr);title('(d)使用竖线做重构开运算');
ff=imfill(f,'holes');%对f进行孔洞填充
subplot(3,2,5),imshow(ff);title('(e)对f填充孔洞后的图像');
fc=imclearborder(f,8);%清除边界,2维8邻接
subplot(3,2,6),imshow(fc);title('(f)对f清除边界后的图像');
令I表示二值图像,假设我们选择标记图像F,除了图像边缘外,其余部分都为 0, 边缘部分设值为 1-I:
函数:
g = imfill(f,‘holes’);
定义标记图像F为:
其中,/是原始图像,然后以/作为模板图像,重建
得到一幅图像H, 其中仅包含与边界接触的物体。
函数:
g = imclearborder(f,conn)
f 是输入图像,g 是结果。conn 的值不是 4 就是 8(默认)。 物体更亮且与图像边界相连接的结构。
灰度图像的形态学梯度定义为膨胀运算与腐蚀运算的结果之间的差值。
膨胀定义:
腐蚀定义:
膨胀和腐蚀操作:
编写代码:
f = imread('D:\数字图像处理\第九章学习\Fig0923(a).tif');
se=strel('square',3); %构造了一个平坦的3x3的结构元素
gd=imdilate(f,se); %对原图像进行膨胀操作
ge=imerode(f,se); %对原图像进行腐蚀操作
morph_grad=imsubtract(gd,ge); %从膨胀的图像中减去腐蚀过得图像产生一个形态学梯度。
subplot(3,2,1);imshow(f,[]);title('(a)原始图像');
subplot(3,2,2),imshow(gd,[]);title('(b)膨胀的图像');
subplot(3,2,3),imshow(ge,[]);title('(c)腐蚀的图像');
subplot(3,2,4),imshow(morph_grad,[]);title('(d)形态学梯度');
图像开运算:
图像闭运算:
用开操作和闭操作做形态学平滑 :
f = imread('D:\数字图像处理\第九章学习\Fig0925(a).tif');
subplot(3,2,1),imshow(f);
title('(a)木钉图像原图');
se=strel('disk',5); %disk其实就是一个八边形
fo=imopen(f,se); %经过开运算
subplot(3,2,2),imshow(f);
title('(b)使用半径5的disk开运算后的图像');
foc=imclose(fo,se);
subplot(3,2,3),imshow(foc);
title('(c)先开后闭的图像');
focd=imclose(f,se);
subplot(3,2,4),imshow(focd);
title('(d)原始图像的闭操作');
foce=imopen(focd,se);
subplot(3,2,5),imshow(foce);
title('(e)先闭后开的图像');
fasf=f;
for i=2:5
se=strel('disk',i);
fasf=imclose(imopen(fasf,se),se);
end
subplot(3,2,6),imshow(fasf);
title('(f)使用开闭交替滤波后图像');
非均匀背景的补偿 :
f = imread('D:\数字图像处理\第九章学习\Fig0926(a).tif');
g = f>=(255*graythresh(f));
se=strel('disk',100);
fo=imopen(f,se);
f2=imsubtract(f,fo);
g1 = f2>=(255*graythresh(f2));
subplot(2,3,1),imshow(f);
title('(a)原始图像');
subplot(2,3,2),imshow(g);
title('(b)经过阈值处理后的图像');
subplot(2,3,3),imshow(f);
title('(c)原图开运算后的图像');
subplot(2,3,4),imshow(f2);
title('(d)原图减去开运算');
subplot(2,3,5),imshow(g1);
title('(e)最终结果');
粒度测定 :
颗粒分析:形态学技术可以用与间接地度量颗粒的大小分布,但不能准确地识别每一个颗粒。对于形状规则且亮于背景大的颗粒,基本方法是应用不断增大尺寸的形态学开运算。
f = imread('D:\数字图像处理\第九章学习\Fig0926(a).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('(a)表面积和结构元素半径之间的关系');
figure,plot(-diff(sumpixels));%diff()函数为差分或者近似倒数,即相邻2个之间的差值
xlabel('k'),ylabel('surface area reduction');
title('(b)减少的表面积和结构元素半径之间的关系');
分析:
重建:
重建移去复杂的背景 :
f = imread('D:\数字图像处理\第九章学习\Fig0930(a).tif');
subplot(3,3,1),imshow(f);
title('(a)原图像');
f_obr=imreconstruct(imerode(f,ones(1,71)),f);
subplot(3,3,2),imshow(f_obr);
title('(b)重建的开操作');
f_o=imopen(f,ones(1,71));
subplot(3,3,3),imshow(f_o);
title('(c)开操作');
f_thr=imsubtract(f,f_obr); %顶帽重构
subplot(3,3,4),imshow(f_thr);
title('(d)重建的顶帽操作');
f_th=imsubtract(f,f_o) %标准顶帽运算,方便比较
subplot(3,3,5),imshow(f_th);
title('(e)顶帽操作');
g_obr=imreconstruct(imerode(f_thr,ones(1,11)),f_thr);
subplot(3,3,6),imshow(g_obr);
title('(f)用水平线对(b)经开运算后重建图');
g_obrd=imdilate(g_obr,ones(1,2));
subplot(3,3,7),imshow(g_obrd);
title('(g)使用水平线对(f)进行膨胀');
f2=imreconstruct(min(g_obrd,f_thr),f_thr);
subplot(3,3,8),imshow(f2);
title('(h)最后的重建结果');
为了消除每个键盘上方的水平反射光,利用这些反射比图像中任何文本字符都要宽的这个事实。用长水平线的结构元执行重建的开操作,重建的开操作(f_obr) 显示于图(b)中。为了进行对比,图(c )显示了标准的开操作 (f_o) 。重建的开操作在提取水平的相邻键之间的背景方面的确较好。从原始图像中减去重建的开操作被称为顶帽重建 , 结果示于图 (d)中。消除图 (d)中键右边的垂直反射光。这可以通过用短的水平线执行重建的开操作来完成,在这个结果中(见图 (f)),垂直的反射光不见了。但是,包括字母的垂直的细笔画也不见了。我们利用了那些已被错误消除的字母非常接近第一次膨胀(见图 (g))后还存在的其他字符这一事实,以 f_thr 作为模板,以 min(g_obrd,f_thr) 作为标记,图 (h)显示了最后的结果。注意,背景上键盘的阴影和反射光都成功去除了。