武汉大学形态学处理实习报告.docx
- 文档编号:30228709
- 上传时间:2023-08-07
- 格式:DOCX
- 页数:45
- 大小:467.13KB
武汉大学形态学处理实习报告.docx
《武汉大学形态学处理实习报告.docx》由会员分享,可在线阅读,更多相关《武汉大学形态学处理实习报告.docx(45页珍藏版)》请在冰豆网上搜索。
武汉大学形态学处理实习报告
图像形态学处理程序设计报告
班级:
姓名:
学号:
指导老师:
武汉大学遥感信息工程学院
摘要:
形态学运算是针对二值图像依据数学形态学集合论方法发展起来的图像处理方法。
数学形态学以图像的形态特征为研究对象,描述图像的基本特征和基本结构。
通常形态学图像处理表现为一种邻域运算形式,在每个像素位置上邻域结构元素上进行特定的逻辑运算。
数学形态学的运算以腐蚀和膨胀为基础,引出了其他几个常用的数学形态运算。
最常用的基本运算有7种,分别为:
腐蚀、膨胀、开运算、闭运算、击中、细化和粗化,它们是全部形态学的基础。
关键词:
VC++,形态学处理,腐蚀,膨胀,开运算,闭运算,细化,边界提取
一、原理介绍
1.1.图像腐蚀
腐蚀是数学形态学的两种最为基本的运算之一,腐蚀在数学形态学中的作用是消除物体边界点,使边界向内部收缩的过程,可以把小于结构元素的物体去除。
这样选取不同大小的结构元素,就可以去除不同大小的物体。
如两个物体间有细小的连通,通过腐蚀可以将两个物体分开。
腐蚀的数学表达式是:
在公式中S表示腐蚀后的二值图像集合,B表示用来进行腐蚀的结构元素,结构元素可以组成任何一种形状的图形,在B图形中有一个中心点。
此公式的含义是用B来腐蚀X得到集合S,S是由B完全包括在X中时B的当前位置的集合。
通常是拖动结构元素在X图像域移动,横向移动间隔取1个像素,纵向间隔取1个扫描行。
在每一个位置上,当结构元素B的中心点平移到X图像上的某一点(x,y),如果结构元素内的每一个像素都与以(x,y)为中心的相同邻域中对应像素完全相同,那么就保留(x,y)像素点,对于原图不满足条件的像素点则全部删除,从而达到使物体边界向内收缩的效果。
1.2.图像膨胀
膨胀是数学形态学中除腐蚀之外的另一种基本运算。
膨胀在数学形态学中的作用与腐蚀的作用正好相反,它是对二值化物体边界点进行扩充,将与物体接触的所有背景点合并到该物体中,使边界向外部扩张的过程。
如果两个物体之间的距离比较近,则膨胀运算可能会把两个物体连通到一起,膨胀对填补图像分割后物体中的空洞很有用。
膨胀的数学表达式是:
这公式中S表示膨胀后的二值图像集合,B表示用来进行膨胀的结构元素,结构元素内的每一个元素取值为0或1,它可以组成任何一种形状的图形,在图形中有一个中心点;X表示原图像经过二值化后的像素集合。
此公式的含义是用B来膨胀X得到的集合S,S是由B映像的位移与X至少有一个像素相同时B的中心点位置的集合。
通畅是拖动结构元素在X图像域移动,横向移动间隔取一个像素,纵向移动间隔取一个扫描行。
在每一个位置上,当结构元素B的中心点平移到X图像上的某一点(x,y),如果结构元素的像素与目标物体至少有一个像素香蕉,那么就保留(x,y)像素点,从而达到使物体边界向外扩张的效果。
1.3.图像开运算
腐蚀和膨胀两种操作不具有互逆的关系。
开运算和闭运算正是依据腐蚀和膨胀的不可逆性演变而来的。
先腐蚀后膨胀的过程就成为开运算。
原图经过开运算后,能够去除孤立的小点、毛刺和小桥(即连通两块区域的小点),消除小物体、平滑较大物体的边界,同时并不明显改变其面积。
开运算的数学表达式是:
在公式中S表示进行开运算后的二值图像集合,B表示用来进行开运算的结构元素,结构元素内的每一个元素取值为0或1,它可以组成任何一种形状的图形,在图形中有一个中心点;X表示原图像经过二值化后的像素集合。
此公式的含义是用B来开启X得到的集合S,S是所有这集合结构上不小于结构元素B的部分集合,也就是选出了X种的某些与B相匹配的点,而这些点则可以通过完全包含这X中的结构元素B的平移来得到。
1.4.图像闭运算
闭运算是通过对腐蚀和膨胀的另一种不同次序的执行而得到的,闭运算是先膨胀后腐蚀的过程,其功能是用来填充物体内细小空洞、连接邻近物体、平滑其边界,同时不明显改变其面积。
开运算的数学表达式是:
在公式中S表示进行闭运算后的二值图像集合,B表示用来进行闭运算的结构元素,结构元素内的每一个元素取值为0或1,它可以组成任何一种形状的图形,在图形中有一个中心点;X表示原图像经过二值化后的像素集合。
此公式的含义是用B来闭合X得到的集合S,就是图像X与经过映射和平移的结构元素B的交集不为空的点的集合。
1.5.图像细化
对图像细化的过程实际上是求以图像骨架的过程。
骨架是二维二值目标的重要拓扑描述,它是指图像中央的骨骼部分,是描述图像几何及拓扑性质的重要特征之一。
骨架形状描述的方法是Blum最先提出来的,他使用的是中轴的概念。
如果用一个形象的比喻来说明骨架的含义,那就是设想在t=0的时刻,将目标的边界各处同时点燃,火焰以匀速向目标内部蔓延,当火焰的前沿相交时火焰熄灭,那么火焰熄灭点的集合就构成了中轴,也就是图像的骨架。
例如一个长方形的骨架是它的长方向上的中轴线,正方形的骨架是它的中心点,园的骨架是它的圆心,直线的骨架是它自身,孤立点的骨架也是自身。
细化的目的就是在将图像的骨架提取出来的同时保持图像细小部分的连通性,特别是在文字识别,地质识别,工业零件识别或图像理解中,先对被处理图像进行细化有助于突出形状特点和减少冗余信息量。
细化的数学表达式为:
式中↑表示的是击中击不中变换,S是二值图像进行细化后的像素集合,B表示用来进行细化运算的结构元素,结构元素内的每一个元素取值为0或1,它可以组成任何一种形状的图形,在图形中有一个中心点;X表示原图像经过二值化后的像素集合。
此公式的含义是用B来细化X得到的集合S,S是X的全部像素点除去击中击不中变换结果后的集合。
在细化一副图像X的过程中应满足两个条件:
第一,在细化的过程中,X应该有规律地缩小;第二,在X逐步缩小的过程中,应当使X的连通性质保持不变。
1.6.边界提取
对图像进行边界提取就是将图像的内部点删除,只留下图像的边界。
二、算法设计
2.1.图像腐蚀
图中示意了用结构元素B(如图(b)所示)对目标图像X(如图(a)所示)进行腐蚀运算并得到运算结果(如图(c)所示)的过程。
图(a)中白色的部分代表背景,灰色的部分代表目标图像X。
图(b)中黑色的方格代表结构元素的中心点,灰色的方格代表邻域。
图(c)中黑色的部分表示腐蚀后的结果,灰色的部分表示目标图像被腐蚀掉的部分。
在腐蚀处理过程中,将结构元素在图像中移动,如果结构元素完全包含在目标图像X中,则保留目标图像中对应于中心点的像素点,否则删除像素点。
腐蚀实际上是把图像的外围去掉,同时保留图像内部的部分。
2.1.1.水平腐蚀
水平腐蚀的原理同上面介绍的相同,只是使用的结构元素不同,水平腐蚀所用的结构元素是1×3的结构。
2.1.2.垂直腐蚀
垂直腐蚀的原理同上面介绍的相同,只是使用的结构元素不同,垂直腐蚀所用的结构元素是3×1的结构。
2.1.3.全方向腐蚀
全方向腐蚀的原理同上面介绍的相同,只是使用的结构元素不同,全方向腐蚀所用的结构元素是3×3的结构。
2.2.图像膨胀
图中示意了用结构元素B(如图(b)所示)对目标图像X(如图(a)所示)进行膨胀运算并得到运算结果(如图(c)所示)的过程。
图(a)中白色的部分代表背景,灰色的部分代表目标图像X。
图(b)中黑色的方格代表结构元素的中心点,灰色的方格代表邻域。
图(c)中灰色的部分表示原目标图像,黑色的部分表示膨胀出来的结果。
在膨胀处理过程中,将结构元素在图像中移动,如果结构元素的邻域与目标图像X有部分重合,则保留图像中对应于中心点的像素点。
膨胀实际上是把图像的外围扩充了一圈,同时保留图像内部的部分。
2.2.1.水平膨胀
水平膨胀的原理同上面介绍的相同,只是使用的结构元素不同,水平膨胀所用的结构元素是1×3的结构。
2.2.2.垂直膨胀
垂直膨胀的原理同上面介绍的相同,只是使用的结构元素不同,垂直膨胀所用的结构元素是3×1的结构。
2.2.3.全方向膨胀
全方向膨胀的原理同上面介绍的相同,只是使用的结构元素不同,全方向膨胀所用的结构元素是3×3的结构。
2.3.图像开运算
如图,左边是被处理的二值图像,针对的是黑点,中间是结构元素B,那个标有1的点是中心点,即当前处理元素的位置,拿B的中心点和X上的点一个一个地对比。
对于腐蚀运算:
如果B上的所有点都在X的范围内,则该点保留,否则将该点去掉。
对于膨胀运算:
如果B上有一个点落在X的范围内,则该点就为黑。
可以看到,当使用圆盘结构元素时,开运算对边界进行了平滑,去掉凸角。
在凸角点周围,图像的集合结构无法容纳给定圆盘,从而使凸角点被开运算删除。
而当使用线段结构元素沿线段宽度方向较大的部分才能够保存下来。
而较小的凸部分将被删除。
因此,经过开运算后,能够去除孤立的小点,毛刺和小桥,平滑较大物体的边界,同时并不明显改变其面积。
2.4.图像闭运算
如图,左边是被处理的二值图像,针对的是黑点,右边是结构元素B,左边是膨胀后的结果,右边是在此基础上腐蚀的结果,可以看到,原图经过闭运算后,断裂的地方被弥合了。
一般来说,闭运算能够填平小湖(即小孔),弥合小裂缝,而总的置和形状不变。
这就是闭运算的作用。
2.5.图像细化
判断一个像素点这细化过程中是否可以删除,应该和该点周围8邻域内的其他8个点综合来判断。
通过数学逻辑计算,设置一个5×5的邻域S模板,如图所示,S模板中各个位置上的取值取决于模板所对应图像中不同像素位置,如果S模板某一个位置上所对应的像素值为白,则模板上该位置赋为0,否则为1。
我们总结出了4个条件来判断像素点是否可以删除,当像素点同时满足这4个条件时,这个点就可以删除。
这4个条件是:
N(s[2][2])表示以s[2][2]为中心的3×3邻域内目标像素(即黑点)的个数。
取其中的3×3邻域以s[2][2]为中心点,则T(s[2][2])表示序列:
s[1][2]s[1][1]s[2][1]s[3][1]s[3][2]s[3][3]s[2][3]s[1][3]s[1][2]中0->1的变化次数。
取其中的3×3邻域以s[1][2]为中心点,则T(s[1][2])表示序列:
s[0][2]s[0][1]s[1][1]s[2][1]s[2][2]s[2][3]s[1][3]s[0][3]s[0][2]中0->1的变化次数。
取其中的3×3邻域以s[2][1]为中心点,则T(s[2][1])表示序列:
S[1][1]s[1][0]s[2][0]s[3][0]s[3][1]s[3][2]s[2][2]s[1][2]s[1][1]中0->1的变化次数。
条件1:
2≤N(s[2][2])≤6;
条件2:
T(s[2][2])=1;
条件3:
s[1][2]*s[2][1]*s[2][3]=0同时T(s[1][2])!
=1;
条件4:
s[1][2]*s[2][1]*s[3][2]=0同时T(s[2][1])!
=1;
如果同时满足以上4个条件,则删除该点,否则保留像素点,重复判断像素点直至没有点可以删除。
细化过程就是判断每一个二值化的图像像素点是否满足以上4个条件,满足则删除该点,重复判断直至所有点都不能删除为止。
2.6.边界提取
对目标图像每一个像素点进行扫描,扫描周围3×3邻域内是否有背景点(即白色像素点),如果有,说明该点是边界点,保留像素点,否则删除该点,重复判断直至所有点都扫描位置。
三、实现方法与过程
3.1.图像腐蚀
3.1.1.水平腐蚀
(1)获得原图像的首地址几图像的宽和高;
(2)开辟一块内存缓冲区;
(3)用1×3的结构元素扫描每个点,为防止越界,最左边和最右边像素不做处理,将1×3邻域内的像素最大值赋给检查的像素点,并且暂时存在内存缓冲区;
(4)将缓冲区数据拷贝到原始图像数据区;
(5)释放缓冲区,并刷新视图显示。
核心代码:
voidCXcView:
:
OnErosionHorizontal()
{
//TODO:
Addyourcommandhandlercodehere
CXcDoc*pDoc=GetDocument();
ASSERT_VALID(pDoc);
if(pDoc->hDib==NULL)
{
AfxMessageBox("请先打开图像!
");
return;
}
nReoperation=1;
LPSTRp=(LPSTR)LocalLock(pDoc->hDib);
BYTE*pData=(BYTE*)FindDIBBits(p);
LONGWidth=DIBWidth(p);
LONGHeight=DIBHeight(p);
LONGLineBytes=(Width*8+31)/32*4;
DataBack[nBack]=newBYTE[Width*Height];
memcpy(DataBack[nBack],pData,Width*Height);
nBack++;
BYTE*DataCopy=newBYTE[LineBytes*Height];
inti,j,nMax;
//求取1*3范围最大值,赋给待处理像素
for(i=0;i for(j=1;j { nMax=pData[LineBytes*i+j-1]; for(intp=0;p<2;p++) { if(nMax nMax=pData[LineBytes*i+j+p]; } DataCopy[LineBytes*i+j]=(BYTE)nMax; } for(i=0;i for(j=1;j { pData[LineBytes*i+j]=DataCopy[LineBytes*i+j]; } delete[]DataCopy; Invalidate(); } 3.1.2.垂直腐蚀 (1)获得原图像的首地址几图像的宽和高; (2)开辟一块内存缓冲区; (3)用3×1的结构元素扫描每个点,为防止越界,最上边和最下边像素不做处理,将3×1邻域内的像素最大值赋给检查的像素点,并且暂时存在内存缓冲区; (4)将缓冲区数据拷贝到原始图像数据区; (5)释放缓冲区,并刷新视图显示。 核心代码: voidCXcView: : OnErosionVertical() { //TODO: Addyourcommandhandlercodehere CXcDoc*pDoc=GetDocument(); ASSERT_VALID(pDoc); if(pDoc->hDib==NULL) { AfxMessageBox("请先打开图像! "); return; } nReoperation=2; LPSTRp=(LPSTR)LocalLock(pDoc->hDib); BYTE*pData=(BYTE*)FindDIBBits(p); LONGWidth=DIBWidth(p); LONGHeight=DIBHeight(p); LONGLineBytes=(Width*8+31)/32*4; DataBack[nBack]=newBYTE[Width*Height]; memcpy(DataBack[nBack],pData,Width*Height); nBack++; BYTE*DataCopy=newBYTE[LineBytes*Height]; inti,j,nMax; //求取3*1范围最大值,赋给待处理像素 for(i=1;i for(j=0;j { nMax=pData[LineBytes*(i-1)+j]; for(intp=0;p<2;p++) { if(nMax nMax=pData[LineBytes*(i+p)+j]; } DataCopy[LineBytes*i+j]=(BYTE)nMax; } for(i=1;i for(j=0;j { pData[LineBytes*i+j]=DataCopy[LineBytes*i+j]; } delete[]DataCopy; Invalidate(); } 3.1.3.全方向腐蚀 (1)获得原图像的首地址几图像的宽和高; (2)开辟一块内存缓冲区; (3)用3×3的结构元素扫描每个点,为防止越界,边界像素不做处理,将3×3邻域内的像素最大值赋给检查的像素点,并且暂时存在内存缓冲区; (4)将缓冲区数据拷贝到原始图像数据区; (5)释放缓冲区,并刷新视图显示。 核心代码: voidCXcView: : OnErosionOmnidirectional() { //TODO: Addyourcommandhandlercodehere CXcDoc*pDoc=GetDocument(); ASSERT_VALID(pDoc); if(pDoc->hDib==NULL) { AfxMessageBox("请先打开图像! "); return; } nReoperation=3; LPSTRp=(LPSTR)LocalLock(pDoc->hDib); BYTE*pData=(BYTE*)FindDIBBits(p); LONGWidth=DIBWidth(p); LONGHeight=DIBHeight(p); LONGLineBytes=(Width*8+31)/32*4; DataBack[nBack]=newBYTE[Width*Height]; memcpy(DataBack[nBack],pData,Width*Height); nBack++; BYTE*DataCopy=newBYTE[LineBytes*Height]; inti,j,nMax; //求取3*3范围最大值,赋给待处理像素 for(i=1;i for(j=1;j { nMax=0; for(intp=0;p<3;p++) for(intq=0;q<3;q++) { if(nMax nMax=pData[LineBytes*(i+p-1)+j+q-1]; } DataCopy[LineBytes*i+j]=(BYTE)nMax; } for(i=1;i for(j=1;j { pData[LineBytes*i+j]=DataCopy[LineBytes*i+j]; } delete[]DataCopy; Invalidate(); } 3.2.图像膨胀 3.2.1.水平膨胀 (1)获得原图像的首地址几图像的宽和高; (2)开辟一块内存缓冲区; (3)用1×3的结构元素扫描每个点,为防止越界,最左边和最右边像素不做处理,将1×3邻域内的像素最小值赋给检查的像素点,并且暂时存在内存缓冲区; (4)将缓冲区数据拷贝到原始图像数据区; (5)释放缓冲区,并刷新视图显示。 核心代码: voidCXcView: : OnDilationHorizontal() { //TODO: Addyourcommandhandlercodehere CXcDoc*pDoc=GetDocument(); ASSERT_VALID(pDoc); if(pDoc->hDib==NULL) { AfxMessageBox("请先打开图像! "); return; } nReoperation=4; LPSTRp=(LPSTR)LocalLock(pDoc->hDib); BYTE*pData=(BYTE*)FindDIBBits(p); LONGWidth=DIBWidth(p); LONGHeight=DIBHeight(p); LONGLineBytes=(Width*8+31)/32*4; DataBack[nBack]=newBYTE[Width*Height]; memcpy(DataBack[nBack],pData,Width*Height); nBack++; BYTE*DataCopy=newBYTE[LineBytes*Height]; inti,j,nMin; //求取1*3范围最小值,赋给待处理像素 for(i=0;i for(j=1;j { nMin=pData[LineBytes*i+j-1]; for(intp=0;p<2;p++) { if(nMin>pData[LineBytes*i+j+p]) nMin=pData[LineBytes*i+j+p]; } DataCopy[LineBytes*i+j]=(BYTE)nMin; } for(i=0;i for(j=1;j { pData[LineBytes*i+j]=DataCopy[LineBytes*i+j]; } delete[]DataCopy; Invalidate(); } 3.2.2.垂直膨胀 (1)获得原图像的首地址几图像的宽和高; (2)开辟一块内存缓冲区; (3)用3×1的结构元素扫描每个点,为防止越界,最上边和最下边像素不做处理,将3×1邻域内的像素最小值赋给检查的像素点,并且暂时存在内存缓冲区; (4)将缓冲区数据拷贝到原始图像数据区; (5)释放缓冲区,并刷新视图显示。 核心代码: voidCXcView: : OnDilationVertical() { //TODO: Addyourcommandhandlercodehere CXcDoc*pDoc=GetDocument(); ASSERT_VALID(pDoc); if(pDoc->hDib==NULL) { AfxMessageBox("请先打开图像! "); return; } nReoperation=5; LPSTRp=(LPSTR)LocalLock(pDoc->hDib); BYTE*pData=(BYTE*)FindDIBBits(p); LONGWidth=DIBWidth(p); LONGHeight=DIB
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 武汉大学 形态学 处理 实习 报告