softwaremercy 发表于 2006-3-22 03:09

数字图像处理编程---7边沿检测与提取,轮廓跟踪

<div style="LAYOUT-GRID-CHAR: none; LAYOUT-GRID-LINE: 15.6pt;"><h1><a name="_Toc486331897"></a><a name="_Toc486332897"></a><a name="_Toc486339006"></a><a name="_Toc454810871"></a><a name="_Toc454856645"><span><span>第<span lang="EN-US">7</span></span></span></a><span><span><span style="FONT-FAMILY: 黑体;">章</span> </span></span><span><span><span style="FONT-FAMILY: 黑体;">边沿检测与提取,轮廓跟踪</span></span></span></h1><p style="LINE-HEIGHT: 18pt;"><span style="FONT-FAMILY: 宋体;">我们在第三章介绍平滑与锐化时引入了模板操作,今天还要用到它。</span></p><h2><span lang="EN-US">7.1</span> <span lang="EN-US"></span><a name="_Toc486331898"></a><a name="_Toc486332898"></a><a name="_Toc486339007"></a><a name="_Toc454810872"></a><a name="_Toc454856646"><span><span>边沿检测</span></span></a></h2><p style="LINE-HEIGHT: 18pt;"><span style="FONT-FAMILY: 宋体;">我们给出一个模板</span><span lang="EN-US"><sub> <img height="23" src="mk:@MSITStore:H:\200541352851453.chm::/10.files/image002.gif" width="76" vshapes="_x0000_i1025" alt=""/> </sub></span><span style="FONT-FAMILY: 宋体;">和一幅图象</span><span lang="EN-US"><sub> <img height="96" src="mk:@MSITStore:H:\200541352851453.chm::/10.files/image004.gif" width="228" vshapes="_x0000_i1026" alt=""/> </sub></span><span style="FONT-FAMILY: 宋体;">。不难发现原图中左边暗,右边亮,中间存在着一条明显的边界。进行模板操作后的结果如下:</span><span lang="EN-US"><sub> <img height="96" src="mk:@MSITStore:H:\200541352851453.chm::/10.files/image006.gif" width="229" vshapes="_x0000_i1027" alt=""/> </sub></span><span style="FONT-FAMILY: 宋体;">。</span></p><p style="LINE-HEIGHT: 18pt;"><span style="FONT-FAMILY: 宋体;">可以看出,第</span><span lang="EN-US">3</span><span style="FONT-FAMILY: 宋体;">、</span><span lang="EN-US">4</span><span style="FONT-FAMILY: 宋体;">列比其他列的灰度值高很多,人眼观察时,就能发现一条很明显的亮边,其它区域都很暗,这样就起到了边沿检测的作用。</span></p><p style="LINE-HEIGHT: 18pt;"><span style="FONT-FAMILY: 宋体;">为什么会这样呢?仔细看看那个模板就明白了,它的意思是将右邻点的灰度值减左邻点的灰度值作为该点的灰度值。在灰度相近的区域内,这么做的结果使得该点的灰度值接近于</span><span lang="EN-US">0</span><span style="FONT-FAMILY: 宋体;">;而在边界附近,灰度值有明显的跳变,这么做的结果使得该点的灰度值很大,这样就出现了上面的结果。</span></p><p style="LINE-HEIGHT: 18pt;"><span style="FONT-FAMILY: 宋体;">这种模板就是一种边沿检测器,它在数学上的涵义是一种基于梯度的滤波器,又称边沿算子,你没有必要知道梯度的确切涵义,只要有这个概念就可以了。梯度是有方向的,和边沿的方向总是正交</span><span lang="EN-US">(</span><span style="FONT-FAMILY: 宋体;">垂直</span><span lang="EN-US">)</span><span style="FONT-FAMILY: 宋体;">的,例如,对于上面那幅图象的转置图象,边是水平方向的,我们可以用梯度是垂直方向的模板</span><span lang="EN-US"><sub> <img height="75" src="mk:@MSITStore:H:\200541352851453.chm::/10.files/image008.gif" width="36" vshapes="_x0000_i1035" alt=""/> </sub></span><span style="FONT-FAMILY: 宋体;">检测它的边沿。</span></p><p style="LINE-HEIGHT: 18pt;"><span style="FONT-FAMILY: 宋体;">例如,一个梯度为</span><span lang="EN-US">45</span><span style="FONT-FAMILY: 宋体;">度方向模板</span><span lang="EN-US"><sub> <img height="75" src="mk:@MSITStore:H:\200541352851453.chm::/10.files/image010.gif" width="91" vshapes="_x0000_i1036" alt=""/> </sub></span><span style="FONT-FAMILY: 宋体;">,可以检测出</span><span lang="EN-US">135</span><span style="FONT-FAMILY: 宋体;">度方向的边沿。</span></p><p style="LINE-HEIGHT: 18pt;"><b><span lang="EN-US">1.<span style="FONT: 7pt 'Times New Roman';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></b><b><span lang="EN-US">Sobel</span></b><b><span style="FONT-FAMILY: 宋体;">算子</span><span lang="EN-US"></span></b></p><p style="LINE-HEIGHT: 18pt;"><span style="FONT-FAMILY: 宋体;">在边沿检测中,常用的一种模板是</span><span lang="EN-US">Sobel </span><span style="FONT-FAMILY: 宋体;">算子。</span><span lang="EN-US">Sobel </span><span style="FONT-FAMILY: 宋体;">算子有两个,一个是检测水平边沿的</span><span lang="EN-US"><sub> <img height="75" src="mk:@MSITStore:H:\200541352851453.chm::/10.files/image012.gif" width="103" vshapes="_x0000_i1037" alt=""/> </sub></span><span style="FONT-FAMILY: 宋体;">;另一个是检测垂直平边沿的</span><span lang="EN-US"><sub> <img height="75" src="mk:@MSITStore:H:\200541352851453.chm::/10.files/image014.gif" width="88" vshapes="_x0000_i1038" alt=""/> </sub></span><span style="FONT-FAMILY: 宋体;">。与</span><span lang="EN-US"><sub> <img height="75" src="mk:@MSITStore:H:\200541352851453.chm::/10.files/image016.gif" width="100" vshapes="_x0000_i1039" alt=""/> </sub></span><span style="FONT-FAMILY: 宋体;">和</span><span lang="EN-US"><sub> <img height="75" src="mk:@MSITStore:H:\200541352851453.chm::/10.files/image018.gif" width="81" vshapes="_x0000_i1040" alt=""/> </sub></span><span style="FONT-FAMILY: 宋体;">相比,</span><span lang="EN-US">Sobel</span><span style="FONT-FAMILY: 宋体;">算子对于象素的位置的影响做了加权,因此效果更好。</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">Sobel</span><span style="FONT-FAMILY: 宋体;">算子另一种形式是各向同性</span><span lang="EN-US">Sobel(Isotropic Sobel)</span><span style="FONT-FAMILY: 宋体;">算子,也有两个,一个是检测水平边沿的</span><span lang="EN-US"><sub> <img height="80" src="mk:@MSITStore:H:\200541352851453.chm::/10.files/image020.gif" width="115" vshapes="_x0000_i1041" alt=""/> </sub></span><span style="FONT-FAMILY: 宋体;">,另一个是检测垂直平边沿的</span><span lang="EN-US"><sub> <img height="75" src="mk:@MSITStore:H:\200541352851453.chm::/10.files/image022.gif" width="112" vshapes="_x0000_i1042" alt=""/> </sub></span><span style="FONT-FAMILY: 宋体;">。各向同性</span><span lang="EN-US">Sobel</span><span style="FONT-FAMILY: 宋体;">算子和普通</span><span lang="EN-US">Sobel</span><span style="FONT-FAMILY: 宋体;">算子相比,它的位置加权系数更为准确,在检测不同方向的边沿时梯度的幅度一致。</span></p><p style="LINE-HEIGHT: 18pt;"><span style="FONT-FAMILY: 宋体;">下面的几幅图中,图</span><span lang="EN-US">7.1</span><span style="FONT-FAMILY: 宋体;">为原图;图</span><span lang="EN-US">7.2</span><span style="FONT-FAMILY: 宋体;">为普通</span><span lang="EN-US">Sobel</span><span style="FONT-FAMILY: 宋体;">算子处理后的结果图;图</span><span lang="EN-US">7.3</span><span style="FONT-FAMILY: 宋体;">为各向同性</span><span lang="EN-US">Sobel</span><span style="FONT-FAMILY: 宋体;">算子处理后的结果图。可以看出</span><span lang="EN-US">Sobel</span><span style="FONT-FAMILY: 宋体;">算子确实把图象中的边沿提取了出来。</span></p><p align="center" style="LINE-HEIGHT: 18pt; TEXT-ALIGN: center;"><span lang="EN-US"><img height="202" src="mk:@MSITStore:H:\200541352851453.chm::/10.files/image024.jpg" width="319" vshapes="_x0000_i1043" alt=""/> </span></p><p align="center" style="LINE-HEIGHT: 18pt; TEXT-ALIGN: center;"><b><span style="FONT-FAMILY: 宋体;">图</span>7.1&nbsp;&nbsp;&nbsp;&nbsp; </b><b><span style="FONT-FAMILY: 宋体;">原图</span><span lang="EN-US"></span></b></p><p align="center" style="LINE-HEIGHT: 18pt; TEXT-ALIGN: center;"><span lang="EN-US"><img height="201" src="mk:@MSITStore:H:\200541352851453.chm::/10.files/image026.jpg" width="319" vshapes="_x0000_i1044" alt=""/> </span></p><p align="center" style="LINE-HEIGHT: 18pt; TEXT-ALIGN: center;"><b><span style="FONT-FAMILY: 宋体;">图</span>7.2&nbsp;&nbsp;&nbsp;&nbsp; </b><b><span style="FONT-FAMILY: 宋体;">普通</span><span lang="EN-US">Sobel</span></b><b><span style="FONT-FAMILY: 宋体;">算子处理后的结果图</span><span lang="EN-US"></span></b></p><p align="center" style="LINE-HEIGHT: 18pt; TEXT-ALIGN: center;"><b><span lang="EN-US"><img height="200" src="mk:@MSITStore:H:\200541352851453.chm::/10.files/image028.jpg" width="316" vshapes="_x0000_i1045" alt=""/> </span></b></p><p align="center" style="LINE-HEIGHT: 18pt; TEXT-ALIGN: center;"><b><span style="FONT-FAMILY: 宋体;">图</span>7.3&nbsp;&nbsp;&nbsp;&nbsp; </b><b><span style="FONT-FAMILY: 宋体;">各向同性</span><span lang="EN-US">Sobel</span></b><b><span style="FONT-FAMILY: 宋体;">算子处理后的结果图</span><span lang="EN-US"></span></b></p><p style="LINE-HEIGHT: 18pt;"><span style="FONT-FAMILY: 宋体;">在程序中仍然要用到第</span><span lang="EN-US">3</span><span style="FONT-FAMILY: 宋体;">章介绍的通用</span><span lang="EN-US">3</span><span style="FONT-FAMILY: 宋体;">×</span><span lang="EN-US">3</span><span style="FONT-FAMILY: 宋体;">模板操作函数</span><span lang="EN-US">TemplateOperation</span><span style="FONT-FAMILY: 宋体;">,所做的操作只是增加几个常量标识及其对应的模板数组,这里就不再给出了。</span></p><p style="LINE-HEIGHT: 18pt;"><b><span lang="EN-US">2.<span style="FONT: 7pt 'Times New Roman';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></b><b><span style="FONT-FAMILY: 宋体;">高斯拉普拉斯算子</span><span lang="EN-US"></span></b></p><p style="LINE-HEIGHT: 18pt;"><span style="FONT-FAMILY: 宋体;">由于噪声点</span><span lang="EN-US">(</span><span style="FONT-FAMILY: 宋体;">灰度与周围点相差很大的点</span><span lang="EN-US">)</span><span style="FONT-FAMILY: 宋体;">对边沿检测有一定的影响,所以效果更好的边沿检测器是高斯拉普拉斯</span><span lang="EN-US">(LOG)</span><span style="FONT-FAMILY: 宋体;">算子。它把我们在第</span><span lang="EN-US">3</span><span style="FONT-FAMILY: 宋体;">章中介绍的高斯平滑滤波器和拉普拉斯锐化滤波器结合了起来,先平滑掉噪声,再进行边沿检测,所以效果会更好。</span></p><p style="LINE-HEIGHT: 18pt;"><span style="FONT-FAMILY: 宋体;">常用的</span><span lang="EN-US">LOG</span><span style="FONT-FAMILY: 宋体;">算子是</span><span lang="EN-US">5</span><span style="FONT-FAMILY: 宋体;">×</span><span lang="EN-US">5</span><span style="FONT-FAMILY: 宋体;">的模板,如下所示</span><span lang="EN-US"><sub> <img height="120" src="mk:@MSITStore:H:\200541352851453.chm::/10.files/image030.gif" width="187" vshapes="_x0000_i1046" alt=""/> </sub></span><span style="FONT-FAMILY: 宋体;">。到中心点的距离与位置加权系数的关系用曲线表示为图</span><span lang="EN-US">7.4</span><span style="FONT-FAMILY: 宋体;">。是不是很象一顶墨西哥草帽?所以,</span><span lang="EN-US">LOG</span><span style="FONT-FAMILY: 宋体;">又叫墨西哥草帽滤波器。</span></p><p class="a" style="LINE-HEIGHT: 18pt;"><span lang="EN-US"><img height="148" src="mk:@MSITStore:H:\200541352851453.chm::/10.files/image032.jpg" width="268" vshapes="_x0000_i1047" alt=""/> </span></p><p align="center" style="LINE-HEIGHT: 18pt; TEXT-ALIGN: center;"><b><span style="FONT-FAMILY: 宋体;">图</span>7.4&nbsp;&nbsp;&nbsp;&nbsp; LOG</b><b><span style="FONT-FAMILY: 宋体;">到中心点的距离与位置加权系数的关系曲线</span><span lang="EN-US"></span></b></p><p style="LINE-HEIGHT: 18pt;"><span style="FONT-FAMILY: 宋体;">图</span><span lang="EN-US">7.5</span><span style="FONT-FAMILY: 宋体;">为图</span><span lang="EN-US">7.1</span><span style="FONT-FAMILY: 宋体;">用</span><span lang="EN-US">LOG</span><span style="FONT-FAMILY: 宋体;">滤波器处理后的结果。</span></p><p class="a" style="LINE-HEIGHT: 18pt;"><span lang="EN-US"><img height="192" src="mk:@MSITStore:H:\200541352851453.chm::/10.files/image034.jpg" width="303" vshapes="_x0000_i1048" alt=""/> </span></p><p align="center" style="LINE-HEIGHT: 18pt; TEXT-ALIGN: center;"><b><span style="FONT-FAMILY: 宋体;">图</span>7.5&nbsp;&nbsp;&nbsp;&nbsp; </b><b><span style="FONT-FAMILY: 宋体;">图</span><span lang="EN-US">7.1</span></b><b><span style="FONT-FAMILY: 宋体;">用</span><span lang="EN-US">LOG</span></b><b><span style="FONT-FAMILY: 宋体;">滤波器处理后的结果图</span><span lang="EN-US"></span></b></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">LOG</span><span style="FONT-FAMILY: 宋体;">的算法和普通模板操作的算法没什么不同,只不过把</span><span lang="EN-US">3</span><span style="FONT-FAMILY: 宋体;">×</span><span lang="EN-US">3</span><span style="FONT-FAMILY: 宋体;">改成了</span><span lang="EN-US">5</span><span style="FONT-FAMILY: 宋体;">×</span><span lang="EN-US">5</span><span style="FONT-FAMILY: 宋体;">,这里就不再给出了。读者可以参照第</span><span lang="EN-US">3</span><span style="FONT-FAMILY: 宋体;">章的源程序自己来完成。</span></p><h2><span lang="EN-US">7.2</span> <a name="_Toc486331899"></a><a name="_Toc486332899"></a><a name="_Toc486339008"></a><a name="_Toc454810873"></a><a name="_Toc454856647"><span><span>Hough</span></span></a><span><span><span style="FONT-FAMILY: 黑体;">变换</span></span></span></h2><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">Hough</span><span style="FONT-FAMILY: 宋体;">变换用来在图象中查找直线。它的原理很简单:假设有一条与原点距离为</span><span lang="EN-US">s</span><span style="FONT-FAMILY: 宋体;">,方向角为θ的一条直线,如图</span><span lang="EN-US">7.6</span><span style="FONT-FAMILY: 宋体;">所示。</span></p><p align="center" style="LINE-HEIGHT: 18pt; TEXT-ALIGN: center;"><span lang="EN-US"><img height="178" src="mk:@MSITStore:H:\200541352851453.chm::/10.files/image036.jpg" width="232" vshapes="_x0000_i1049" alt=""/> </span></p><p align="center" style="LINE-HEIGHT: 18pt; TEXT-ALIGN: center;"><b><span style="FONT-FAMILY: 宋体;">图</span>7.6&nbsp;&nbsp;&nbsp; </b><b><span style="FONT-FAMILY: 宋体;">一条与原点距离为</span><span lang="EN-US">s</span></b><b><span style="FONT-FAMILY: 宋体;">,方向角为θ的一条直线</span><span lang="EN-US"></span></b></p><p style="LINE-HEIGHT: 18pt;"><span style="FONT-FAMILY: 宋体;">直线上的每一点都满足方程</span></p><p align="center" style="LINE-HEIGHT: 18pt; TEXT-ALIGN: center;"><span lang="EN-US"><sub><img height="21" src="mk:@MSITStore:H:\200541352851453.chm::/10.files/image038.gif" width="128" vshapes="_x0000_i1050" alt=""/> </sub></span></p><p align="right" style="LINE-HEIGHT: 18pt; TEXT-ALIGN: right;"><span lang="EN-US">(7.1)</span></p><p style="LINE-HEIGHT: 18pt;"><span style="FONT-FAMILY: 宋体;">利用这个事实,我们可以找出某条直线来。下面将给出一段程序,用来找出图象中最长的直线</span><span lang="EN-US">(</span><span style="FONT-FAMILY: 宋体;">见图</span><span lang="EN-US">7.7)</span><span style="FONT-FAMILY: 宋体;">。找到直线的两个端点,在它们之间连一条红色的直线。为了看清效果,将结果描成粗线,如图</span><span lang="EN-US">7.8</span><span style="FONT-FAMILY: 宋体;">所示。</span></p><table cellspacing="0" cellpadding="0" border="0"><tbody><tr><td class="Normal" valign="top" width="276"><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US"><img height="193" src="mk:@MSITStore:H:\200541352851453.chm::/10.files/image040.gif" width="239" vshapes="_x0000_i1051" alt=""/> </span></p><p align="center" style="LINE-HEIGHT: 18pt; TEXT-ALIGN: center;"><b><span style="FONT-FAMILY: 宋体;">图</span><span lang="EN-US">7.7 </span></b><b><span style="FONT-FAMILY: 宋体;">原图</span><span lang="EN-US"></span></b></p></td><td class="Normal" valign="top" width="276"><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US"><img height="193" src="mk:@MSITStore:H:\200541352851453.chm::/10.files/image042.jpg" width="243" vshapes="_x0000_i1052" alt=""/> </span></p><p align="center" style="LINE-HEIGHT: 18pt; TEXT-ALIGN: center;"><b><span style="FONT-FAMILY: 宋体;">图</span><span lang="EN-US">7.8 Hough</span></b><b><span style="FONT-FAMILY: 宋体;">变换的结果</span><span lang="EN-US"></span></b></p></td></tr></tbody></table><p style="LINE-HEIGHT: 18pt;"><span style="FONT-FAMILY: 宋体;">可以看出,找到的确实是最长的直线。方法是,开一个二维数组做为计数器,第一维是角度,第二维是距离。先计算可能出现的最大距离为</span><span lang="EN-US"><sub> <img height="29" src="mk:@MSITStore:H:\200541352851453.chm::/10.files/image044.gif" width="125" vshapes="_x0000_i1053" alt=""/> </sub></span><span style="FONT-FAMILY: 宋体;">,用来确定数组第二维的大小。对于每一个黑色点,角度的变化范围从</span><span lang="EN-US">0<sup>0</sup></span><span style="FONT-FAMILY: 宋体;">到</span><span lang="EN-US">178<sup>0</sup>(</span><span style="FONT-FAMILY: 宋体;">为了减少存储空间和计算时间,角度每次增加</span><span lang="EN-US">2<sup>0</sup></span><span style="FONT-FAMILY: 宋体;">而不是</span><span lang="EN-US">1<sup>0</sup>)</span><span style="FONT-FAMILY: 宋体;">,按方程</span><span lang="EN-US">(7.1)</span><span style="FONT-FAMILY: 宋体;">求出对应的距离</span><span lang="EN-US">s</span><span style="FONT-FAMILY: 宋体;">来,相应的数组元素</span><span lang="EN-US">[<sub> <img height="19" src="mk:@MSITStore:H:\200541352851453.chm::/10.files/image046.gif" width="13" vshapes="_x0000_i1054" alt=""/> </sub>]</span><span style="FONT-FAMILY: 宋体;">加</span><span lang="EN-US">1</span><span style="FONT-FAMILY: 宋体;">。同时开一个数组</span><span lang="EN-US">Line</span><span style="FONT-FAMILY: 宋体;">,计算每条直线的上下两个端点。所有的象素都算完后,找到数组元素中最大的,就是最长的那条直线。直线的端点可以在</span><span lang="EN-US">Line</span><span style="FONT-FAMILY: 宋体;">中找到。要注意的是,我们处理的虽然是二值图,但实际上是</span><span lang="EN-US">256</span><span style="FONT-FAMILY: 宋体;">级灰度图,不过只用到了</span><span lang="EN-US">0</span><span style="FONT-FAMILY: 宋体;">和</span><span lang="EN-US">255</span><span style="FONT-FAMILY: 宋体;">两种颜色。</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">BOOL Hough(HWND hWnd)</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">{</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">//</span><span style="FONT-FAMILY: 宋体;">定义一个自己的直线结构</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp; </span>typedef struct{</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp; </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;int topx; //<span style="FONT-FAMILY: 宋体;">最高点的</span><span lang="EN-US">x</span><span style="FONT-FAMILY: 宋体;">坐标</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp; </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;int topy; //<span style="FONT-FAMILY: 宋体;">最高点的</span><span lang="EN-US">y</span><span style="FONT-FAMILY: 宋体;">坐标</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp; </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;int botx; //<span style="FONT-FAMILY: 宋体;">最低点的</span><span lang="EN-US">x</span><span style="FONT-FAMILY: 宋体;">坐标</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp; </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;int boty; //<span style="FONT-FAMILY: 宋体;">最低点的</span><span lang="EN-US">y</span><span style="FONT-FAMILY: 宋体;">坐标</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp; </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;}MYLINE;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>DWORD &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OffBits,BufSize;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp; </span>&nbsp; LPBITMAPINFOHEADER&nbsp;&nbsp;&nbsp; lpImgData;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>LPSTR&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lpPtr;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>HDC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hDc;</p><p style="LINE-HEIGHT: 18pt;">LONG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x,y;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>long&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i,maxd;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; k;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Dist,Alpha;</p><p style="LINE-HEIGHT: 18pt;">HGLOBAL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hDistAlpha,hMyLine;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp; </span>&nbsp; Int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; *lpDistAlpha;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>MYLINE &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *lpMyLine,*TempLine,MaxdLine;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp; </span>&nbsp; static LOGPEN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rlp={PS_SOLID,1,1,RGB(255,0,0)};</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp; </span>&nbsp; HPEN &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rhp;</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">//</span><span style="FONT-FAMILY: 宋体;">我们处理的实际上是</span><span lang="EN-US">256</span><span style="FONT-FAMILY: 宋体;">级灰度图,不过只用到了</span><span lang="EN-US">0</span><span style="FONT-FAMILY: 宋体;">和</span><span lang="EN-US">255</span><span style="FONT-FAMILY: 宋体;">两种颜色。</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">if( NumColors!=256){ </span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>MessageBox(hWnd,"Must be a mono bitmap with grayscale palette!",</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">"Error Message",MB_OK|MB_ICONEXCLAMATION);</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">return FALSE;</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">}</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">//</span><span style="FONT-FAMILY: 宋体;">计算最大距离</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Dist=(int)(sqrt((double)bi.biWidth*bi.biWidth+</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">(double)bi.biHeight*bi.biHeight)+0.5);</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Alpha=180 /2 ;&nbsp; //0 <span style="FONT-FAMILY: 宋体;">到</span><span lang="EN-US"> to 178 </span><span style="FONT-FAMILY: 宋体;">度,步长为</span><span lang="EN-US">2</span><span style="FONT-FAMILY: 宋体;">度</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//<span style="FONT-FAMILY: 宋体;">为距离角度数组分配内存</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">if((hDistAlpha=GlobalAlloc(GHND,(DWORD)Dist*Alpha*</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">sizeof(int)))==NULL){</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">MessageBox(hWnd,"Error alloc memory!","Error Message",</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">MB_OK|MB_ICONEXCLAMATION);</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">return FALSE;</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp; </span>}</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//<span style="FONT-FAMILY: 宋体;">为记录直线端点的数组分配内存</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp; </span>&nbsp;&nbsp;&nbsp; if((hMyLine=GlobalAlloc(GHND,(DWORD)Dist*Alpha*</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">sizeof(MYLINE)))==NULL){</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp; </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GlobalFree(hDistAlpha);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp; </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return&nbsp; FALSE;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>OffBits=bf.bfOffBits-sizeof(BITMAPFILEHEADER);</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">//BufSize</span><span style="FONT-FAMILY: 宋体;">为缓冲区大小</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>BufSize=OffBits+bi.biHeight*LineBytes;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp; </span>&nbsp; lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp; </span>&nbsp; lpDistAlpha=(int *)GlobalLock(hDistAlpha);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>lpMyLine=(MYLINE *)GlobalLock(hMyLine);</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">for (i=0;i&lt;(long)Dist*Alpha;i++){</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>TempLine=(MYLINE*)(lpMyLine+i);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>(*TempLine).boty=32767; //<span style="FONT-FAMILY: 宋体;">初始化最低点的</span><span lang="EN-US">y</span><span style="FONT-FAMILY: 宋体;">坐标为一个很大的值</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>for (y=0;y&lt;bi.biHeight;y++){</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//lpPtr<span style="FONT-FAMILY: 宋体;">指向位图数据</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>lpPtr=(char *)lpImgData+(BufSize-LineBytes-y*LineBytes);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>for (x=0;x&lt;bi.biWidth;x++)</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if(*(lpPtr++)==0) //<span style="FONT-FAMILY: 宋体;">是个黑点</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>for (k=0;k&lt;180;k+=2){</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//<span style="FONT-FAMILY: 宋体;">计算距离</span><span lang="EN-US">i</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i=(long)fabs((x*cos(k*PI/180.0)+y*sin(k*PI/180.0)));</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//<span style="FONT-FAMILY: 宋体;">相应的数组元素加</span><span lang="EN-US">1</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; *(lpDistAlpha+i*Alpha+k/2)=*(lpDistAlpha+i*Alpha+k/2)+1;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>TempLine=(MYLINE*)(lpMyLine+i*Alpha+k/2);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if(y&gt; (*TempLine).topy){</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//<span style="FONT-FAMILY: 宋体;">记录该直线最高点的</span><span lang="EN-US">x,y</span><span style="FONT-FAMILY: 宋体;">坐标</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>(*TempLine).topx=x;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>(*TempLine).topy=y;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if(y&lt; (*TempLine).boty){</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//<span style="FONT-FAMILY: 宋体;">记录该直线最低点的</span><span lang="EN-US">x,y</span><span style="FONT-FAMILY: 宋体;">坐标</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>(*TempLine).botx=x;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>(*TempLine).boty=y;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">}</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>maxd=0;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>for (i=0;i&lt;(long)Dist*Alpha;i++){</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>TempLine=(MYLINE*)(lpMyLine+i);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>k=*(lpDistAlpha+i);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if(k &gt; maxd){</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//<span style="FONT-FAMILY: 宋体;">找到数组元素中最大的,及相应的直线端点</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>maxd=k;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>MaxdLine.topx=(*TempLine).topx;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>MaxdLine.topy=(*TempLine).topy;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>MaxdLine.botx=(*TempLine).botx;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>MaxdLine.boty=(*TempLine).boty;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>hDc = GetDC(hWnd);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>rhp = CreatePenIndirect(&amp;rlp);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>SelectObject(hDc,rhp);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>MoveToEx(hDc,MaxdLine.botx,MaxdLine.boty,NULL);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//<span style="FONT-FAMILY: 宋体;">在两端点之间画一条红线用来标识</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>LineTo(hDc,MaxdLine.topx,MaxdLine.topy);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;</span>&nbsp;&nbsp;&nbsp;&nbsp; DeleteObject(rhp);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;</span>&nbsp;&nbsp;&nbsp;&nbsp; ReleaseDC(hWnd,hDc);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//<span style="FONT-FAMILY: 宋体;">释放内存及资源</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>GlobalUnlock(hImgData);</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">GlobalUnlock(hDistAlpha);</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>GlobalFree(hDistAlpha);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp; </span>&nbsp; GlobalUnlock(hMyLine);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>GlobalFree(hMyLine);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>return TRUE;</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">}</span><span lang="EN-US" style="FONT-SIZE: 9pt;"></span></p><p style="LINE-HEIGHT: 18pt;"><span style="FONT-FAMILY: 宋体;">如果</span><span lang="EN-US"><sub> <img height="19" src="mk:@MSITStore:H:\200541352851453.chm::/10.files/image047.gif" width="13" vshapes="_x0000_i1055" alt=""/> </sub></span><span style="FONT-FAMILY: 宋体;">是给定的,用上述方法,我们可以找到该方向上最长的直线。</span></p><p style="LINE-HEIGHT: 18pt;"><span style="FONT-FAMILY: 宋体;">其实</span><span lang="EN-US">Hough</span><span style="FONT-FAMILY: 宋体;">变换能够查找任意的曲线,只要你给定它的方程。这里,我们就不详述了。</span></p><h2><span lang="EN-US">7.3</span> <span lang="EN-US"></span><a name="_Toc486331900"></a><a name="_Toc486332900"></a><a name="_Toc486339009"></a><a name="_Toc454810874"></a><a name="_Toc454856648"><span><span>轮廓提取</span></span></a></h2><p style="LINE-HEIGHT: 18pt;"><span style="FONT-FAMILY: 宋体;">轮廓提取的实例如图</span><span lang="EN-US">7.9</span><span style="FONT-FAMILY: 宋体;">、图</span><span lang="EN-US">7.10</span><span style="FONT-FAMILY: 宋体;">所示。</span></p><table cellspacing="0" cellpadding="0" border="0"><tbody><tr><td class="Normal" valign="top" width="276"><p align="center" style="LINE-HEIGHT: 18pt; TEXT-ALIGN: center;"><b><span lang="EN-US"><img height="148" src="mk:@MSITStore:H:\200541352851453.chm::/10.files/image049.gif" width="224" vshapes="_x0000_i1056" alt=""/> </span></b></p><p align="center" style="LINE-HEIGHT: 18pt; TEXT-ALIGN: center;"><b><span style="FONT-FAMILY: 宋体;">图</span>7.9&nbsp;&nbsp;&nbsp;&nbsp; </b><b><span style="FONT-FAMILY: 宋体;">原图</span><span lang="EN-US"></span></b></p></td><td class="Normal" valign="top" width="276"><p class="a" style="LINE-HEIGHT: 18pt;"><span lang="EN-US"><img height="148" src="mk:@MSITStore:H:\200541352851453.chm::/10.files/image051.gif" width="224" vshapes="_x0000_i1057" alt=""/> </span></p><p align="center" style="LINE-HEIGHT: 18pt; TEXT-ALIGN: center;"><b><span style="FONT-FAMILY: 宋体;">图</span>7.10&nbsp;&nbsp; </b><b><span style="FONT-FAMILY: 宋体;">轮廓提取</span><span lang="EN-US"></span></b></p></td></tr></tbody></table><p style="LINE-HEIGHT: 18pt;"><span style="FONT-FAMILY: 宋体;">轮廓提取的算法非常简单,就是掏空内部点:如果原图中有一点为黑,且它的</span><span lang="EN-US">8</span><span style="FONT-FAMILY: 宋体;">个相邻点都是黑色时</span><span lang="EN-US">(</span><span style="FONT-FAMILY: 宋体;">此时该点是内部点</span><span lang="EN-US">)</span><span style="FONT-FAMILY: 宋体;">,则将该点删除。要注意的是,我们处理的虽然是二值图,但实际上是</span><span lang="EN-US">256</span><span style="FONT-FAMILY: 宋体;">级灰度图,不过只用到了</span><span lang="EN-US">0</span><span style="FONT-FAMILY: 宋体;">和</span><span lang="EN-US">255</span><span style="FONT-FAMILY: 宋体;">两种颜色。源程序如下:</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">BOOL Outline(HWND hWnd)</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">{</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>DWORD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OffBits,BufSize;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp; </span>&nbsp; LPBITMAPINFOHEADER&nbsp;&nbsp;&nbsp; lpImgData;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>LPSTR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; lpPtr;</p><p style="LINE-HEIGHT: 18pt;">HLOCAL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hTempImgData;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>LPBITMAPINFOHEADER&nbsp;&nbsp;&nbsp; lpTempImgData;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>LPSTR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; lpTempPtr;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>HDC&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hDc;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>HFILE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hf;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>LONG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; x,y;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; num;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nw,n,ne,w,e,sw,s,se;</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">//</span><span style="FONT-FAMILY: 宋体;">我们处理的实际上是</span><span lang="EN-US">256</span><span style="FONT-FAMILY: 宋体;">级灰度图,不过只用到了</span><span lang="EN-US">0</span><span style="FONT-FAMILY: 宋体;">和</span><span lang="EN-US">255</span><span style="FONT-FAMILY: 宋体;">两种颜色。</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">if( NumColors!=256){ </span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">MessageBox(hWnd,"Must be a mono bitmap with grayscale palette!",</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">"Error Message",MB_OK|MB_ICONEXCLAMATION);</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">return FALSE;</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">}</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">OffBits=bf.bfOffBits-sizeof(BITMAPFILEHEADER);</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">//BufSize</span><span style="FONT-FAMILY: 宋体;">为缓冲区大小</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>BufSize=OffBits+bi.biHeight*LineBytes;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//<span style="FONT-FAMILY: 宋体;">为新图缓冲区分配内存</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if((hTempImgData=LocalAlloc(LHND,BufSize))==NULL)</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp; </span>{</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp; </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MessageBox(hWnd,"Error alloc memory!","Error Message",MB_OK|</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">MB_ICONEXCLAMATION);</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">return FALSE;</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp; </span>}</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp; </span>&nbsp; lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData);&nbsp;&nbsp;&nbsp; </p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>lpTempImgData=(LPBITMAPINFOHEADER)LocalLock(hTempImgData);</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">//</span><span style="FONT-FAMILY: 宋体;">拷贝头信息和位图数据</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>memcpy(lpTempImgData,lpImgData,BufSize);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>for (y=1;y&lt;bi.biHeight-1;y++){ //<span style="FONT-FAMILY: 宋体;">注意</span><span lang="EN-US">y</span><span style="FONT-FAMILY: 宋体;">的范围是从</span><span lang="EN-US">1</span><span style="FONT-FAMILY: 宋体;">到高度</span><span lang="EN-US">-2</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//lpPtr<span style="FONT-FAMILY: 宋体;">指向原图数据,</span><span lang="EN-US">lpTempPtr</span><span style="FONT-FAMILY: 宋体;">指向新图数据</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>lpPtr=(char *)lpImgData+(BufSize-LineBytes-y*LineBytes);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>lpTempPtr=(char *)lpTempImgData+(BufSize-LineBytes-y*LineBytes);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>for (x=1;x&lt;bi.biWidth-1;x++){</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if(*(lpPtr+x)==0){ //<span style="FONT-FAMILY: 宋体;">是个黑点</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//<span style="FONT-FAMILY: 宋体;">查找八个相邻点</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>nw=(unsigned char)*(lpPtr+x+LineBytes-1);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>n=(unsigned char)*(lpPtr+x+LineBytes);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>ne=(unsigned char)*(lpPtr+x+LineBytes+1);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>w=(unsigned char)*(lpPtr+x-1);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>e=(unsigned char)*(lpPtr+x+1);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>sw=(unsigned char)*(lpPtr+x-LineBytes-1);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>s=(unsigned char)*(lpPtr+x-LineBytes);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>se=(unsigned char)*(lpPtr+x-LineBytes+1);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>num=nw+n+ne+w+e+sw+s+se;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if(num==0) //<span style="FONT-FAMILY: 宋体;">说明都是黑点</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>*(lpTempPtr+x)=(unsigned char)255; //<span style="FONT-FAMILY: 宋体;">删除该黑点</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp; </span>&nbsp; if(hBitmap!=NULL)</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;&nbsp;&nbsp; DeleteObject(hBitmap);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>hDc=GetDC(hWnd);&nbsp;&nbsp;&nbsp;&nbsp; </p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//<span style="FONT-FAMILY: 宋体;">创立一个新的位图</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>hBitmap=CreateDIBitmap(hDc,(LPBITMAPINFOHEADER)lpTempImgData,</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">(LONG)CBM_INIT,</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">(LPSTR)lpTempImgData+</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">sizeof(BITMAPINFOHEADER)+</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">NumColors*sizeof(RGBQUAD),</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">(LPBITMAPINFO)lpTempImgData,</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">DIB_RGB_COLORS);</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">hf=_lcreat("c:\\outline.bmp",0);</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>_lwrite(hf,(LPSTR)&amp;bf,sizeof(BITMAPFILEHEADER)); </p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>_lwrite(hf,(LPSTR)lpTempImgData,BufSize);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>_lclose(hf);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//<span style="FONT-FAMILY: 宋体;">释放内存和资源</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;</span>&nbsp;&nbsp;&nbsp;&nbsp; ReleaseDC(hWnd,hDc);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>LocalUnlock(hTempImgData);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>LocalFree(hTempImgData);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>GlobalUnlock(hImgData);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>return TRUE;</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">}</span></p><h2><span lang="EN-US">7.4</span> <span lang="EN-US"></span><a name="_Toc486331901"></a><a name="_Toc486332901"></a><a name="_Toc486339010"></a><a name="_Toc454810875"></a><a name="_Toc454856649"><span><span>种子填充</span></span></a></h2><p style="LINE-HEIGHT: 18pt;"><span style="FONT-FAMILY: 宋体;">种子填充算法用来在封闭曲线形成的环中填充某中颜色,在这里我们只填充黑色。</span></p><p style="LINE-HEIGHT: 18pt;"><span style="FONT-FAMILY: 宋体;">种子填充其实上是图形学中的算法,其原理是:准备一个堆栈,先将要填充的点</span><span lang="EN-US">push</span><span style="FONT-FAMILY: 宋体;">进堆栈中;以后,每</span><span lang="EN-US">pop</span><span style="FONT-FAMILY: 宋体;">出一个点,将该点涂成黑色,然后按左上右下的顺序查看它的四个相邻点,若为白</span><span lang="EN-US">(</span><span style="FONT-FAMILY: 宋体;">表示还没有填充</span><span lang="EN-US">)</span><span style="FONT-FAMILY: 宋体;">,则将该邻点</span><span lang="EN-US">push</span><span style="FONT-FAMILY: 宋体;">进栈。一直循环,直到堆栈为空。此时,区域内所有的点都被涂成了黑色。</span></p><p style="LINE-HEIGHT: 18pt;"><span style="FONT-FAMILY: 宋体;">这里,我们自己定义了一些堆栈的数据结构和操作,实现了堆栈的初始化、</span><span lang="EN-US">push</span><span style="FONT-FAMILY: 宋体;">、</span><span lang="EN-US">pop</span><span style="FONT-FAMILY: 宋体;">、判断是否为空、及析构。</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">//</span><span style="FONT-FAMILY: 宋体;">堆栈结构</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">typedef struct{</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp; HGLOBAL hMem; //<span style="FONT-FAMILY: 宋体;">堆栈全局内存句柄</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp; </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;POINT *lpMyStack; //<span style="FONT-FAMILY: 宋体;">指向该句柄的指针</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp; LONG&nbsp; ElementsNum; //<span style="FONT-FAMILY: 宋体;">堆栈的大小</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp; LONG&nbsp; ptr; //<span style="FONT-FAMILY: 宋体;">指向栈顶的指针</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp; }MYSTACK;</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">//</span><span style="FONT-FAMILY: 宋体;">初始化堆栈的操作,第二个参数指定堆栈的大小</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">BOOL InitStack(HWND hWnd,LONG StackLen)</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">{</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>SeedFillStack.ElementsNum=StackLen; //<span style="FONT-FAMILY: 宋体;">将堆栈的大小赋值</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if((SeedFillStack.hMem=GlobalAlloc(GHND,SeedFillStack.ElementsNum*</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">sizeof(POINT)))==NULL)</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//<span style="FONT-FAMILY: 宋体;">内存分配错误,返回</span><span lang="EN-US">FALSE;</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp; </span>&nbsp; MessageBox(hWnd,"Error alloc memory!","ErrorMessage",MB_OK|</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">MB_ICONEXCLAMATION);</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>return FALSE;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>SeedFillStack.lpMyStack=(POINT *)GlobalLock(SeedFillStack.hMem);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//<span style="FONT-FAMILY: 宋体;">缓冲区全部清零</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">memset(SeedFillStack.lpMyStack,0,SeedFillStack.ElementsNum*</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">sizeof(POINT));</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">//</span><span style="FONT-FAMILY: 宋体;">堆顶指针为零</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>SeedFillStack.ptr=0;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//<span style="FONT-FAMILY: 宋体;">成功,返回</span><span lang="EN-US">TRUE</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>return TRUE;</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">}</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">//</span><span style="FONT-FAMILY: 宋体;">析构函数</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">void DeInitStack()</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">{</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//<span style="FONT-FAMILY: 宋体;">释放内存,重置堆栈大小及栈顶指针。</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>GlobalUnlock(SeedFillStack.hMem);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>GlobalFree(SeedFillStack.hMem);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>SeedFillStack.ElementsNum=0;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>SeedFillStack.ptr=0;</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">}</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">//push</span><span style="FONT-FAMILY: 宋体;">操作</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">BOOL MyPush(POINT p)</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">{</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>POINT *TempPtr;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if(SeedFillStack.ptr&gt;=SeedFillStack.ElementsNum) </p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>return FALSE; //<span style="FONT-FAMILY: 宋体;">栈已满,返回</span><span lang="EN-US">FALSE</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//<span style="FONT-FAMILY: 宋体;">进栈,栈顶指针加</span><span lang="EN-US">1</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>TempPtr=(POINT *)(SeedFillStack.lpMyStack+SeedFillStack.ptr++);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>(*TempPtr).x=p.x;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>(*TempPtr).y=p.y;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>return TRUE;</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">}</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">//pop</span><span style="FONT-FAMILY: 宋体;">操作</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">POINT MyPop()</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">{</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>POINT InvalidP;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>InvalidP.x=-1;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>InvalidP.y=-1;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if(SeedFillStack.ptr&lt;=0)</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>return InvalidP; //<span style="FONT-FAMILY: 宋体;">栈为空,返回无效点</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>SeedFillStack.ptr--; //<span style="FONT-FAMILY: 宋体;">栈顶指针减</span><span lang="EN-US">1</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//<span style="FONT-FAMILY: 宋体;">返回栈顶点</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>return *(SeedFillStack.lpMyStack+SeedFillStack.ptr);</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">}</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">//</span><span style="FONT-FAMILY: 宋体;">判断堆栈是否为空</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">BOOL IsStackEmpty()</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">{</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>return (SeedFillStack.ptr==0)?TRUE:FALSE;</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">}</span><span lang="EN-US" style="FONT-SIZE: 9pt;"></span></p><p style="LINE-HEIGHT: 18pt;"><span style="FONT-FAMILY: 宋体;">如果读者对堆栈的概念还不清楚,请参阅有关数据结构方面的书籍,这里就不详述了。</span></p><p style="LINE-HEIGHT: 18pt;"><span style="FONT-FAMILY: 宋体;">要注意的是:</span><span lang="EN-US">(1)</span><span style="FONT-FAMILY: 宋体;">要填充的区域是封闭的;</span><span lang="EN-US">(2)</span><span style="FONT-FAMILY: 宋体;">我们处理的虽然是二值图,但实际上是</span><span lang="EN-US">256</span><span style="FONT-FAMILY: 宋体;">级灰度图,不过只用到了</span><span lang="EN-US">0</span><span style="FONT-FAMILY: 宋体;">和</span><span lang="EN-US">255</span><span style="FONT-FAMILY: 宋体;">两种颜色;</span><span lang="EN-US">(3)</span><span style="FONT-FAMILY: 宋体;">在菜单中选择种子填充命令时,提示用户用鼠标点取一个要填充区域中的点,处理是在</span><span lang="EN-US">WM_LBUTTONDOWN</span><span style="FONT-FAMILY: 宋体;">中。</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">MYSTACK SeedFillStack;</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">BOOL SeedFill(HWND hWnd)</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">{</span></p><p style="LINE-HEIGHT: 18pt;">DWORD&nbsp;&nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OffBits,BufSize;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp; </span>&nbsp; LPBITMAPINFOHEADER&nbsp;&nbsp;&nbsp; lpImgData;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>HLOCAL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; hTempImgData;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>LPBITMAPINFOHEADER&nbsp;&nbsp;&nbsp; lpTempImgData;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>LPSTR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; lpTempPtr,lpTempPtr1;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>HDC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hDc;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>HFILE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hf;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>POINT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; CurP,NeighborP;</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">//</span><span style="FONT-FAMILY: 宋体;">我们处理的实际上是</span><span lang="EN-US">256</span><span style="FONT-FAMILY: 宋体;">级灰度图,不过只用到了</span><span lang="EN-US">0</span><span style="FONT-FAMILY: 宋体;">和</span><span lang="EN-US">255</span><span style="FONT-FAMILY: 宋体;">两种颜色。</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if( NumColors!=256){</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">MessageBox(hWnd,"Must be a mono bitmap with grayscale palette!",</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">"Error Message",MB_OK|MB_ICONEXCLAMATION);</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">return FALSE;</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">}</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">OffBits=bf.bfOffBits-sizeof(BITMAPFILEHEADER);</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">//BufSize</span><span style="FONT-FAMILY: 宋体;">为缓冲区大小</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>BufSize=OffBits+bi.biHeight*LineBytes;</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">//</span><span style="FONT-FAMILY: 宋体;">为新图缓冲区分配内存</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if((hTempImgData=LocalAlloc(LHND,BufSize))==NULL)</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp; </span>{</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp; </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MessageBox(hWnd,"Error alloc memory!","Error Message",MB_OK|</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">MB_ICONEXCLAMATION);</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">return FALSE;</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp; </span>}</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp; </span>&nbsp; lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData);&nbsp;&nbsp;&nbsp; </p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>lpTempImgData=(LPBITMAPINFOHEADER)LocalLock(hTempImgData);</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">//</span><span style="FONT-FAMILY: 宋体;">拷贝头信息和位图数据</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>memcpy(lpTempImgData,lpImgData,BufSize);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if(!InitStack(hWnd,(LONG)bi.biHeight*bi.biWidth)){&nbsp; //<span style="FONT-FAMILY: 宋体;">初始化堆栈</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//<span style="FONT-FAMILY: 宋体;">若失败,释放内存,返回</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>LocalUnlock(hTempImgData);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>LocalFree(hTempImgData);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>GlobalUnlock(hImgData);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>return FALSE;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>lpTempPtr=(char*)lpTempImgData+</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">(BufSize-LineBytes-SeedPoint.y*LineBytes)+SeedPoint.x;</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if(*lpTempPtr==0){</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//<span style="FONT-FAMILY: 宋体;">鼠标点到了黑点上,提示用户不能选择边界上的点,返回</span><span lang="EN-US">FALSE</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">MessageBox(hWnd,"The point you select is a contour point!",</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">"Error Message",MB_OK|MB_ICONEXCLAMATION);</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>LocalUnlock(hTempImgData);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>LocalFree(hTempImgData);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>GlobalUnlock(hImgData);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>DeInitStack();</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">return FALSE;</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//push<span style="FONT-FAMILY: 宋体;">该点</span><span lang="EN-US">(</span><span style="FONT-FAMILY: 宋体;">用户用鼠标选择的,处理是在</span><span lang="EN-US">WM_LBUTTONDOWN</span><span style="FONT-FAMILY: 宋体;">中</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>MyPush(SeedPoint);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>while(!IsStackEmpty()) //<span style="FONT-FAMILY: 宋体;">堆栈不空则一直处理</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>CurP=MyPop(); //pop<span style="FONT-FAMILY: 宋体;">栈顶的点</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>lpTempPtr=(char*)lpTempImgData+</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">(BufSize-LineBytes-CurP.y*LineBytes)+CurP.x;</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//<span style="FONT-FAMILY: 宋体;">将该点涂黑</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>*lpTempPtr=(unsigned char)0;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//<span style="FONT-FAMILY: 宋体;">左邻点</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if(CurP.x&gt;0) //<span style="FONT-FAMILY: 宋体;">注意判断边界</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>NeighborP.x=CurP.x-1;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>NeighborP.y=CurP.y;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>lpTempPtr1=lpTempPtr-1;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if(*lpTempPtr1!=0) //<span style="FONT-FAMILY: 宋体;">如果为白,表示还没有填,进栈</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>MyPush(NeighborP);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">//</span><span style="FONT-FAMILY: 宋体;">上邻点</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if(CurP.y&gt;0) //<span style="FONT-FAMILY: 宋体;">注意判断边界</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>NeighborP.x=CurP.x;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>NeighborP.y=CurP.y-1;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>lpTempPtr1=lpTempPtr+LineBytes;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if(*lpTempPtr1!=0) //<span style="FONT-FAMILY: 宋体;">如果为白,表示还没有填,进栈</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>MyPush(NeighborP);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">//</span><span style="FONT-FAMILY: 宋体;">右邻点</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if(CurP.x&lt;bi.biWidth-1) //<span style="FONT-FAMILY: 宋体;">注意判断边界</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>NeighborP.x=CurP.x+1;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>NeighborP.y=CurP.y;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>lpTempPtr1=lpTempPtr+1;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if(*lpTempPtr1!=0) //<span style="FONT-FAMILY: 宋体;">如果为白,表示还没有填,进栈</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>MyPush(NeighborP);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//<span style="FONT-FAMILY: 宋体;">下邻点</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if(CurP.y&lt;bi.biHeight-1) //<span style="FONT-FAMILY: 宋体;">注意判断边界</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>NeighborP.x=CurP.x;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>NeighborP.y=CurP.y+1;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>lpTempPtr1=lpTempPtr-LineBytes;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if(*lpTempPtr1!=0) //<span style="FONT-FAMILY: 宋体;">如果为白,表示还没有填,进栈</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>MyPush(NeighborP);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//<span style="FONT-FAMILY: 宋体;">析构堆栈,释放内存</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>DeInitStack();</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">if(hBitmap!=NULL)</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;&nbsp;&nbsp; DeleteObject(hBitmap);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>hDc=GetDC(hWnd);&nbsp;&nbsp;&nbsp;&nbsp; </p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//<span style="FONT-FAMILY: 宋体;">创建新的位图</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>hBitmap=CreateDIBitmap(hDc,(LPBITMAPINFOHEADER)lpTempImgData,</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">(LONG)CBM_INIT,</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">(LPSTR)lpTempImgData+</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">sizeof(BITMAPINFOHEADER)+</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">NumColors*sizeof(RGBQUAD),</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">(LPBITMAPINFO)lpTempImgData,</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">DIB_RGB_COLORS);</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>hf=_lcreat("c:\\seed.bmp",0);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>_lwrite(hf,(LPSTR)&amp;bf,sizeof(BITMAPFILEHEADER)); </p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>_lwrite(hf,(LPSTR)lpTempImgData,BufSize);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>_lclose(hf);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//<span style="FONT-FAMILY: 宋体;">释放内存和资源</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;</span>&nbsp;&nbsp;&nbsp;&nbsp; ReleaseDC(hWnd,hDc);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>LocalUnlock(hTempImgData);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>LocalFree(hTempImgData);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>GlobalUnlock(hImgData);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>return TRUE;</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">}</span></p><h2><span lang="EN-US">7.5</span> <span lang="EN-US"></span><a name="_Toc486331902"></a><a name="_Toc486332902"></a><a name="_Toc486339011"></a><a name="_Toc454810876"></a><a name="_Toc454856650"><span><span>轮廓跟踪</span></span></a></h2><p style="LINE-HEIGHT: 18pt;"><span style="FONT-FAMILY: 宋体;">轮廓跟踪,顾名思义就是通过顺序找出边缘点来跟踪出边界。图</span><span lang="EN-US">7.9</span><span style="FONT-FAMILY: 宋体;">经轮廓跟踪后得到的结果如图</span><span lang="EN-US">7.11</span><span style="FONT-FAMILY: 宋体;">所示。</span></p><p align="center" style="LINE-HEIGHT: 18pt; TEXT-ALIGN: center;"><span lang="EN-US"><img height="148" src="mk:@MSITStore:H:\200541352851453.chm::/10.files/image053.gif" width="224" vshapes="_x0000_i1058" alt=""/> </span></p><p align="center" style="LINE-HEIGHT: 18pt; TEXT-ALIGN: center;"><b><span style="FONT-FAMILY: 宋体;">图</span>7.11&nbsp;&nbsp;&nbsp; </b><b><span style="FONT-FAMILY: 宋体;">图</span><span lang="EN-US">7.9</span></b><b><span style="FONT-FAMILY: 宋体;">轮廓跟踪后的结果</span><span lang="EN-US"></span></b></p><p style="LINE-HEIGHT: 18pt;"><span style="FONT-FAMILY: 宋体;">一个简单二值图象闭合边界的轮廓跟踪算法很简单:首先按从上到下,从左到右的顺序搜索,找到的第一个黑点一定是最左上方的边界点,记为</span><span lang="EN-US">A</span><span style="FONT-FAMILY: 宋体;">。它的右,右下,下,左下四个邻点中至少有一个是边界点,记为</span><span lang="EN-US">B</span><span style="FONT-FAMILY: 宋体;">。从开始</span><span lang="EN-US">B</span><span style="FONT-FAMILY: 宋体;">找起,按右,右下,下,左下,左,左上,上,右上的顺序找相邻点中的边界点</span><span lang="EN-US">C</span><span style="FONT-FAMILY: 宋体;">。如果</span><span lang="EN-US">C</span><span style="FONT-FAMILY: 宋体;">就是</span><span lang="EN-US">A</span><span style="FONT-FAMILY: 宋体;">点,则表明已经转了一圈,程序结束;否则从</span><span lang="EN-US">C</span><span style="FONT-FAMILY: 宋体;">点继续找,直到找到</span><span lang="EN-US">A</span><span style="FONT-FAMILY: 宋体;">为止。判断是不是边界点很容易:如果它的上下左右四个邻居都是黑点则不是边界点,否则是边界点。源程序如下,其中函数</span><span lang="EN-US">IsContourP</span><span style="FONT-FAMILY: 宋体;">用来判断某点是不是边界点。</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">BOOL Contour(HWND hWnd)</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">{</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>DWORD&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OffBits<span style="FONT-FAMILY: 宋体;">,</span><span lang="EN-US">BufSize;</span></p><p style="LINE-HEIGHT: 18pt;">LPBITMAPINFOHEADER&nbsp;&nbsp;&nbsp; lpImgData;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>LPSTR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; lpPtr;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>HLOCAL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; hTempImgData;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>LPBITMAPINFOHEADER&nbsp;&nbsp;&nbsp; lpTempImgData;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>LPSTR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; lpTempPtr;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>HDC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hDc;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>HFILE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hf;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>LONG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; x,y;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>POINT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; StartP,CurP;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>BOOL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; found;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i;</p><p style="LINE-HEIGHT: 18pt;">int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; direct={{1,0},{1,1},{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1}};</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">//</span><span style="FONT-FAMILY: 宋体;">我们处理的实际上是</span><span lang="EN-US">256</span><span style="FONT-FAMILY: 宋体;">级灰度图,不过只用到了</span><span lang="EN-US">0</span><span style="FONT-FAMILY: 宋体;">和</span><span lang="EN-US">255</span><span style="FONT-FAMILY: 宋体;">两种颜色。</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if( NumColors!=256){</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">MessageBox(hWnd,"Must be a mono bitmap with grayscale palette!",</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">"Error Message",MB_OK|MB_ICONEXCLAMATION);</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">return FALSE;</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">}</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">//</span><span style="FONT-FAMILY: 宋体;">到位图数据的偏移值</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>OffBits=bf.bfOffBits-sizeof(BITMAPFILEHEADER);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//<span style="FONT-FAMILY: 宋体;">缓冲区大小</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">BufSize=OffBits+bi.biHeight*LineBytes;</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">//</span><span style="FONT-FAMILY: 宋体;">为新图缓冲区分配内存</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if((hTempImgData=LocalAlloc(LHND,BufSize))==NULL)</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp; </span>&nbsp; {</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>MessageBox(hWnd,"Error alloc memory!","Error Message",</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">MB_OK|MB_ICONEXCLAMATION);</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">return FALSE;</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">}</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp; </span>&nbsp;&nbsp;&nbsp; lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>lpTempImgData=(LPBITMAPINFOHEADER)LocalLock(hTempImgData);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//<span style="FONT-FAMILY: 宋体;">新图缓冲区初始化为</span><span lang="EN-US">255</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>memset(lpTempImgData,(BYTE)255,BufSize);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//<span style="FONT-FAMILY: 宋体;">拷贝头信息</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>memcpy(lpTempImgData,lpImgData,OffBits);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//<span style="FONT-FAMILY: 宋体;">找到标志置为假</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>found=FALSE;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>for (y=0;y&lt;bi.biHeight &amp;&amp; !found; y++){</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>lpPtr=(char *)lpImgData+(BufSize-LineBytes-y*LineBytes);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>for (x=0;x&lt;bi.biWidth &amp;&amp; !found; x++)</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if (*(lpPtr++) ==0) found=TRUE; </p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">//</span><span style="FONT-FAMILY: 宋体;">找到了最左上的黑点,一定是个边界点</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if(found){ //<span style="FONT-FAMILY: 宋体;">如果找到了,才做处理</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">//</span><span style="FONT-FAMILY: 宋体;">从循环退出时,</span><span lang="EN-US">x</span><span style="FONT-FAMILY: 宋体;">,</span><span lang="EN-US">y</span><span style="FONT-FAMILY: 宋体;">坐标都做了加</span><span lang="EN-US">1</span><span style="FONT-FAMILY: 宋体;">的操作。在这里把它们减</span><span lang="EN-US">1</span><span style="FONT-FAMILY: 宋体;">,得到</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">//</span><span style="FONT-FAMILY: 宋体;">起始点坐标</span><span lang="EN-US">StartP</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>StartP.x=x-1;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>StartP.y=y-1;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>lpTempPtr=(char*)lpTempImgData+</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">(BufSize-LineBytes-StartP.y*LineBytes)+StartP.x;</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>*lpTempPtr=(unsigned char)0; //<span style="FONT-FAMILY: 宋体;">起始点涂黑</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//<span style="FONT-FAMILY: 宋体;">右邻点</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp; </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CurP.x=StartP.x+1;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>CurP.y=StartP.y;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>lpPtr=(char *)lpImgData+(BufSize-LineBytes-CurP.y*LineBytes)+CurP.x;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if(*lpPtr!=0){ //<span style="FONT-FAMILY: 宋体;">若右邻点为白,则找右下邻点</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CurP.x=StartP.x+1;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>CurP.y=StartP.y+1;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>lpPtr=(char*)lpImgData+</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">(BufSize-LineBytes-CurP.y*LineBytes)+CurP.x;</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if(*lpPtr!=0){ //<span style="FONT-FAMILY: 宋体;">若仍为白,则找下邻点</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CurP.x=StartP.x;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>CurP.y=StartP.y+1;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>else{ //<span style="FONT-FAMILY: 宋体;">若仍为白,则找左下邻点</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CurP.x=StartP.x-1;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>CurP.y=StartP.y+1;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>while (! ( (CurP.x==StartP.x) &amp;&amp;(CurP.y==StartP.y))){ //<span style="FONT-FAMILY: 宋体;">知道找到起始点,</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">//</span><span style="FONT-FAMILY: 宋体;">循环才结束</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>lpTempPtr=(char*)lpTempImgData+</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">(BufSize-LineBytes-CurP.y*LineBytes)+CurP.x;</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>*lpTempPtr=(unsigned char)0;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>for(i=0;i&lt;8;i++){ </p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">//</span><span style="FONT-FAMILY: 宋体;">按右,右上,上,左上,左,左下,下,右下的顺序找相邻点</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">//direct</span><span style="FONT-FAMILY: 宋体;">中存放的是该方向</span><span lang="EN-US">x,y</span><span style="FONT-FAMILY: 宋体;">的偏移值</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>x=CurP.x+direct;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>y=CurP.y+direct;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//lpPtr<span style="FONT-FAMILY: 宋体;">指向原图数据,</span><span lang="EN-US">lpTempPtr</span><span style="FONT-FAMILY: 宋体;">指向新图数据</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>lpTempPtr=(char*)lpTempImgData+</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">(BufSize-LineBytes-y*LineBytes)+x;</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>lpPtr=(char *)lpImgData+(BufSize-LineBytes-y*LineBytes)+x;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if(((*lpPtr==0)&amp;&amp;(*lpTempPtr!=0))||</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">((x==StartP.x)&amp;&amp;(y==StartP.y)))</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//<span style="FONT-FAMILY: 宋体;">原图中为黑点,且新图中为白点</span><span lang="EN-US">(</span><span style="FONT-FAMILY: 宋体;">表示还没搜索过</span><span lang="EN-US">)</span><span style="FONT-FAMILY: 宋体;">时才处理</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//<span style="FONT-FAMILY: 宋体;">另一种可能是找到了起始点</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(IsContourP(x,y,lpPtr)){ //<span style="FONT-FAMILY: 宋体;">若是个边界点</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //<span style="FONT-FAMILY: 宋体;">记住当前点的位置</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>CurP.x=x;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>CurP.y=y;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>break;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp; </span>&nbsp;&nbsp;if(hBitmap!=NULL)</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;&nbsp;&nbsp; DeleteObject(hBitmap);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>hDc=GetDC(hWnd);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//<span style="FONT-FAMILY: 宋体;">创立一个新的位图</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>hBitmap=CreateDIBitmap(hDc,(LPBITMAPINFOHEADER)lpTempImgData,</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">(LONG)CBM_INIT,</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">(LPSTR)lpTempImgData+</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">sizeof(BITMAPINFOHEADER)+</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">NumColors*sizeof(RGBQUAD),</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (LPBITMAPINFO)lpTempImgData,</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">DIB_RGB_COLORS);</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>hf=_lcreat("c:\\contour.bmp",0);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>_lwrite(hf,(LPSTR)&amp;bf,sizeof(BITMAPFILEHEADER)); </p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>_lwrite(hf,(LPSTR)lpTempImgData,BufSize);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>_lclose(hf);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//<span style="FONT-FAMILY: 宋体;">释放内存和资源</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;</span>&nbsp;&nbsp;&nbsp;&nbsp; ReleaseDC(hWnd,hDc);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>LocalUnlock(hTempImgData);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>LocalFree(hTempImgData);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>GlobalUnlock(hImgData);</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>return TRUE;</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">}</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">//</span><span style="FONT-FAMILY: 宋体;">判断某点是不是边界点,参数</span><span lang="EN-US">x,y </span><span style="FONT-FAMILY: 宋体;">为该点坐标,</span><span lang="EN-US">lpPtr</span><span style="FONT-FAMILY: 宋体;">为指向原数据的指针</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">BOOL IsContourP(LONG x,LONG y, char *lpPtr)</span></p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">{</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>int&nbsp;&nbsp;&nbsp; num,n,w,e,s;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>n=(unsigned char)*(lpPtr+LineBytes); //<span style="FONT-FAMILY: 宋体;">上邻点</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>w=(unsigned char)*(lpPtr-1); //<span style="FONT-FAMILY: 宋体;">左邻点</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>e=(unsigned char)*(lpPtr+1); //<span style="FONT-FAMILY: 宋体;">右邻点</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>s=(unsigned char)*(lpPtr-LineBytes); //<span style="FONT-FAMILY: 宋体;">下邻点</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>num=n+w+e+s;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if(num==0) //<span style="FONT-FAMILY: 宋体;">全是黑点,说明是个内部点而不是边界点</span></p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>return FALSE;</p><p style="LINE-HEIGHT: 18pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>return TRUE;</p><p style="LINE-HEIGHT: 18pt;"><span lang="EN-US">}</span></p></div><div style="DISPLAY: block; FONT-SIZE: 10px; FONT-FAMILY: Verdana, Geneva, Arial;">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 </div>

狱火玄冰 发表于 2011-5-1 13:47

看不懂啊啊

headkarl 发表于 2011-12-2 14:55

我这里看图像都挂了,还有很多划线...LZ检查一下吧

jiatianjie 发表于 2012-9-1 12:13

LZ我感觉要不用个压缩文件上传好了,版型都乱了。
页: [1]
查看完整版本: 数字图像处理编程---7边沿检测与提取,轮廓跟踪