边缘检测和轮廓提取方法和VC++程序
- 格式:doc
- 大小:181.50 KB
- 文档页数:14
图像特征提取方法详解图像特征提取是计算机视觉和图像处理领域中的一个重要任务,它是对图像中的信息进行分析和提取,以便进行后续的图像识别、分类和分析。
在图像处理和计算机视觉应用中,图像特征提取是至关重要的一步,因为它直接影响了后续处理的结果。
一、图像特征的概念图像特征是指图像中能够表征其内容和结构的可测量属性。
常见的图像特征包括颜色、纹理、形状、边缘等。
这些特征可以帮助我们理解图像的含义,区分不同的物体、场景和结构。
二、图像特征提取的方法1. 颜色特征提取颜色是图像中最直观和重要的特征之一。
常用的颜色特征提取方法包括直方图统计、颜色矩和颜色空间转换。
直方图统计是通过统计图像中每种颜色出现的频率来提取颜色特征,它可以帮助我们了解图像中的主要颜色分布。
颜色矩是一种用于描述颜色分布和颜色相关性的方法,它可以帮助我们定量地比较不同图像之间的颜色特征。
颜色空间转换则是将图像的RGB颜色空间转换为其他颜色空间(如HSV、Lab等),以便更好地提取颜色特征。
2. 纹理特征提取纹理是图像中的重要特征之一,它可以帮助我们理解图像中的细节和结构。
常见的纹理特征提取方法包括灰度共生矩阵、小波变换和局部二值模式。
灰度共生矩阵是一种用于描述图像纹理结构的统计方法,它可以帮助我们了解图像中不同区域的纹理分布。
小波变换是一种多尺度分析方法,它可以帮助我们提取图像中不同尺度和方向的纹理特征。
局部二值模式是一种用于描述图像局部纹理特征的方法,它可以帮助我们快速提取图像中的纹理信息。
3. 形状特征提取形状是图像中的重要特征之一,它可以帮助我们理解图像中的对象和结构。
常见的形状特征提取方法包括边缘检测、轮廓提取和形状描述子。
边缘检测是一种用于提取图像中边缘信息的方法,它可以帮助我们理解图像中的对象轮廓和结构。
轮廓提取是一种用于提取图像中对象轮廓信息的方法,它可以帮助我们理解图像中的对象形状和结构。
形状描述子是一种用于描述图像对象形状特征的方法,它可以帮助我们快速提取图像中的形状信息。
目标轮廓提取方法目标轮廓提取是计算机视觉和图像处理领域中的一个重要任务,其主要目的是从图像中识别并提取出感兴趣目标的边界或外形。
以下是几种常用的目标轮廓提取方法:边缘检测:这是最直接的方法,主要利用边缘检测算子如Canny、Sobel、Prewitt、Roberts等,它们通过计算图像中像素点的梯度强度来确定边缘。
这种方法对于具有明显边缘特征的目标效果较好,但对于边缘模糊或复杂背景的情况可能效果不佳。
阈值分割:这是一种基于像素值的方法,首先设定一个或多个阈值,然后根据像素值与阈值的关系将图像分为不同的区域。
例如,对于二值图像,可以直接设定一个阈值,大于阈值的像素被视为目标,小于阈值的像素被视为背景。
这种方法简单快速,但对于目标与背景颜色接近或重叠的情况可能效果不佳。
形态学处理:这是一种基于数学形态学的图像处理技术,主要利用结构元素对图像进行膨胀、腐蚀、开运算、闭运算等操作,从而提取或强调目标的轮廓。
这种方法对于去除噪声、填补孔洞、断开连接等任务非常有效。
区域生长:这是一种基于种子点的方法,首先选择一个或多个种子点,然后按照一定的规则(如像素值相似、距离近等)将相邻的像素点加入到目标区域中,直到满足停止条件。
这种方法对于目标内部特征一致、背景复杂的情况效果较好。
深度学习:近年来,随着深度学习技术的发展,越来越多的研究者开始使用神经网络来提取目标轮廓。
例如,U-Net、Mask R-CNN等网络可以直接从图像中预测出目标的轮廓或分割掩码。
这种方法对于复杂场景和多变的目标形状具有较强的适应性,但需要大量的训练数据和计算资源。
总的来说,目标轮廓提取的方法多种多样,需要根据具体的应用场景和目标特性来选择合适的方法。
寻找不规则物体中心的方法介绍寻找不规则物体中心的问题是在计算机视觉和图像处理领域中的一个重要问题。
不规则物体通常指非几何形状的物体,如动物、植物等。
找到不规则物体的中心可以有助于进行物体识别、目标跟踪、形状分析等应用。
本文将介绍一些常见的方法和技术来解决这一问题。
方法一:基于颜色特征的中心点检测如果不规则物体具有明显的颜色特征,可以通过颜色的分布和密度来推测中心点的位置。
以下是一种基于颜色特征的中心点检测方法:1.预处理:将图像转换为HSV(色相、饱和度、明度)颜色空间,以便更好地提取颜色特征。
2.颜色分割:使用阈值分割或其他颜色分割方法,将感兴趣的颜色区域提取出来。
3.去除噪声:对颜色区域进行腐蚀和膨胀等形态学操作,去除杂质和噪声。
4.中心点计算:计算颜色区域的质心位置作为中心点的估计。
方法二:基于形状特征的中心点检测除了颜色特征,不规则物体的形状特征也可以用来推测中心点的位置。
以下是一种基于形状特征的中心点检测方法:1.边缘检测:使用边缘检测算法(如Canny算法)检测不规则物体的边缘。
2.轮廓提取:通过边缘检测得到的边缘图像,提取不规则物体的轮廓。
3.质心计算:计算不规则物体轮廓的质心位置作为中心点的估计。
方法三:基于机器学习的中心点检测除了基于颜色和形状特征的方法,还可以使用机器学习算法来训练模型以预测不规则物体的中心点位置。
以下是一种基于机器学习的中心点检测方法:1.数据收集:收集一组带有标注中心点位置的不规则物体图像作为训练数据。
2.特征提取:对训练数据进行特征提取,可以使用颜色和形状特征等。
3.模型训练:使用机器学习算法(如支持向量机、随机森林等)训练一个回归模型来预测中心点的位置。
4.中心点预测:对新的不规则物体图像进行特征提取,并使用训练好的模型来预测中心点的位置。
方法四:深度学习方法近年来,深度学习方法在计算机视觉领域取得了很大的成功。
也可以使用深度学习模型来解决不规则物体中心点检测问题。
图像识别中的轮廓提取算法探索引言:图像识别技术如今已经广泛应用于各个领域,其关键之一就是图像中的轮廓提取算法。
轮廓提取的准确与否直接影响到图像识别的效果。
本文将探索图像识别中常用的轮廓提取算法,并对其原理和优缺点进行分析。
一、边缘检测算法边缘检测是图像处理中最基础的一步,是进行轮廓提取的前提。
常用的边缘检测算法有Sobel算子、Laplacian算子和Canny算子等。
1. Sobel算子Sobel算子是一种基于梯度的边缘检测算法,其原理是通过计算每个像素点的梯度值来判断其是否为边缘点。
然后根据梯度值的大小确定边缘的强度,进而提取轮廓。
Sobel算子的优点是计算简单,对噪声鲁棒性强。
但其缺点也较为明显,容易产生边缘断裂的情况,并且对角线边缘检测效果较差。
2. Laplacian算子Laplacian算子是一种基于二阶导数的边缘检测算法,其原理是通过计算图像中每个像素点的二阶导数来判断其是否为边缘点。
Laplacian算子的优点是能够检测出边缘的交叉点,能够更精准地定位边缘。
但其缺点是对噪声比较敏感,容易产生误检。
3. Canny算子Canny算子是一种综合考虑多种因素的边缘检测算法,其原理是通过梯度计算、非极大值抑制和阈值处理来提取目标轮廓。
Canny算子的优点是能够提取清晰且连续的边缘,对噪声抑制效果好。
但其缺点是计算量较大,算法较为复杂。
二、区域生长算法区域生长算法是一种基于种子点的轮廓提取方法,其原理是在图像中选择若干个种子点,然后通过像素点之间的相似性判断来逐渐生长成为一个完整的区域。
区域生长算法的优点是能够提取出连续且相似的轮廓,适用于要求较高的图像识别任务。
但其缺点是对种子点的选择比较敏感,容易受到图像质量和噪声的影响。
三、边缘跟踪算法边缘跟踪算法是一种基于边缘连接的轮廓提取方法,其原理是通过追踪边缘点的连接关系,形成完整的轮廓。
边缘跟踪算法的优点是能够提取出精细的轮廓,并且对噪声抑制效果好。
计算机视觉中的轮廓线提取技术随着现代技术的迅速发展,计算机视觉技术也日渐成熟。
其中轮廓线提取技术是视觉算法中一个重要的环节,它能够从图像中提取出物体的轮廓线,为图像处理、目标检测、三维建模等应用提供基础支持。
本文将介绍计算机视觉中的轮廓线提取技术,包括方法原理、应用场景以及相关算法。
一、轮廓线提取技术原理轮廓线提取是数字图像处理中一个重要的过程,它主要通过对图像进行边缘检测和特征提取,来实现对物体轮廓线的提取。
轮廓线是物体和背景之间的边界线,它具有明显的区分度,适用于识别物体的形状、大小和位置等信息。
轮廓线提取技术的主要流程包括:1. 去噪:对原始图像进行降噪处理,使得图像更加干净,有利于后续的边缘检测和特征提取。
2. 边缘检测:经过降噪后,对图像进行边缘检测,以便提取出物体的轮廓线。
边缘检测算法主要有Sobel算子、Canny算子、Laplacian算子等。
3. 特征提取:提取边缘点,将其组成闭合的轮廓线。
常用的特征提取算法有霍夫变换、最大连通区域分析等。
二、轮廓线提取算法1. Sobel算子Sobel算子是一种边缘检测算法,在数字图像处理中广泛应用。
该算法通过对图像进行卷积操作,来提取出图像中的边缘点。
Sobel算子具有简单、易于实现的特点,但是提取出的边缘点可能不够准确,容易受到噪声的影响。
2. Canny算子Canny算子是一种比较常用的边缘检测算法,它对图像进行多次卷积操作,以提取出图像中的边缘点。
Canny算子具有高灵敏度和低误检率的特点,可以有效地提取出物体的轮廓线,受到很广泛的应用。
3. Laplacian算子Laplacian算子是一种利用二阶偏导数求解的边缘检测算法,它主要通过对图像进行拉普拉斯滤波,来提取出图像中的边缘点。
Laplacian算子具有灵敏度高、响应速度快的特点,但是容易受到噪声的干扰。
三、轮廓线提取技术的应用场景轮廓线提取技术可以应用于多个领域,如图像处理、目标检测、三维建模等。
使用图像处理技术实现图像特征提取的技巧与方法图像特征提取是图像处理领域中的一个重要任务,它旨在从图像数据中提取出有意义的特征信息,用于后续的图像分析和理解。
图像特征可以描述图像的某种属性或结构,如颜色、纹理、形状等,通过对图像进行特征提取,可以实现图像分类、目标检测、图像搜索等任务。
在实际应用中,图像特征提取的技巧和方法有很多种。
下面将介绍几种常用的图像特征提取方法。
首先是颜色特征提取技术。
颜色是图像中最直观、最容易获取和识别的特征之一。
常用的颜色特征提取方法包括直方图、颜色空间转换和颜色描述子等。
直方图能够统计图像中每个颜色的像素数目,通过对颜色直方图的分析,可以获取图像的颜色分布特征。
颜色空间转换可以将图像从RGB空间转换成其他颜色空间,如HSV、Lab等,从而提取出不同颜色通道的特征。
颜色描述子能够对图像的颜色进行定量化描述,如颜色矩、颜色矢量等。
其次是纹理特征提取技术。
纹理是指图像中像素间的某种规律或重复性,常用于描述物体表面的细节特征。
常用的纹理特征提取方法有灰度共生矩阵、小波变换和局部二值模式等。
灰度共生矩阵能够统计图像中不同像素间的灰度共生关系,通过计算共生矩阵中的纹理特征,可以获取图像的纹理信息。
小波变换能够将图像从空间域转换到频率域,通过分析不同频率的小波系数,可以提取出图像的纹理特征。
局部二值模式是一种基于像素邻域的纹理特征描述方法,通过比较像素与其邻域像素之间的灰度差异,可以刻画图像的纹理细节。
还有形状特征提取技术。
形状是物体的外形和轮廓特征,常用于目标检测和识别。
常用的形状特征提取方法有轮廓描述子、边缘检测和形状匹配等。
轮廓描述子能够基于物体的边缘轮廓提取其形状特征,如轮廓长度、曲率等。
边缘检测可以通过检测图像中的边缘信息,提取物体的形状特征。
形状匹配则是通过比较不同物体的形状特征,实现目标的检测和识别。
除了以上提到的方法,还有很多其他的图像特征提取技巧和方法,如兴趣点检测、尺度不变特征变换等。
图像处理中的边缘检测和特征提取方法图像处理是计算机视觉领域中的关键技术之一,而边缘检测和特征提取是图像处理中重要的基础操作。
边缘检测可以帮助我们分析图像中的轮廓和结构,而特征提取则有助于识别和分类图像。
本文将介绍边缘检测和特征提取的常见方法。
1. 边缘检测方法边缘检测是指在图像中找到不同区域之间的边缘或过渡的技术。
常用的边缘检测方法包括Sobel算子、Prewitt算子和Canny算子。
Sobel算子是一种基于梯度的边缘检测算法,通过对图像进行卷积操作,可以获取图像在水平和垂直方向上的梯度值,并计算获得边缘的强度和方向。
Prewitt算子也是一种基于梯度的边缘检测算法,类似于Sobel算子,但其卷积核的权重设置略有不同。
Prewitt算子同样可以提取图像的边缘信息。
Canny算子是一种常用且经典的边缘检测算法。
它结合了梯度信息和非极大值抑制算法,可以有效地检测到图像中的边缘,并且在边缘检测的同时还能削弱图像中的噪声信号。
这些边缘检测算法在实际应用中常常结合使用,选择合适的算法取决于具体的任务需求和图像特点。
2. 特征提取方法特征提取是指从原始图像中提取出具有代表性的特征,以便进行后续的图像分析、识别或分类等任务。
常用的特征提取方法包括纹理特征、形状特征和颜色特征。
纹理特征描述了图像中的纹理信息,常用的纹理特征包括灰度共生矩阵(GLCM)、局部二值模式(LBP)和方向梯度直方图(HOG)。
GLCM通过统计图像中像素之间的灰度变化分布来描述纹理特征,LBP通过比较像素与其邻域像素的灰度值来提取纹理特征,HOG则是通过计算图像中梯度的方向和强度来提取纹理特征。
这些纹理特征可以用于图像分类、目标检测等任务。
形状特征描述了图像中物体的形状信息,常用的形状特征包括边界描述子(BDS)、尺度不变特征变换(SIFT)和速度不变特征变换(SURF)。
BDS通过提取物体边界的特征点来描述形状特征,SIFT和SURF则是通过提取图像中的关键点和描述子来描述形状特征。
数字图像轮廓提取方法数字图像轮廓提取是计算机视觉和图像处理领域中的一个重要任务,它在图像分析、形状识别和目标检测等方面有广泛的应用。
本文将介绍几种常用的数字图像轮廓提取方法,并对它们的优缺点进行讨论。
一、边缘检测边缘检测是最常用的数字图像轮廓提取方法之一。
它通过分析图像中像素灰度值的变化来确定物体的边缘。
常用的边缘检测算法包括Sobel算子、Prewitt算子和Canny算子等。
1. Sobel算子Sobel算子是一种基于梯度的算法。
它通过对图像进行卷积操作来计算图像在水平和垂直方向上的梯度值,然后将两个梯度值平方和开方得到最终的边缘强度。
Sobel算子简单易实现,对噪声具有一定的抑制作用,但边缘提取结果可能比较粗糙。
2. Prewitt算子Prewitt算子也是一种基于梯度的算法,它与Sobel算子类似,但使用了不同的卷积核。
Prewitt算子对噪声的抑制能力较差,但边缘提取结果较为精细。
3. Canny算子Canny算子是一种基于多阶段处理的算法,它首先对图像进行高斯滤波以平滑图像,然后计算图像梯度,接着使用非极大值抑制方法提取边缘,最后通过双阈值处理来连接边缘。
Canny算子精度较高,能够有效地提取细节边缘,但对参数设置要求较高。
二、形态学轮廓形态学轮廓是基于数学形态学原理的一种轮廓提取方法。
它利用图像形态学的操作,如腐蚀和膨胀,来提取图像中的物体轮廓。
形态学轮廓通常应用于二值图像,先对图像进行二值化处理,然后利用形态学操作来提取轮廓。
1. 腐蚀腐蚀是形态学中常用的操作之一,它通过将图像中的物体边缘向内缩小,同时抑制噪声和细小的边缘分支。
腐蚀操作可以得到物体的骨架轮廓。
2. 膨胀膨胀是形态学中的另一种操作,它通过将图像中的物体边缘向外扩张,填充物体间的空隙,从而使轮廓更加完整。
膨胀操作可以得到物体的外轮廓。
形态学轮廓方法简单易懂,对噪声具有一定的抑制作用,但提取结果可能比较粗糙,且对图像中物体的尺寸和形状敏感。
轮廓特征提取
轮廓特征提取是一种常用的图像处理技术,用于从图像中提取物体的轮廓信息。
这种技术可以应用于许多领域,例如医学图像分析、工业自动化、机器人视觉等。
轮廓特征提取的主要步骤包括:
1. 边缘检测:通过应用一些算法,如Canny算子、Sobel滤波器等,从图像中提取出物体的边缘。
2. 轮廓提取:在边缘检测的基础上,通过对边缘进行处理,提取出物体的轮廓。
常用的轮廓提取算法包括分水岭算法、连通域分析等。
3. 特征提取:在得到物体的轮廓后,可以通过一些特征提取方法,如Hu不变矩、Zernike矩、傅里叶描述子等,提取出物体的形状、纹理等特征信息。
轮廓特征提取的应用非常广泛,例如在医学图像分析中,可以通过提取肿瘤轮廓的特征信息,对肿瘤进行识别和分类;在工业自动化中,可以通过提取产品轮廓的特征信息,实现自动检测和质量控制;在机器人视觉中,可以通过提取环境中物体的轮廓特征,实现机器人的感知和导航等功能。
- 1 -。
opencv曲线提取点坐标
在OpenCV中,要提取曲线上的点坐标,可以通过以下步骤实现:
1. 图像预处理,首先,你需要对图像进行预处理,以便更好地
提取曲线。
可以使用图像增强、滤波等技术来减少噪声和增强曲线
的对比度。
2. 边缘检测,使用边缘检测算法(如Canny边缘检测)来检测
图像中的曲线边缘。
这将产生一幅二值图像,其中曲线的边缘将被
表示为白色像素,而背景将是黑色像素。
3. 轮廓提取,使用轮廓提取算法(如findContours函数)来
提取边缘图像中的曲线轮廓。
这将返回一组点的坐标,表示曲线的
轮廓。
4. 过滤曲线,根据需要,你可以对曲线进行过滤,以去除不需
要的轮廓。
例如,可以根据曲线的长度、面积或形状进行过滤。
5. 提取坐标,遍历每个轮廓,使用approxPolyDP函数将曲线
轮廓近似为更简单的形状(如直线或多边形)。
然后,可以使用
boundingRect函数获取每个近似形状的边界框,或者使用minEnclosingCircle函数获取每个近似形状的最小外接圆。
这些边界框或圆的中心点坐标即为曲线上的点坐标。
需要注意的是,以上步骤是一种常用的方法,可以根据具体情况进行调整和优化。
另外,OpenCV提供了丰富的函数和工具,可以帮助你更方便地实现曲线提取点坐标的任务。
边沿检测和轮廓提取方法和程序1 边沿检测我们给出一个模板和一幅图象。
不难发现原图中左边暗,右边亮,中间存在着一条明显的边界。
进行模板操作后的结果如下:。
可以看出,第3、4列比其他列的灰度值高很多,人眼观察时,就能发现一条很明显的亮边,其它区域都很暗,这样就起到了边沿检测的作用。
为什么会这样呢?仔细看看那个模板就明白了,它的意思是将右邻点的灰度值减左邻点的灰度值作为该点的灰度值。
在灰度相近的区域内,这么做的结果使得该点的灰度值接近于0;而在边界附近,灰度值有明显的跳变,这么做的结果使得该点的灰度值很大,这样就出现了上面的结果。
这种模板就是一种边沿检测器,它在数学上的涵义是一种基于梯度的滤波器,又称边沿算子,你没有必要知道梯度的确切涵义,只要有这个概念就可以了。
梯度是有方向的,和边沿的方向总是正交(垂直)的,例如,对于上面那幅图象的转置图象,边是水平方向的,我们可以用梯度是垂直方向的模板检测它的边沿。
例如,一个梯度为45度方向模板,可以检测出135度方向的边沿。
1.Sobel算子在边沿检测中,常用的一种模板是Sobel 算子。
Sobel 算子有两个,一个是检测水平边沿的;另一个是检测垂直平边沿的。
与和相比,Sobel算子对于象素的位置的影响做了加权,因此效果更好。
Sobel算子另一种形式是各向同性Sobel(Isotropic Sobel)算子,也有两个,一个是检测水平边沿的,另一个是检测垂直平边沿的。
各向同性Sobel 算子和普通Sobel算子相比,它的位置加权系数更为准确,在检测不同方向的边沿时梯度的幅度一致。
下面的几幅图中,图7.1为原图;图7.2为普通Sobel算子处理后的结果图;图7.3为各向同性Sobel算子处理后的结果图。
可以看出Sobel算子确实把图象中的边沿提取了出来。
图7.1 原图图7.2 普通Sobel算子处理后的结果图图7.3 各向同性Sobel算子处理后的结果图在程序中仍然要用到第3章介绍的通用3×3模板操作函数TemplateOperation,所做的操作只是增加几个常量标识及其对应的模板数组,这里就不再给出了。
2.高斯拉普拉斯算子由于噪声点(灰度与周围点相差很大的点)对边沿检测有一定的影响,所以效果更好的边沿检测器是高斯拉普拉斯(LOG)算子。
它把我们在第3章中介绍的高斯平滑滤波器和拉普拉斯锐化滤波器结合了起来,先平滑掉噪声,再进行边沿检测,所以效果会更好。
常用的LOG算子是5×5的模板,如下所示。
到中心点的距离与位置加权系数的关系用曲线表示为图7.4。
是不是很象一顶墨西哥草帽?所以,LOG又叫墨西哥草帽滤波器。
图7.4 LOG到中心点的距离与位置加权系数的关系曲线图7.5为图7.1用LOG滤波器处理后的结果。
图7.5 图7.1用LOG滤波器处理后的结果图LOG的算法和普通模板操作的算法没什么不同,只不过把3×3改成了5×5,这里就不再给出了。
读者可以参照第3章的源程序自己来完成。
7.2 Hough变换Hough变换用来在图象中查找直线。
它的原理很简单:假设有一条与原点距离为s,方向角为θ的一条直线,如图7.6所示。
图7.6 一条与原点距离为s,方向角为θ的一条直线直线上的每一点都满足方程(7.1)利用这个事实,我们可以找出某条直线来。
下面将给出一段程序,用来找出图象中最长的直线(见图7.7)。
找到直线的两个端点,在它们之间连一条红色的直线。
为了看清效果,将结果描成粗线,如图7.8所示。
图7.7 原图图7.8 Hough 变换的结果可以看出,找到的确实是最长的直线。
方法是,开一个二维数组做为计数器,第一维是角度,第二维是距离。
先计算可能出现的最大距离为,用来确定数组第二维的大小。
对于每一个黑色点,角度的变化范围从00到1780(为了减少存储空间和计算时间,角度每次增加20而不是10),按方程(7.1)求出对应的距离s 来,相应的数组元素[s][]加1。
同时开一个数组Line ,计算每条直线的上下两个端点。
所有的象素都算完后,找到数组元素中最大的,就是最长的那条直线。
直线的端点可以在Line 中找到。
要注意的是,我们处理的虽然是二值图,但实际上是256级灰度图,不过只用到了0和255两种颜色。
BOOL Hough(HWND hWnd) {//定义一个自己的直线结构 typedef struct{int topx; //最高点的x 坐标 int topy; //最高点的y 坐标 int botx; //最低点的x 坐标 int boty; //最低点的y 坐标 }MYLINE;DWORD OffBits,BufSize; LPBITMAPINFOHEADER lpImgData;LPSTR lpPtr;HDC hDc;LONG x,y;long i,maxd;int k;int Dist,Alpha;HGLOBAL hDistAlpha,hMyLine;Int *lpDistAlpha;MYLINE *lpMyLine,*TempLine,MaxdLine;static LOGPEN rlp={PS_SOLID,1,1,RGB(255,0,0)};HPEN rhp;//我们处理的实际上是256级灰度图,不过只用到了0和255两种颜色。
if( NumColors!=256){MessageBox(hWnd,"Must be a mono bitmap with grayscale palette!", "Error Message",MB_OK|MB_ICONEXCLAMATION);return FALSE;}//计算最大距离Dist=(int)(sqrt((double)bi.biWidth*bi.biWidth+(double)bi.biHeight*bi.biHeight)+0.5);Alpha=180 /2 ; //0 到to 178 度,步长为2度//为距离角度数组分配内存if((hDistAlpha=GlobalAlloc(GHND,(DWORD)Dist*Alpha*sizeof(int)))==NULL){MessageBox(hWnd,"Error alloc memory!","Error Message",MB_OK|MB_ICONEXCLAMATION);return FALSE;}//为记录直线端点的数组分配内存if((hMyLine=GlobalAlloc(GHND,(DWORD)Dist*Alpha*sizeof(MYLINE)))==NULL){GlobalFree(hDistAlpha);return FALSE;}OffBits=bf.bfOffBits-sizeof(BITMAPFILEHEADER);//BufSize为缓冲区大小BufSize=OffBits+bi.biHeight*LineBytes;lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData);lpDistAlpha=(int *)GlobalLock(hDistAlpha);lpMyLine=(MYLINE *)GlobalLock(hMyLine);for (i=0;i<(long)Dist*Alpha;i++){TempLine=(MYLINE*)(lpMyLine+i);(*TempLine).boty=32767; //初始化最低点的y坐标为一个很大的值}for (y=0;y<bi.biHeight;y++){//lpPtr指向位图数据lpPtr=(char *)lpImgData+(BufSize-LineBytes-y*LineBytes);for (x=0;x<bi.biWidth;x++)if(*(lpPtr++)==0) //是个黑点for (k=0;k<180;k+=2){//计算距离ii=(long)fabs((x*cos(k*PI/180.0)+y*sin(k*PI/180.0)));//相应的数组元素加1*(lpDistAlpha+i*Alpha+k/2)=*(lpDistAlpha+i*Alpha+k/2)+1;TempLine=(MYLINE*)(lpMyLine+i*Alpha+k/2);if(y> (*TempLine).topy){//记录该直线最高点的x,y坐标(*TempLine).topx=x;(*TempLine).topy=y;}if(y< (*TempLine).boty){//记录该直线最低点的x,y坐标(*TempLine).botx=x;(*TempLine).boty=y;}}}maxd=0;for (i=0;i<(long)Dist*Alpha;i++){TempLine=(MYLINE*)(lpMyLine+i);k=*(lpDistAlpha+i);if(k > maxd){//找到数组元素中最大的,及相应的直线端点maxd=k;MaxdLine.topx=(*TempLine).topx;MaxdLine.topy=(*TempLine).topy;MaxdLine.botx=(*TempLine).botx;MaxdLine.boty=(*TempLine).boty;}}hDc = GetDC(hWnd);rhp = CreatePenIndirect(&rlp);SelectObject(hDc,rhp);MoveToEx(hDc,MaxdLine.botx,MaxdLine.boty,NULL);//在两端点之间画一条红线用来标识LineTo(hDc,MaxdLine.topx,MaxdLine.topy);DeleteObject(rhp);ReleaseDC(hWnd,hDc);//释放内存及资源 GlobalUnlock(hImgData); GlobalUnlock(hDistAlpha); GlobalFree(hDistAlpha); GlobalUnlock(hMyLine); GlobalFree(hMyLine); return TRUE; }如果是给定的,用上述方法,我们可以找到该方向上最长的直线。
7.3 轮廓提取轮廓提取的实例如图7.9、图7.10所示。
图7.9原图图7.10 轮廓提取轮廓提取的算法非常简单,就是掏空内部点:如果原图中有一点为黑,且它的8个相邻点都是黑色时(此时该点是内部点),则将该点删除。