热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

图像处理(7):边缘检测

边缘检测是图形图像处理、计算机视觉和机器视觉中的一个基本工具,通常用于特征提取和特征检测,旨在检测一张数字图像中有明显变化的边缘或者不连续的区域

    边缘检测是图形图像处理、计算机视觉和机器视觉中的一个基本工具,通常用于特征提取和特征检测,旨在检测一张数字图像中有明显变化的边缘或者不连续的区域,在一维空间中,类似的操作被称作步长检测(step detection)。边缘是一幅图像中不同屈原之间的边界线,通常一个边缘图像是一个二值图像。边缘检测的目的是捕捉亮度急剧变化的区域,而这些区域通常是我们关注的。


一、常规边缘检测


    颜色边缘检测方法是使用边缘滤波器,这些滤波器通过寻找较亮和较暗的区域边界像素点的方式提取边缘,滤波器寻找图像中梯度变化明显的部分。这些梯度一般描述为边缘的振幅和方向。将边缘振幅高的所有像素选择出来,就完成了区域的边缘轮廓提取。

    Halcon提供了许多标准的边缘滤波器,如 Sobel、Roberts、Robinson和Frei滤波器。此外,还提供了非极大值抑制算子,用于进行提取边缘后的处理。


    1.1 常用算子

    1. Sobel算子

    Sobel算子结合了高斯平滑和微分求导。它是一阶导数的边缘检测算子,使用卷积核对图像中的每个像素点做卷积和运算,然后采用合适的阈值提取边缘。Soble算子有两个卷积核,分别对应x与y两个方向。其计算过程如下。


  • 分别在x和y两个方向求导。

  • 在图像的每一个像素点上,结合以上两个结果求出近似梯度。

    2. Laplace算子

    Laplace算子是一种二阶导数算子。在图像的边缘区域,像素值会发生比较大的变化,对这些像素求导会出现极值。在这些极值位置,其二阶导数为0,所以也可以用二阶导数来检测图像边缘。

    3.Canny算子

    Canny算子的基本思想是寻找梯度的局部最大值。首先使用高斯平滑滤波器卷积降噪,再用一对卷积阵列计算边缘梯度和方向,然后使用非极大值抑制移除非边缘线条,最后使用滞后阈值(高阈值和低阈值)检测并连接边缘。

 

    对比上述3种算子:


  1. Sobel算子在边缘检测的同时尽量减少了噪声的影响,比较容易实现。它对像素位置的影响进行了加权,因此效果比较好,是很常用的边缘检测方法。

  2. Laplace算子是一种各向同性算子,比较适用于只关心边缘的位置而不考虑其周围像素的灰度差值的情况。Laplace算子对孤立像素的响应要比对边缘或线的响应更强烈,因此只适用于无噪声图像。存在噪声的情况下,使用Laplace算子进行边缘检测之前需要先进行低通滤波处理。

  3. Canny算子是目前理论上相对最完善的一种边缘检测算法,但其也存在不足之处。为了得到较好的边缘检测结果,它通常需要使用较大的滤波尺度,这样容易丢失一些细节。

 


1.2边缘检测处理流程

    边缘检测的一般处理流程如下。

    (1)获取图像。

    (2)用ROI裁剪图像。

    (3)图像滤波。对输入图像使用边缘滤波器是采集后的一个关键步骤,为了获取图像的边缘部分,在读取了输入图像之后,可以使用边缘滤波器获取边缘的梯度和方向。对于像素级边缘,Halcon中提供了常用算子,如 sobel amp、sobel_dir、edges_image、derivate_gauss、edges_color等。

    (4)提取边缘。将符合条件的边缘提取出来,应用滤波器之后,可以使用阈值处理将图像中的高亮边缘提取出来。这里可以使用前文介绍的threshold算子,也可以使用 hysteresis_threshold算子减少非关键的边缘,将符合条件的边缘提取出来。还可以进一步对结果进行非极大值抑制,然后使用skelcton算子将边缘绘制出来。

    (5)边缘处理。根据检测的需要对提取出的边缘进行处理,有时得到的边缘可能会比较粗略,往往大于1个像素,需要进行一些细化;有时得到的边缘并不连续,因此还需要对边缘做一些处理,如生成轮廓、合并非连续的边缘、分离背景等。

    (6)显示结果。将结果绘制在窗口中,以表现直观的边缘提取效果。

 


    1.3 sobel_amp算子

    Halcon提供了大量的边缘滤波器,最常用的是Sobel滤波器。它是一种经典的边缘检测算子,速度和效率都非常令人满意。其在Halcon中对应的算子为sobel_amp算子和 sobel_dir算子,二者都是使用Sobel算子进行边缘检测。前者用于计算边缘的梯度,后者除了能表示梯度外,还能表示边缘的方向。

    下面是一个实例:

read_image(Image,'test1.bmp')
sobel_amp(Image,Amp,'sum_abs',3)
threshold(Amp,Edg,100,255)
skeleton (Edg, Skeleton)

    该例子使用sobel_amp算子对灰度图像进行了边缘检测,选择了sum_abs类型的滤波器,并将带有边缘梯度的图像Amp输出。通过threshold阈值处理去除一些非关键的轮廓点和线。使用skeleton提取区域的框架。

    sobel_amp算子是一种常用的边缘滤波器,该算子是一阶导数的边缘检测算子,使用一个卷积核对图像中的每个像素点做卷积运算,然后采用合适的阈值提取边缘。根据滤波器的不同,卷积核的运算方式也不同。该算子的原型如下:

sobel_amp(Image : EdgeAmplitude : FilterType, Size : )

    其各参数含义如下。


  • Image:为输入的图像,这里是单通道图像。

  • EdgeAmplitude:为输出参数,是带有边缘梯度的图像。

  • FilterType:为输入参数,表示卷积核或滤波器的类型。

  • Size:为输入参数,表示滤波器的尺寸。该参数值越大,得到的边缘线条会越粗,细节越少。这个值一般为单数,默认为3,也可以根据图像的检测需要选择合适的奇数。

    这里的FilterType是基于两种滤波器掩膜的,它决定了卷积的计算方式。假设两个卷积的滤波掩膜矩阵是A和B,矩阵如下:


1.4 edges_image算子

    它使用递归实现的滤波器(如Deriche、Lanser和Shen)检测边缘,也可以使用高斯导数滤波器检测边缘。此外,edges_image算子也提供了非极大值抑制和滞后阈值,使提取出的边缘更细化。edges image算子同样能返回精确的边缘梯度和方向,这一点比 Sobel滤波器要好一些,但是相应地所花的时间也长一些。对一些强调精度而不注重运算时间的场合,可以使用edges _image算子来提高检测效率。此外,也可以结合使用sobel_ fast滤波器,

以提高检测的速度。

    该算子的原型如下:

edges_image(Image : ImaAmp, ImaDir : Filter, Alpha, NMS, Low, High : )

其各参数含义如下。


  • Image:为输入的单通道图像。

  • ImaAmp:为输出的边缘梯度图像。

  • ImaDir:为输出的边缘方向图像。

  • Filter:为输入参数,表示选择的滤波算子。默认为canny,也可以选择derichel .derichel_int4、deriche2、deriche2_int4、lanser1、lanser2、mshen、shen、sobel_fast。

  • Alpha:为输入参数,表示平滑的程度。值越小,表示平滑的程度越大。默认是0,也可以取0.1到1.1之间的值。

  • NMS:表示非极大值抑制。默认为nms,表示使用非极大值抑制;也可以设为none,表示不使用非极大值抑制。使用非极大值抑制可以使模糊的边界变得清晰,因为这步操作只留下边缘上梯度强度最大的点。

  • Low和High:分别表示滞后阈值的低阈值和高阙值。边缘梯度比高阈值大的部分是可以被接受的;低于低阈值的部分将被排除;介于两者之间的,要看该像素是否与边缘点相连,相连的可以认为是边缘。

    下面是一个实例:


 

dev_close_window ()
read_image(Image,'C:/Users/Administrator/Desktop/test1.jpg')
rgb1_to_gray (Image, GrayImage)
gen_image_proto (Image, ImageCleared, 1)
dev_open_window (0, 0, 256, 256, 'black', WindowHandle1)
dev_open_window (0, 256, 256, 256, 'black', WindowHandle2)
dev_open_window (256, 0, 256, 256, 'black', WindowHandle3)
dev_open_window (256, 256, 256, 256, 'black', WindowHandle4)
edges_image (GrayImage, ImaAmpGray, ImaDirGray, 'canny', 1, 'none', -1, -1)
edges_image (GrayImage, ImaAmpGrayNMS, ImaDirGrayHyst, 'canny', 1, 'nms',20, 40)
*对非极大值抑制后的边缘梯度图像进行了阈值处理
threshold (ImaAmpGrayNMS, RegionGray, 1, 255)
*提取边缘轮廓
skeleton (RegionGray, EdgesGray)
*用于结果显示和对比
dev_set_window (WindowHandle1)
dev_display (Image)
dev_set_window (WindowHandle2)
dev_display (ImageCleared)
dev_display (ImaAmpGray)
dev_set_window (WindowHandle3)
dev_display (ImageCleared)
dev_display (ImaAmpGrayNMS)
dev_set_window (WindowHandle4)
dev_display (ImageCleared)
dev_display (EdgesGray)

    这里使用了3种边缘提取方法进行对比。右上图使用canny滤波器提取的,没有使用非极大值抑制的边缘梯度图像。左下图为使用canny滤波器提取的,使用了非极大值抑制的边缘梯度图像。右下图在左下图的基础上加入了灰度阈值处理,并描绘出了经阈值处理的框架图像。

    非极大值抑制(Non-MaximumSuppression,NMS)。经非极大值抑制后,边缘仅剩下梯度最大的像素,所以经阈值处理提取出的像素就是图像的边缘。而如果使用未经非极大值抑制的图像,可能阈值处理会提取过多的像素,无法理想地表现出边缘信息。

    与edges_image算子类似的还有edges_color算子,该算子可以用干提取彩色图像的边缘,其原型如下:

edges_color(Image : ImaAmp, ImaDir : Filter, Alpha, NMS, Low, High : )

1.5其他滤波器

    除了前面介绍的两个算子外,还可以使用其他方法提取图像边缘。

    1. derivate_gauss算子

    derivate_gauss算子不仅可以提取图像边缘,还有以下功能。


  • 平滑图像。

  • 边缘检测,提取图像的边缘。

  • 角点检测,检测图像上的角点。

derivate_gauss(Image : DerivGauss : Sigma, Component : )

其各参数的含义如下。


  • Image:为输入的灰度图像。

  • DerivGauss:为输出的滤波后的图像。参数3 :Sigma为输入的高斯导数的 sigma值。

  • Component:为输入的要计算的导数或者特征。这里有以下几种类型可以选择。


  1. none:仅对图像进行平滑处理。

  2. x:沿着x轴方向求导。

  3. y:沿着y轴方向求导。

  4. gradient :求梯度的绝对值。

  5. gradient_dir:求梯度的方向。

  6. xx:沿着x轴方向二阶求导。

  7. yy:沿着y轴方向二阶求导。

  8. laplace:使用Laplace算子求导。

 

    2.laplace算子

    使用laplace算子对图像进行二次求导,会在边缘产生零点,因此该算子常常与zero_crossing算子配合使用。求出这些零点,也就得到了图像的边缘。同时,由于 laplace算子对孤立像素的响应要比对边缘或线的响应更强烈,因此在检测之前应先进行去噪处理。

    该算子的原型如下:

laplace(Image : ImageLaplace : ResultType, MaskSize, FilterMask : )

其各参数含义如下。


  • Image:为输入的多通道图像。

  • ImagcLaplace:为输出的 laplacc图像。

  • ResultType:为输入的图像的类型。

  • MaskSize:为输入的滤波器的核的尺寸。

  • FilterMask:为输入参数,表示laplace算子使用的滤波核或掩膜的类型。

    以下是一个实例:

read_image(Image,'C:/Users/Administrator/Desktop/test1.jpg')
rgb1_to_gray (Image, GrayImage)
laplace (GrayImage, ImageLaplace, 'signed', 11, 'n_8_isotropic')
zero_crossing (ImageLaplace, RegionCrossing)

    laplace滤波图像然后给zero_crossing算子进行过零点检测,通过检测图像的二阶导数的零交点,可以得到边缘的位置。检测出来的就是二阶导数为0的点,即边缘的点。

    3. laplace_of _gauss算子

    由于图像中一般会存在噪声,而laplace算子对噪声比较敏感,因此需要配合使用图像的平滑操作。高斯–拉普拉斯算法将高斯的低通滤波器和 laplace算子进行了结合,简化成单一的 laplace_of_gauss算子,只需要填入简单的参数,就能得到比较理想的结果。该算子的原型如下:

laplace_of_gauss(Image : ImageLaplace : Sigma : )

其各参数的含义如下。


  • Image:为输入的图像,可以是多通道的。

  • ImageLaplace:为输出的经过高斯–拉普拉斯滤波后的图像。

  • Sigma:为高斯平滑参数。这个值越大,平滑力度越大,图像越模糊。

    以下是一个实例:

    laplace_of _gauss算子进行边缘的滤波计算,并使用zero_crossing算子进行二阶导数的过零点检测,检测得到的二阶导数为0的点,就是边缘的点。


二、亚像素级边缘检测


    亚像素(Sub-Pixel),一般描述图像的最基本的单位是像素,相机的分辨率也是以像素数量来计算的,像素越高,分辨率越大,图像越清晰。点与点之间的最小距离就是一个像素的宽度,但实际工程中可能会需要比一个像素宽度更小的精度,因此就有了亚像素级精度的概念,用于提高分辨率。Halcon中用XLD (eXtended Line Descriptions)表示亚像素的轮廓和多边形。

    在检测过程中,受光照、噪声等因素的影响,有些边缘可能是断裂的,所以需要先进行轮廓合并。Halcon同样提供了许多高效的算子,可以一步完成边缘提取、轮廓合并以及XLD轮廓输出。因此,只需要调用一次算子就可以完成诸多工作,省去了很多计算环节,非常易于使用。除此之外,算子的准确率和稳定性也非常理想。


    2.1 edges_sub_pix算子

    最常用的提取亚像素轮廓的算子是edges_sub_pix算子,该算子同样提供了大量的提取方法,只需要在Filter参数中设置方法的名字,就可以完成边缘的提取。该算子的输入是灰度图像,输出是XLD轮廓,其原型如下:

edges_sub_pix(Image : Edges : Filter, Alpha, Low, High : )

其各参数含义如下。


  • Image:为输入的单通道图像。

  • Edges:为输出的XLD轮廓。

  • Filter:为输入参数,与edges_image算子中的Filter参数类似,表示选择的滤波算子。默认的是canny,可选的有canny、deriche1、derichel_int4、deriche2、deriche2_int4、lanserl、lanser2.mshen、shen、sobel_fast,还有一些以“_junctions”结尾的滤波器,适用于一些非连接的边缘。最常见的滤波器有canny和 lanser2。使用lanser2滤波器的一个优点是,它是一个递归的实现,当加大平滑的力度时,计算时间却不会因此增加。如果图像质量比较好,噪声也比较小,但对速度有要求,可以选择sobel_fast算子,因为它速度比较快,但缺点是对噪声敏感。

  • Alpha:为输入参数,表示平滑的程度。其值越小,表示平滑的程度越大。默认是0可以取0.1到1.1之间的值。

  • Low和 High:分别表示滞后阈值的低阈值和高阈值。低阈值越低,图像的细节会越丰富。高阈值用于将边缘与背景区分开来,高于高阈值的像素可以确定是边缘,这些边缘是强过缘,但往往是不连续的,因此需要用一些弱边缘进行补充。低于低阈值的像素可以被认为一定不是边缘。高于低阈值又低于高阈值的部分像素是弱边缘,需要进行判断。如果该像素的相邻像素是达缘,则该像素被认为是边缘,否则就不是。

    以下是一个实例:

read_image(Image,'C:/Users/Administrator/Desktop/test1.jpg')
rgb1_to_gray (Image, GrayImage)
*进行亚像素边缘提取。分别使用了不同的滞后阈值以便进行对比
edges_sub_pix (GrayImage, Edges1, 'lanser2', 0.5, 5, 50)
edges_sub_pix (GrayImage, Edges2, 'lanser2', 0.5, 25, 50)
edges_sub_pix (GrayImage, Edges3, 'lanser2', 0.5, 5, 25)

    2.2 edges_color_sub_pix算子

    如要要提取彩色多通道图像的亚像素边缘,可以使用edges_color_sub_pix算子。该算子与edges_sub_pix算子的参数十分相似,但又有所区别。首先从名称上看,edges_color_sub_pix算子多了一个color,表示它接受彩色多通道图像的输入,它使用Canny等滤波器提取亚像素精度的彩色边缘。另一个区别是,滤波器可选的类型不同。edges_color_sub_pix算子支持Deriche、Shen.Canny 3个大类的滤波器和一个sobel_fast滤波器,而edges_sub pix算子支持的滤波器类型更丰富一些。

    但也有许多地方是相似的,如 edges_color_sub_pix算子也包括一些以“_junctions”结尾的滤波器,这些特殊的滤波器更适用于一些断开的边缘,同时也使用了滞后阈值对滤波器提取出的边缘进行判断。

    以下是一个实例:

read_image(Image,'C:/Users/Administrator/Desktop/test1.jpg')
*使用canny算子进行亚像素边缘提取
edges_color_sub_pix (Image, Edges1, 'canny', 0.5, 5, 50)
*使用canny算子进行亚像素边缘提取
edges_color_sub_pix (Image, Edges2, 'sobel_fast', 0.5, 40, 70)

2.3 lines_gauss 算子

    该算子也可以用于提取边缘线段,它的鲁棒性非常好,提取出的线段类型是亚像素精度的XLD轮廓。其原型如下:

lines_gauss(Image : Lines : Sigma, Low, High, LightDark, ExtractWidth, LineModel, CompleteJunctions : )

其各参数含义如下。


  • Image:为输入的单通道图像。

  • Lines:为输出的一组亚像素精度的XLD轮廓线条。

  • Sigma:为输入的高斯平滑的值。较大的平滑值会使图像平滑的力度更大,但过度平滑也可能导致提取的线条位置有偏差。默认为1.5。在需要提取线条宽度时,Sigma的值应根据要提取的线条宽度进行调节,最小值应不小于wl/3(w为线条宽度,即线条直径的一半)。例如,对于宽度为4的线条,Sigma值应不小于2.3。

  • Low和High:为输入参数,分别表示滞后阈值的低阈值和高阈值。高阈值越低,边缘线条的细节会越丰富。其原理在10.2.1小节edges sub pix算子的参数介绍中有详细介绍。但这里值得一提的是,如果Sigma选得比较大,阈值就应选择较低的高阈值和较高的低阈值。因为选择的Sigma越大,二阶导数就越小。低阙值和高阈值也可以根据要提取的线的相应灰度对比度和Sigma参数值进行计算。

  • LightDark:为输入参数,表示提取较亮的线条还是较暗的线条。默认为light,即提取较亮线条。

  • ExtractWidth:为输入参数,表示是否需要提取线条的宽度。默认为true,即提取每条线段的宽度值。

  • LineModel:为输入参数,表示调整线条位置和宽度的线段模型。可选的有 bar-shaped(条型).gaussian(高斯型)、 parabolic(抛物线型)。默认为条型,大多数应用场景都可以选择该选项。如果是背光比较强的情况,可以考虑另外两种模型。其中,当图像中的线条比较清晰明锐时,可以选择抛物线型:如果不是特别清晰,可以选择高斯型。

  • CompleteJunctions:为输入参数,表示是否添加连接,用于边缘线段不连续的情况,默认为true。因为某些非连通线段无法通过边缘提取器进行提取,所以这里设为true,即可使用其他方式尝试对非连续部分进行连接。

    以下是一个实例:

read_image(Image,'C:/Users/Administrator/Desktop/test1.jpg')
rgb1_to_gray (Image, GrayImage)
dev_open_window (0, 512, 512, 512, 'black', WindowHandle1)
*进行边缘检测
lines_gauss(GrayImage,Lines,1.5,1,8,'light','true','bar-shaped','true')

三、轮廓处理


    对于检测任务来说,提取出边缘或者线条,获取了线条的属性,工作还远未结束。由于这些边缘或者线条并不能表示轮廓,轮廓必须是闭合的,而且有些高精度测量对轮廓的精度要求非常高,因此还需要对轮廓做一些处理。

    在Halcon中,轮廓的数据结构为XLD。对于亚像素级的轮廓处理,Halcon中有许多强大的工具,下面将针对不同的应用情况进行介绍。


3.1轮廓的生成

    轮廓的生成最常用的edges_sub_pix算子,在该算子中可以选择不同的滤波器类型,最常见的滤波器有canny 和 lanser2。

    如果输入图像是多通道的彩色图像,可以选择edges color_sub_pix算子,其与edges_sub_pix算子类似、也推荐选择sobel fast滤波器,用于快速地提取边缘。

    最常用的线条提取方法是lines_gauss,它具有很强的鲁棒性。也可以通过指定ExtractWidth参数提取出线条的宽度等多种特征。线条的宽度越宽,其 Sigma参数的取值也应当越大。

    与提取边缘类似,提取线条也有一个对应于彩色图像的算子,即 lines_color算子,用于处理输入图像为多通道图像的线条提取。

    这些边缘或者线条提取算子输出的除了XLD轮廓之外,还会返回一些表示属性的特征值。这些属性特征与轮廓的整体或者其控制节点密切相关。可以使用gen contour attrib xld算子或者gen_contour_global_attrib_xld算子通过属性名称访问轮廓的某个属性,这些属性一般是以Tuple数组形式存放的。典型的属性有关于边缘的属性,如梯度和方向:关于线条的属性,如线宽等。还可以使用query_contour_attrib_xld算子或者query contour global attrib xld算子对给定的轮廓进行属性查询。

 


3.2轮廓的处理

    输出了目标的轮廓后,接下来还需要对轮廓进行处理,这主要基于以下3个原因。


  1. 对于某些测量任务而言,并不需要分析目标的整个轮廓,可能只需要局部的一段轮廓就够了。而有时由于ROI(感兴趣区域)选择得过大,因此需要对提取的轮廓进行分割,以得到所需的部分。

  2. 在提取轮廓或线条的过程中,可能会有一些杂点或背景区域被误认为是轮廓也被提取了出来,所以需要做一些剔除,以得到完全需要的区域。

  3. 提取出的轮廓线条可能会有一些不连续,而某些检测中需要轮廓是闭合的,因此需要做一些连接或者填补。

   1.轮廓分割

    首先要介绍的是轮廓分割,可以使用segment_contours_xld算子将轮廓分割成线段、圆弧或者椭圆等预定义的形状,分割出的各个线段可以使用select_obj算子单独进行选择。

    如果只需要分割成线段,则可以使用gen_polygons_xld算子和 split_contours_xld算子的组合,这两步操作的结果类似于segment_contours_xld算子的功能。两种方式的区别主要在于对轮廓进行分割后的处理,使用两步组合法,将生成XLD多边形类型的轮廓。

 

    2.轮廓的筛选

    对于轮廓处理来说,很重要的一步是抑制不相关的轮廓,可以使用select_shape_xld算子实现这一功能。该算子的功能非常强大,与第9章介绍过的select_shape算子类似,它使用一步操作就能提取输入区域的多种特征并进行筛选。该算子提供了30多种不同的形状特征,通过指定不同特征的阈值并结合多种特征进行评估,能非常灵活地提取出理想的轮廓部分。也可以选择select_contours_xld算子,它包含了更多线性结构的典型特征。如果需要用鼠标进行交互操作,如实时选择一些轮廓,可以使用sclect_xld _point算子,通过单击鼠标来选取轮廓。

 

    3.轮廊的连接

    如果轮廓的线条是不连续的,那么断开的部分会被当成独立的部分,后续的处理过程会更加棘手。这时可以试着将断开的部分连接起来,使用union _collinear_contours_xld算子或者union_straight_contours_xld算子,就可以实现这一功能。前者适用于共线的连接,后者适用于同方向的邻近轮廓。还可以选择union_adjacent_contours_xld算子,它适用于端点邻近的情况。

    Halcon也提供了一个 shape_trans_xld 算子用于修改形状,把轮廓转换成包围的圆或者矩形等。还可以使用union2_closed _contours_ xld等算子合并闭合轮廓。

 

    4.轮廓的拟合

前面得到的轮廓有可能是不规则的,实际检测中可能需要将其进行拟合,以得到规则的轮廓,便于后续处理。Halcon 提供了几种不同形状的拟合算子,简要介绍如下。


  1. 拟合直线使用fit_line_contour_xld算子,该算子提供了多种拟合的方法,大部分都是用于抑制非相关轮廓线的。该算子会返回线段和线段两端的坐标。其配合gen contour polygon xld算子可以查看直线的显示结果。

  2. 拟合圆形使用fit_circle_contour_ xld算子,其也有许多拟合方法可选,将返回圆的中心坐标和半径。可以使用gen_circle_contour_xld 算子查看拟和结果。

  3. 拟合矩形选择fit_rectangle2_contour xld算子,该算子返回的主要是矩形的中心坐标和边长,以及矩形的旋转角度。其配合gen_rectangle2 contour_xld算子可以显示拟合结果。

  4. 拟合椭圆形可以用fit_ellinse_contour_xld算子,返回椭圆的中心坐标。长轴和短轴的半径,以及椭圆的角度和方向特征。其搭配使用geo_ellipse cntour_xld算子,可以轮廓曲线。

 


推荐阅读
  • 本题探讨如何通过最大流算法解决农场排水系统的设计问题。题目要求计算从水源点到汇合点的最大水流速率,使用经典的EK(Edmonds-Karp)和Dinic算法进行求解。 ... [详细]
  • 机器学习中的相似度度量与模型优化
    本文探讨了机器学习中常见的相似度度量方法,包括余弦相似度、欧氏距离和马氏距离,并详细介绍了如何通过选择合适的模型复杂度和正则化来提高模型的泛化能力。此外,文章还涵盖了模型评估的各种方法和指标,以及不同分类器的工作原理和应用场景。 ... [详细]
  • 毕业设计:基于机器学习与深度学习的垃圾邮件(短信)分类算法实现
    本文详细介绍了如何使用机器学习和深度学习技术对垃圾邮件和短信进行分类。内容涵盖从数据集介绍、预处理、特征提取到模型训练与评估的完整流程,并提供了具体的代码示例和实验结果。 ... [详细]
  • 题目Link题目学习link1题目学习link2题目学习link3%%%受益匪浅!-----&# ... [详细]
  • 本文探讨了 C++ 中普通数组和标准库类型 vector 的初始化方法。普通数组具有固定长度,而 vector 是一种可扩展的容器,允许动态调整大小。文章详细介绍了不同初始化方式及其应用场景,并提供了代码示例以加深理解。 ... [详细]
  • MATLAB中的类别数组:存储和操作有限类别的数据
    类别数组(categorical array)是MATLAB中用于存储有限类别数据的一种特殊数组类型。它不仅提供对非数值数据的高效存储和操作,还保留了原有类别的名称,使数据处理更加直观便捷。此外,类别数组可以与表格(table)数据类型结合使用,以实现更复杂的数据分析。 ... [详细]
  • 最近团队在部署DLP,作为一个技术人员对于黑盒看不到的地方还是充满了好奇心。多次咨询乙方人员DLP的算法原理是什么,他们都以商业秘密为由避而不谈,不得已只能自己查资料学习,于是有了下面的浅见。身为甲方,虽然不需要开发DLP产品,但是也有必要弄明白DLP基本的原理。俗话说工欲善其事必先利其器,只有在懂这个工具的原理之后才能更加灵活地使用这个工具,即使出现意外情况也能快速排错,越接近底层,越接近真相。根据DLP的实际用途,本文将DLP检测分为2部分,泄露关键字检测和近似重复文档检测。 ... [详细]
  • 深入解析 Apache Shiro 安全框架架构
    本文详细介绍了 Apache Shiro,一个强大且灵活的开源安全框架。Shiro 专注于简化身份验证、授权、会话管理和加密等复杂的安全操作,使开发者能够更轻松地保护应用程序。其核心目标是提供易于使用和理解的API,同时确保高度的安全性和灵活性。 ... [详细]
  • 作为一名专业的Web前端工程师,掌握HTML和CSS的命名规范是至关重要的。良好的命名习惯不仅有助于提高代码的可读性和维护性,还能促进团队协作。本文将详细介绍Web前端开发中常用的HTML和CSS命名规范,并提供实用的建议。 ... [详细]
  • 本文介绍了一种解决二元可满足性(2-SAT)问题的方法。通过具体实例,详细解释了如何构建模型、应用算法,并提供了编程实现的细节和优化建议。 ... [详细]
  • 给定一个整数数组arr,找到min(b)的总和,其中b的范围为arr的每个(连续)子数组。由于答案可能很大,因此返回答案模10^9+7。classSolution{publicin ... [详细]
  • 本文汇总了在正式宴会上常用的寒暄语句,包括欢迎词、感谢词及日常问候,适用于各种正式场合。这些语句不仅有助于提升交际礼仪,还能增进彼此之间的友好关系。 ... [详细]
  • 深入解析 Spring Security 用户认证机制
    本文将详细介绍 Spring Security 中用户登录认证的核心流程,重点分析 AbstractAuthenticationProcessingFilter 和 AuthenticationManager 的工作原理。通过理解这些组件的实现,读者可以更好地掌握 Spring Security 的认证机制。 ... [详细]
  • 本文深入探讨了 Python 中的循环结构(包括 for 循环和 while 循环)、函数定义与调用,以及面向对象编程的基础概念。通过详细解释和代码示例,帮助读者更好地理解和应用这些核心编程元素。 ... [详细]
  • 本文介绍如何使用布局文件在Android应用中排列多行TextView和Button,使其占据屏幕的特定比例,并提供示例代码以帮助理解和实现。 ... [详细]
author-avatar
杨俊其632
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有