分享
分销 收藏 举报 申诉 / 26
播放页_导航下方通栏广告

类型第6章 腐蚀,膨胀,细化算法.pdf

  • 上传人:曲****
  • 文档编号:4901643
  • 上传时间:2024-10-18
  • 格式:PDF
  • 页数:26
  • 大小:1.13MB
  • 下载积分:11 金币
  • 播放页_非在线预览资源立即下载上方广告
    配套讲稿:

    如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。

    特殊限制:

    部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。

    关 键  词:
    第6章 腐蚀 膨胀 细化算法 腐蚀 膨胀 细化 算法
    资源描述:
    第6章腐蚀,膨胀,细化算法这一章的内容我认为是最有趣的。还记得前言中那个抽取骨架的例子吗?现在我们就来看看它是如何实现的。今天所讲的内容属于一门新兴的学科:数学形态学(MathematicalMorphology)。说起来很有意思,它是法国和德国的 科学家在研究岩石结构时建立的一门学科。形态学的用途主要是获取物体拓扑和结构信息,它通过物体和结构元素 相互作用的某些运算,得到物体更本质的形态。在图象处理中的应用主要是:(1)利用形态学的基本运算,对图象进 行观察和处理,从而达到改善图象质量的目的;(2)描述和定义图象的各种几何参数和特征,如面积、周长、连通度、颗粒度、骨架和方向性等。限于篇幅,我们只介绍二值图象的形态学运算,对于灰度图象的形态学运算,有兴趣的读者可以阅读有关的参考书。在程序中,为了处理的方便,还是采用256级灰度图,不过只用到了调色板中的。和255两项。先来定义一些基本符号和关系。1.元素 设有一幅图象X,若点a在X的区域以内,则称a为X的元素,记作aX,如图6.1所示。2.B包含于X设有两幅图象B,Xo对于B中所有的元素ai,都有aiX,则称B包含于(included in)X,记作B匚X,如图6.2所03.B击中X设有两幅图象B,Xo若存在这样一个点,它即是B的元素,又是X的元素,则称B击中(hit)X,记作BTX,如图 6.3所示。4.B不击中X设有两幅图象B,Xo若不存在任何一个点,它即是B的元素,又是X的元素,即B和X的交集是空,则称B不击 中(miss)X,记作BAX=;其中G是集合运算相交的符号,表示空集。如图6.4所示。图6.3 击中图6.4 不击中5.补集设有一幅图象X,所有X区域以外的点构成的集合称为X的补集,记作X。,如图6.5所示。显然,如果BAX二,则B在X的补集内,即B CXco6.结构元素设有两幅图象B,Xo若X是被处理的对象,而B是用来处理X的,则称B为结构元素(structure element),又被形 象地称做刷子。结构元素通常都是一些比较小的图象。7.对称集设有一幅图象B,将B中所有元素的坐标取反,即令(x,y)变成(-X,-y),所有这些点构成的新的集合称为B的对称 集,记作B,如图6.6所示。8.平移设有一幅图象B,有一个点a(xo,y。),将B平移a后的结果是,把B中所有元素的横坐标加x0,纵坐标加y,即令(x,y)变成(x+xo,y+yo),所有这些点构成的新的集合称为B的平移,记作Ba,如图6.7所示。图6.6 对称集的示意图 图6.7 平移的示意图好了,介绍了这么多基本符号和关系,现在让我们应用这些符号和关系,看一下形态学的基本运算。6.1腐蚀 把结构元素B平移a后得到Ba,若Ba包含于X,我们记下这个a点,所有满足上述条件的a点组成的集合称做X被 B腐蚀(Erosion)的结果。用公式表示为:E(X)=al Ba CX=X B,如图6.8所示。图6.8 腐蚀的示意图图6.8中X是被处理的对象,B是结构元素。不难知道,对于任意一个在阴影部分的点a,Ba包含于X,所以X被 B腐蚀的结果就是那个阴影部分。阴影部分在X的范围之内,且比X小,就象X被剥掉了一层似的,这就是为什么 叫腐蚀的原因。值得注意的是,上面的B是对称的,即B的对称集BJB,所以X被B腐蚀的结果和X被B腐蚀的结果是一样的。如果B不是对称的,让我们看看图6.9,就会发现X被B腐蚀的结果和X被腐蚀的结果不同。图6.9 结构元素非对称时,腐蚀的结果不同图6.8和图6.9都是示意图,让我们来看看实际上是怎样进行腐蚀运算的。在图6.10中,左边是被处理的图象X(二值图象,我们针对的是黑点),中间是结构元素B,那个标有origin的点是中 心点,即当前处理元素的位置,我们在介绍模板操作时也有过类似的概念。腐蚀的方法是,拿B的中心点和X上的点一个一个地对比,如果B上的所有点都在X的范围内,则该点保留,否则将该点去掉;右边是腐蚀后的结果。可 以看出,它仍在原来X的范围内,且比X包含的点要少,就象X被腐蚀掉了一层。图6.10腐蚀运算图6.11为原图,图6.12为腐蚀后的结果图,能够很明显地看出腐蚀的效果。HiJm phoenix Glad to meet u.图6.11原图HiJm phoenix Glad to meet u.图6.12腐蚀后的结果图下面的这段程序,实现了上述的腐蚀运算,针对的都是黑色点。参数中有一个BOOL变量,为真时,表示在水平方T1.向进行腐蚀运算,即结构元素B为b1】;否则在垂直方向上进行腐蚀运算,即结构兀素B为。BOOL Erosion(HWND hWnd,BOOL Hori)(DWORD OffBits,BufSize;LPBITMAPINFOHEADER IpImgData;LPSTRIpPtr;HLOCALhTempImgData;LPBITMAPINFOHEADER IpTempImgData;LPSTRIpTempPtr;HDChDc;HFILEhf;LONGx,y;unsigned charnum;inti;为了处理方便,仍采用256级灰度图,不过只用调色板中0和255两项if(NumColors!=256)MessageBox(hWnd,Must be a mono bitmap with grayscale palette!*,Error Message,MB_OKIMB_ICONEXCLAMATION);return FALSE;)OffBits=bf.bfOffBits-sizeof(BITMAPHLEHEADER);/BufSize为缓冲区大小BufSize=OffBits+bi.biHeight*LineBytes;为新的缓冲区分配内存if(hTempImgData=LocalAlloc(LHND,BufSize)=NULL)(MessageBox(hWnd,HError alloc memory!1,Error Message,MB_OKIMB_ICONEXCLAMATION);return FALSE;lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData);lpTempImgData=(LPBITMAPINFOHEADER)LocalLock(hTempImgData);拷贝头信息和位图数据memcpy(lpTempImgData,lpImgData,BufSize);if(Hori)(在水平方向进行腐蚀运算for(y=0;ybi.biHeight;y+)/IpPtr指向原图数据,IpTempPtr指向新图数据 lpPtr=(char*)lpImgData+(BufSize-LineBytes-y*LineBytes)+1;lpTempPtr=(char*)lpTempImgData+(BufSize-LineBytes-y*LineBytes)+l;for(x=l;xbi.biWidth-l;x+)注意为防止越界,x的范围从1到宽度-2num=(unsigned char)*lpPtr;if(num=O)因为腐蚀掉的是黑点,所以只对黑点处理*lpTempPtr=(unsigned char)O;先置成黑点for(i=0;i3;i+)num=(unsigned char)*(lpPtr+i-l);if(num=255)自身及上下邻居中若有一个不是黑点,则将该点腐 蚀成白点*lpTempPtr=(unsigned char)255;break;原图中就是白点的,新图中仍是白点else*lpTempPtr=(unsigned char)255;指向下一个象素lpPtr+;lpTempPtr+;else(在垂直方向进行腐蚀运算for(y=l;yvbi.biHeight-l;y+)注意为防止越界,y的范围从1到高度-2/IpPtr指向原图数据,IpTempPtr指向新图数据lpPtr=(char*)lpImgData+(BufSize-LineBytes-y*LineBytes);lpTempPtr=(char*)lpTempImgData+(BufSize-LineBytes-y*LineBytes);for(x=0;xbi.biWidth;x+)num=(unsigned char)*lpPtr;if(num=O)因为腐蚀掉的是黑点,所以只对黑点处理*lpTempPtr=(unsigned char)O;/先置成黑点for(i=0;i3;i+)num=(unsigned char)*(lpPtr+(i-l)*LineBytes);if(num=255)自身及上下邻居中若有一个不是黑点,则将该点腐蚀成白点*lpTempPtr=(unsigned char)255;break;原图中就是白点的,新图中仍是白点else*lpTempPtr=(unsigned char)255;指向下一个象素lpPtr+;lpTempPtr+;if(hBitmap!=NULL)DeleteObj ect(hB itmap);hDc二GetDC(hWnd);产生新的位图hBitmap=CreateDIBitmap(hDc,(LPBITMAPINFOHEADER)lpTempImgData,(LONG)CBM_INIT,(LPSTR)lpTempImgData+sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD),(LPBITMAPINFO)lpTempImgData,DIB_RGB_COLORS);起不同的结果文件名if(Hori)hf=_lcreat(Hc:herosion.bmp,0);elsehf=_lcreat(Hc:verosion.bmp,0);write(hf,(LPSTR)&bf,sizeof(BITMAPFILEHEADER);_lwrite(hf,(LPSTR)lpTempImgData,BufSize);_lclose(hf);释放内存及资源ReleaseDC(hWnd,hDc);LocalUnlock(hTempImgData);LocalFree(hT empImgData);GlobalUnlock(hlmgData);return TRUE;)6.2膨胀膨胀(dilation)可以看做是腐蚀的对偶运算,其定义是:把结构元素B平移a后得到Ba,若Ba击中X,我们记下这个 a点。所有满足上述条件的a点组成的集合称做X被B膨胀的结果。用公式表示为:D(X)=a I Ba f X=X 0B,如 图6.13所示。图6.13中X是被处理的对象,B是结构元素,不难知道,对于任意一个在阴影部分的点a,Ba击中X,所以X被B膨胀的结果就是那个阴影部分。阴影部分包括X的所有范围,就象X膨胀了一圈似的,这就是为什么叫 膨胀的原因。同样,如果B不是对称的,X被B膨胀的结果和X被B膨胀的结果不同。让我们来看看实际上是怎样进行膨胀运算的。在图6.14中,左边是被处理的图象X 二值图象,我们针对的是黑点),中间是结构元素B。膨胀的方法是,拿B的中心点和X上的点及X周围的点一个一个地对,如果B上有一个点落在 X的范围内,则该点就为黑;右边是膨胀后的结果。可以看出,它包括X的所有范围,就象X膨胀了一圈似的。图6.13膨胀的示意图originX B X B图6.14膨胀运算图6.15为图6.11膨胀后的结果图,能够很明显的看出膨胀的效果。HiJm phoenix.Glad to meet u.图6.15图6.11膨胀后的结果图下面的这段程序,实现了上述的膨胀运算,针对的都是黑色点。参数中有一个BOOL变量,为真时,表示在水平方向进行膨胀运算,即结构元素B为I1力;否则在垂直方向上进行膨胀运算,即结构元素B为BOOL Dilation(HWND hWnd,BOOL Hori)(DWORD OffBits,BufSize;LPBITMAPINFOHEADER IpImgData;LPSTRIpPtr;HLOCALhTempImgData;LPBITMAPINFOHEADER IpTempImgData;LPSTRIpTempPtr;HDChDc;HFILEhf;LONGx,y;unsigned charnum;inti;为了处理的方便,仍采用256级灰度图,不过只调色板中。和255两项if(NumColors!=256)MessageBox(hWnd,Must be a mono bitmap with grayscale palette!,Error Message,MB_OKIMB_ICONEXCLAMATION);return FALSE;)OffBits=bf.bfOffBits-sizeof(BITMAPHLEHEADER);/BufSize为缓冲区大小BufSize=OffBits+bi.biHeight*LineBytes;为新的缓冲区分配内存if(hTempImgData=LocalAlloc(LHND,BufSize)=NULL)(MessageBox(hWnd,nError alloc memory!/Error Message,MB_OKIMBCONEXCLAMATION);return FALSE;)lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData);lpTempImgData=(LPBITMAPINFOHEADER)LocalLock(hTempImgData);拷贝头信息和位图数据memcpy(lpTempImgData,lpImgData,BufSize);if(Hori)(在水平方向进行膨胀运算for(y=0;ybi.biHeight;y+)/IpPtr指向原图数据,IpTempPtr指向新图数据lpPtr=(char*)lpImgData+(BufSize-LineBytes-y*LineBytes)+1;lpTempPtr=(char*)lpTempImgData+(BufSize-LineBytes-y*LineBytes)+l;for(x=1;xbi.biWidth-l;x+)注意为防止越界,x的范围从1到宽度-2num=(unsigned char)*lpPtr;原图中是黑点的,新图中肯定也是,所以要考虑的是那些原图中的白点,看是否有可能膨胀成黑点if(num=255)*lpTempPtr=(unsigned char)255;/先置成白点for(i=0;i3;i+)num=(unsigned char)*(lpPtr+i-l);只要左右邻居中有一个是黑点,就膨胀成黑点if(num=O)*lpTempPtr=(unsigned char)O;break;)原图中就是黑点的,新图中仍是黑点else*lpTempPtr=(unsigned char)O;指向下一个象素lpPtr+;lpTempPtr+;else在垂直方向进行腐蚀运算for(y=l;yvbi.biHeight-l;y+)注意为防止越界,y的范围从1到高度-2lpPtr=(char*)lpImgData+(BufSize-LineBytes-y*LineBytes);lpTempPtr=(char*)lpTempImgData+(BufSize-LineBytes-y*LineBytes);for(x=0;xbi.biWidth;x+)num=(unsigned char)*lpPtr;if(num=255)*lpTempPtr=(unsigned char)255;for(i=0;i3;i+)num=(unsigned char)*(lpPtr+(i-1)*LineBytes);只要上下邻居中有一个是黑点,就膨胀成黑点if(num=O)*lpTempPtr=(unsigned char)O;break;else*lpTempPtr=(unsigned char)O;lpPtr+;lpTempPtr+;if(hBitmap!=NULL)DeleteObj ect(hB itmap);hDc二GetDC(hWnd);产生新的位图hBitmap=CreateDIBitmap(hDc,(LPBITMAPINFOHEADER)lpTempImgData,(LONG)CBM_INIT,(LPSTR)lpTempImgData+sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD),(LPBITMAPINFO)lpTempImgData,DIB_RGB_COLORS);起不同的结果文件名if(Hori)hf=_lcreat(nc:hdilation.bmp,0);elsehf=_lcreat(c:vdilation.bmp,0);write(hf,(LPSTR)&bf,sizeof(BITMAPFILEHEADER);_lwrite(hf,(LPSTR)lpTempImgData,BufSize);_lclose(hf);释放内存及资源ReleaseDC(hWnd,hDc);LocalUnlock(hTempImgData);LocalFree(hT empImgData);GlobalUnlock(hlmgData);return TRUE;腐蚀运算和膨胀运算互为对偶的,用公式表示为(X B)C=(XC B),即X被B腐蚀后的补集等于X的补集被B膨 胀。这句话可以形象的理解为:河岸的补集为河面,河岸的腐蚀等价于河面的膨胀。你可以自己举个例子来验证一 下这个关系。在有些情况下,这个对偶关系是非常有用的。例如:某个图象处理系统用硬件实现了腐蚀运算,那么 不必再另搞一套膨胀的硬件,直接利用该对偶就可以实现了。6.3开先腐蚀后膨胀称为开(open),即OPEN(X)=D(E(X)。让我们来看一个开运算的例子(见图6.16):oooooooooox e B OPEN(X)图6.16开运算在图16上面的两幅图中,左边是被处理的图象X(二值图象,我们针对的是黑点),右边是结构元素B,下面的两幅 图中左边是腐蚀后的结果;右边是在此基础上膨胀的结果。可以看到,原图经过开运算后,一些孤立的小点被去掉 To 一般来说,开运算能够去除孤立的小点,毛刺和小桥(即连通两块区域的小点),而总的位置和形状不变。这就是 开运算的作用。要注意的是,如果B是非对称的,进行开运算时要用B的对称集以膨胀,否则,开运算的结果和原 图相比要发生平移。图6.17和图6.18能够说明这个问题。图6.17用B膨胀后,结果向左平移了图6.18用B膨胀后位置不变 图6.17是用B膨胀的,可以看到,OPEN(X)向左平移了。图18是用B膨胀的,可以看到,总的位置和形状不变。图6.19为图6.11经过开运算后的结果。Hijm phoenix.Glad to meet u.图6.19图6.11经过开运算后的结果开运算的源程序可以很容易的根据上面的腐蚀,膨胀程序得到,这里就不给出了。6.4 闭先膨胀后腐蚀称为闭(close),即CLOSE(X)=E(D(X)o让我们来看一个闭运算的例子(见图6.20):图6.20闭运算在图6.20上面的两幅图中,左边是被处理的图象X(二值图象,我们针对的是黑点),右边是结构元素B,下面的两幅 图中左边是膨胀后的结果,右边是在此基础上腐蚀的结果可以看到,原图经过闭运算后,断裂的地方被弥合了。一 般来说,闭运算能够填平小湖(即小孔),弥合小裂缝,而总的位置和形状不变。这就是闭运算的作用。同样要注意的 是,如果B是非对称的,进行闭运算时要用B的对称集B膨胀,否则,闭运算的结果和原图相比要发生平移。图6.21为图6.11经过闭运算后的结果。HiJm phoenix.Glad to meet u.图6.21图.611经过闭运算后的结果闭运算的源程序可以很容易的根据上面的膨胀,腐蚀程序得到,这里就不给出了。你大概已经猜到了,开和闭也是对偶运算,的确如此。用公式表示为(OPEN(X)c=CLOSE(X),或者(CLOSE(X)。=OPEN(Xc)o即X开运算的补集等于X的补集的闭运算,或者X闭运算的补集等于X的补集的开运算。这句话 可以这样来理解:在两个小岛之间有一座小桥,我们把岛和桥看做是处理对象X,则X的补集为大海。如果涨潮时 将小桥和岛的外围淹没(相当于用尺寸比桥宽大的结构元素对X进行开运算),那么两个岛的分隔,相当于小桥两边 海域的连通(对X。做闭运算)。6.5 细化细化 thinning 算法有很多,我们在这里介绍的是一种简单而且效果很好的算法,用它就能够实现从文本抽取骨架的 功能。我们的对象是白纸黑字的文本,但在程序中为了处理的方便,还是采用256级灰度图,不过只用到了调色板 中0和255两项。所谓细化,就是从原来的图中去掉一些点,但仍要保持原来的形状。实际上,是保持原图的骨架。所谓骨架,可以 理解为图象的中轴,例如一个长方形的骨架是它的长方向上的中轴线;正方形的骨架是它的中心点;圆的骨架是它 的圆心,直线的骨架是它自身,孤立点的骨架也是自身。文本的骨架嘛,前言中的例子显示的很明白。那么怎样判 断一个点是否能去掉呢?显然,要根据它的八个相邻点的情况来判断,我们给几个例子(如图6.22所示)。2 3 4 5 图6.22根据某点的八个相邻点的情况来判断该点是否能删除图6.22中,(1 不能删,因为它是个内部点,我们要求的是骨架,如果连内部点也删了,骨架也会被掏空的;(2 不能 册必和 1 是同样的道理;(3 可以删,这样的点不是骨架;(4 不能删,因为删掉后,原来相连的部分断开了;(5 可以 删,这样的点不是骨架;(6 不能删,因为它是直线的端点,如果这样的点删了,那么最后整个直线也被删了,剩不 下什么;(7 不能删,因为孤立点的骨架就是它自身。总结一下,有如下的判据:(1 内部点不能删除;(2 孤立点不能删除;(3 直线端点不能删除;(4 如果P是边界点,去 掉P后,如果连通分量不增加,则P可以删除。我们可以根据上述的判据,事先做出一张表,从。到255共有256个元素,每个元素要么是0,要么是1。我们根据 某点(当然是要处理的黑色点了)的八个相邻点的情况查表,若表中的元素是1,则表示该点可删,否则保留。查表的方法是,设白点为1,黑点为0;左上方点对应一个8位数的第一位(最低位),正上方点对应第二位,右上方 点对应的第三位,左邻点对应第四位,右邻点对应第五位,左下方点对应第六位,正下方点对应第七位,右下方点 对应的第八位,按这样组成的8位数去查表即可。例如上面的例子中对应表中的第。项,该项应该为0;2 对应 37,该项应该为0;3 对应173,该项应该为1;4 对应231,该项应该为0;5 对应237,该项应该为1;6 对应 254,该项应该为0;7 对应255,该项应该为0。这张表我已经替大家做好了,可花了我不少时间呢!static int erasetable 256=0,0,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,0,1,1,1,1,001,1,1,1,1,1,0,1,1,1,0,1,o,o,o,o,o,o,o,i,1,1,0,1,1,1,0,1,0,0,0,0,0,0,0,1,1,1,0,0,14,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,0,0,1,1,0,0,1,1,0,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,1,1,0,1,1,1,0,1,1,1,0,0,1,1,1,0,0,0,0,0,0,0,1,0,0,14,0,0,1,1,1,1,0,1,1,1,0,1,1,1,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,1,1,0,1,1,1,0,0,1,1,0,0,1,1,1,0,1,1,0,0,1,0,0,0);有了这张表,算法就很简单了,每次对一行一行的将整个图象扫描一遍,对于每个点(不包括边界点),计算它在表中 对应的索引,若为0,则保留,否则删除该点。如果这次扫描没有一个点被删除,则循环结束,剩下的点就是骨架点,如果有点被删除,则进行新的一轮扫描,如此反复,直到没有点被删除为止。实际上,该算法有一些缺陷。举个简单的例子,有一个黑色矩形,如图6.23所示。图6.23经过细化后,我们预期的结果是一条水平直线,且位于该黑色矩形的中心。实际的结果确实是一条水平直线,但不是位于黑色矩形的中心,而是最下面的一条边。为什么会这样,我们来分析一下:在从上到下,从左到右的扫描过程中,我们遇到的第一个黑点就是黑色矩形的左 上角点,经查表,该点可以删。下一个点是它右边的点,经查表,该点也可以删,如此下去,整个一行被删了。每 一行都是同样的情况,所以都被删除了。到了最后一行时,黑色矩形已经变成了一条直线,最左边的黑点不能删,因为它是直线的端点,它右边的点也不能删,因为如果删除,直线就断了,如此下去,直到最右边的点,也不能册,因为它是直线的右端点。所以最下面的一条边保住了,但这并不是我们希望的结果。解决的办法是,在每一行水平扫描的过程中,先判断每一点的左右邻居,如果都是黑点,则该点不做处理。另外,如果某个黑点被删除了,那么跳过它的右邻居,处理下一个点。这样就避免了上述的问题。图6.23黑色矩形图6.24图6.23细化后的结果解决了上面的问题,我们来看看处理后的结果,如图6.24所示。这次变成一小段竖线了,还是不对,是不是很沮丧?别着急,让我们再来分析一下:在上面的算法中,我们遇到的第一个能删除的点就是黑色矩形的左上角点;第二个 是第一行的最右边的点,即黑色矩形的右上角点;第三个是第二行的最左边的点;第四个是第二行的最右边的 点;整个图象处理这样一次后,宽度减少2。每次都是如此,直到剩最中间一列,就不能再删了。为什么会这 样呢?原因是这样的处理过程只实现了水平细化,如果在每一次水平细化后,再进行一次垂直方向的细化(只要把上 述过程的行列换一下),就可以了。这样一来,每处理一次,删除点的顺序变成:(先是水平方向扫描)第一行最左边的点;第一行最右边的点;第二行最 左边的点;第二行最右边的点;最后一行最左边的点;最后一行最右边的点;(然后是垂直方向扫描)第二列最上 边的点(因为第一列最上边的点已被删除);第二列最下边的点;第三列最上边的点;第三列最下边的点;倒数第 二列最上边的点(因为倒数第一列最上边的点已被删除);倒数第二列最下边的点。我们发现,刚好剥掉了一圈,这也 正是细化要做的事。实际的结果也验证了我们的想法。以下是源程序,黑体字部分是值得注意的地方。BOOL Thinning HWND hWnd DWORD OffBits,BufSize;LPBITMAPINFOHEADER IpImgData;LPSTR IpPtr;HLOCAL hT empImgData;LPBITMAPINFOHEADER IpTempImgData;LPSTR IpTempPtr;HDC hDc;HFILE hf;LONG x,y;int num;BOOL Finished;int nw,n,ne,w,e,sw,s,se;为了处理的方便,仍采用256级灰度图,不过只用调色板中0和255两项if(NumColors!=256)MessageBox(hWnd,Must be a mono bitmap with grayscale palette!,Error Message,MB_OKIMB_ICONEXCLAMATION);return FALSE;)OffBits=bf.bfOffBits-sizeof(BITMAPHLEHEADER);/BufSize为缓冲区大小BufSize=OffBits+bi.biHeight*LineBytes;为新的缓冲区分配内存if(hTempImgData=LocalAlloc(LHND,BufSize)=NULL)(MessageBox(hWnd,Error alloc memory!1,Error Message,MB_OKIMB_ICONEXCLAMATION);return FALSE;)lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData);lpTempImgData=(LPBITMAPINFOHEADER)LocalLock(hTempImgData);拷贝头信息和位图数据memcpy(lpTempImgData,lpImgData,BufSize);结束标志置成假Finished=FALSE;while(Finished)还没有结束结束标志置成假Finished=TRUE;先进行水平方向的细化for(y=l;yvbi.biHeight-l;y+)注意为防止越界,y的范围从1到高度-2/IpPtr指向原图数据,IpTempPtr指向新图数据lpPtr=(char*)lpImgData+(BufSize-LineBytes-y*LineBytes);lpTempPtr=(char*)lpTempImgData+(BufSize-LineBytes-y*LineBytes);x=l;注意为防止越界,x的范围从1到宽度-2while(xbi.biWidth-1)if(*(lpPtr+x)=O)是黑点才做处理w=(unsigned char)*(lpPtr+x-l);左邻点e=(unsigned char)*(lpPtr+x+1);右邻点if(w=255)ll(e=255)如果左右两个邻居中至少有一个是白点才处理nw=(unsigned char)*(lpPtr+x+LineBytes-l);左上令R点n=(unsigned char)*(lpPtr+x+LineBytes);上邻点ne=(unsigned char)*(lpPtr+x+LineBytes+l);右上邻点sw=(unsigned char)*(lpPtr+x-LineBytes-l);左下邻点s=(unsigned char)*(lpPtr+x-LineBytes);下邻点se=(unsigned char)*(lpPtr+x-LineBytes+l);右下邻点计算索引num=nw/255+n/255*2+ne/255*4+w/255*8+e/255*16+sw/255*32+s/255*64+se/255*128;if(erasetable num=1)经查表,可以删除在原图缓冲区中将该黑点删除*(lpPtr+x)=(BYTE)255;结果图中该黑点也删除*(lpTempPtr+x)=(B YTE)255;Finished=FALSE;/侑改动,结束标志置成假x+;水平方向跳过一个象素x+;/扫描下一个象素)再进行垂直方向的细化for(x=l;xbi.biWidth-l;x+)/注意为防止越界,x的范围从1到宽度-2y=l;注意为防止越界,y的范围从1到高度-2while(ybi.biHeight-1)lpPtr=(char*)lpImgData+(BufSize-LineBytes-y*LineBytes);lpTempPtr=(char*)lpTempImgData+(BufSize-LineBytes-y*LineBytes);if(*(lpPtr+x)=O)是黑点才做处理n=(unsigned char)*(lpPtr+x+LineBytes);s=(unsigned char)*(lpPtr+x-LineBytes);if(n=255)ll(s=255)如果上下两个邻居中至少有一个是白点才处理nw=(unsigned char)*(lpPtr+x+LineB ytes-1);ne=(unsigned char)*(lpPtr+x+LineBytes+1);w=(unsigned char)*(IpPtr+x-1);e=(unsigned char)*(lpPtr+x+1);sw=(unsigned char)*(lpPtr+x-LineBytes-1);se=(unsigned char)*(lpPtr+x-LineBytes+1);计算索引num二nw/255+n/255*2+ne/255*4+w/255*8+e/255*16+sw/255*32+s/255*64+se/255*128;if(erasetablenum=l)经查表,可以删除在原图缓冲区中将该黑点删除*(lpPtr+x)=(BYTE)255;结果图中该黑点也删除*(lpTempPtr+x)=(B YTE)255;Finished=FALSE;/府改动,结束标志置成假y+;垂直方向跳过一个象素)y+;/扫描下一个象素)if(hBitmap!=NULL)DeleteObj ect(hB itmap);hDc=GetDC(hWnd);产生新的位图hBitmap=CreateDIBitmap(hDc,(LPBITMAPINFOHEADER)lpTempImgData,(LONG)CBMNIT,(LPSTR)lpT empImgData+sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD),(LPBITMAPINFO)lpTempImgData,DIB_RGB_COLORS);hf=_lcreat(c:thinning.bmp,0);_lwrite(hf,(LPSTR)&bf,sizeof(BITMAPHLEHEADER);_lwrite(hf,(LPSTR)lpTempImgData,BufSize);_lclose(hf);释放内存及资源ReleaseDC(hWnd,hDc);LocalUnlock(hT empImgData);LocalFree(hTempImgData);GlobalUnlock(hlmgData);return TRUE;The University of Southern California does not screen or control the content on this website and thus does not guarantee the accuracy,integrity,or quality of such content.All content on this website is provided by and is the sole responsibility of the person from which such content originated,and such content does not necessarily reflect the opinions of the University administration or the Board of Trustees
    展开阅读全文
    提示  咨信网温馨提示:
    1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
    2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
    3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
    4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前可先查看【教您几个在下载文档中可以更好的避免被坑】。
    5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
    6、文档遇到问题,请及时联系平台进行协调解决,联系【微信客服】、【QQ客服】,若有其他问题请点击或扫码反馈【服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【版权申诉】”,意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:0574-28810668;投诉电话:18658249818。

    开通VIP折扣优惠下载文档

    自信AI创作助手
    关于本文
    本文标题:第6章 腐蚀,膨胀,细化算法.pdf
    链接地址:https://www.zixin.com.cn/doc/4901643.html
    页脚通栏广告

    Copyright ©2010-2026   All Rights Reserved  宁波自信网络信息技术有限公司 版权所有   |  客服电话:0574-28810668    微信客服:咨信网客服    投诉电话:18658249818   

    违法和不良信息举报邮箱:help@zixin.com.cn    文档合作和网站合作邮箱:fuwu@zixin.com.cn    意见反馈和侵权处理邮箱:1219186828@qq.com   | 证照中心

    12321jubao.png12321网络举报中心 电话:010-12321  jubao.png中国互联网举报中心 电话:12377   gongan.png浙公网安备33021202000488号  icp.png浙ICP备2021020529号-1 浙B2-20240490   


    关注我们 :微信公众号  抖音  微博  LOFTER               

    自信网络  |  ZixinNetwork