精华内容
下载资源
问答
  • 边缘检测算法

    2018-05-31 13:33:11
    边缘检测算法的matlab实现,内含各种实现方式,应该还比较可靠
  • 图像边缘检测算法

    2020-11-08 14:30:40
    C语言实现灰度图像的集中常用边缘检测算法,包括:梯度算子,roberts边缘检测算法,Sobel边缘检测算法,Laplace边缘检测算法和Canny边缘检测算法
  • Sobel边缘检测算法

    2020-08-01 23:05:59
    本文介绍的是常用图像边缘检测算法 ——Sobel边缘检测算法
  • 本文主要介绍几种常见的边缘检测算法:canny边缘检测、Sobel边缘检测、Laplacian边缘检测和Scharr边缘检测。1. 主要介绍基于canny算子的边缘检测:Canny边缘检测基本原理(1)图象边缘检测必须满足两个条件:一能有效...

    本文主要介绍几种常见的边缘检测算法:canny边缘检测、Sobel边缘检测、Laplacian边缘检测和Scharr边缘检测。

    1. 主要介绍基于canny算子的边缘检测:Canny边缘检测基本原理

    (1)图象边缘检测必须满足两个条件:一能有效地抑制噪声;二必须尽量精确确定边缘的位置。

    (2)根据对信噪比与定位乘积进行测度,得到最优化逼近算子。这就是Canny边缘检测算子。

    (3)类似与Marr(LoG)边缘检测方法,也属于先平滑后求导数的方法。

    基于opencv库函数为:

    Canny边缘检测函数

    Canny (InputArray  image, OutputArray edges, double threshold, 

                double threshold2,int  apertureSize = 3, 

                bool L2gradient = false)

    参数功能:

    • image输入图像

    • edges:输出图像

    • threshold:第一个滞后性阈值

    • threshold2:第二个滞后性阈值

    • apertureSize:表示应用Sobel算子的孔径大小,默认值为3

    • L2gradient:一个计算图像梯度幅值的标识,默认值false

    实现代码:

    #include

    #include

    using namespace cv;

    using namespace std;

    int main()

    {

           Mat src =  imread("lena.jpg");

           imshow("原图",  src);

           Mat dst, edge,  gray;

           //将原图像转换为灰度图像

           cvtColor(src,  gray, COLOR_BGR2GRAY);

           //使用canny算子

           Canny(gray, edge,  3, 9, 3);

           imshow("canny边缘检测结果",  edge);

           waitKey();

           return 0;

    }

    结果

    3fddd99829ea9dd6fa8bcb81629ad1d8.png

    原图

    c85336cd8bff046d6631b4dbe8d023ac.png

    结果

    2. Sobel 算子是一个离散微分算子。它结合了高斯平滑和微分求导,用来计算图像灰度函数的近似梯度。基于opencv库的实现函数为:

    Soble边缘检测函数:

    Sobel(InputArray src,OutputArray dst, int ddepth, int dx,int  dy,

               int ksize= 3,double  scale = 1,double delta = 0, 

               int borderType = BORDER_DEFAULT)

    • src输入图像

    • dst:输出图像

    • ddepth:输出图像的深度,取值规则如下:

    若src.depth()=CV_8U,取ddepth=-1/CV_16S/CV_32F/CV_64F

    若src.depth()=CV_16U/CV_16S,取ddepth=-1/ CV_32F/CV_64F

    若src.depth()=CV_32F,取ddepth=-1/ CV_32F/CV_64F

    若src.depth()=CV_64F,取ddepth=-1/ CV_64F

    • dxx方向上的差分阶数

    • dyy方向上的差分阶数

    • ksize:表示soble核的大小,必须取1357,默认值是3.

    • scale:计算导数值时可选的缩放因子,默认值是1,表示默认情况下是应用缩放的。

    • delta:表示在结果存入目标图之前可选的delta值,默认值为0

    • borderType:边界模式,默认值为BORDER_DEFAULT.

    实现代码:

    #include

    #include

    using namespace cv;

    using namespace std;

    int main()

    {

               Mat grad_x,  grad_y,gray;

               Mat  abs_grad_x, abs_grad_y, dst;

               Mat src =  imread("lena.jpg");

               imshow("原图",  src);

               //将原图像转换为灰度图像

               cvtColor(src,  gray, COLOR_BGR2GRAY);

               //使用Sobel算子,x方向上边缘检测

               Sobel(gray,  grad_x, CV_16S, 1, 0, 3, 1, 1, BORDER_DEFAULT);

               convertScaleAbs(grad_x,  abs_grad_x);

               imshow("x方向边缘检测结果",  abs_grad_x);

               //使用Sobel算子,y方向上边缘检测

               Sobel(gray,  grad_y, CV_16S, 0, 1, 3, 1, 1, BORDER_DEFAULT);

               convertScaleAbs(grad_y,  abs_grad_y);

               imshow("y方向边缘检测结果",  abs_grad_y);

               addWeighted(abs_grad_x,  0.5, abs_grad_y, 0.5, 0, dst);

               imshow("完整边缘检测结果",  dst);

               waitKey();

               return 0;

    }

    结果:

    3fddd99829ea9dd6fa8bcb81629ad1d8.png

    原图

    86ce134382e5058b434b235daf8f3d36.png

    x方向边缘检测结果

    da808094c39aed265b41e0eb371b5c94.png

    y方向边缘检测结果

    7c2c71931ad8da906fb9804be3515ab6.png

    完整边缘检测结果

    3. 拉普拉斯是一种各向同性二阶微分算子。Laplace算子对孤立象素的响应要比对边缘或线的响应要更强烈,因此只适用于无噪声图象。基于opencv的库函数为:

    Laplacian边缘检测函数

    Laplacian (InputArray src, OutputArray dst,int ddepth ,int  ksize = 1,

                      double scale = 1,double delta = 0,

                      intborderType = BORDER_DEFAULT)

    • src输入图像

    • dst:输出图像

    • ddepth:输出图像的深度,取值规则如下:

    若src.depth()=CV_8U,取ddepth=-1/CV_16S/CV_32F/CV_64F

    若src.depth()=CV_16U/CV_16S,取ddepth=-1/ CV_32F/CV_64F

    若src.depth()=CV_32F,取ddepth=-1/ CV_32F/CV_64F

    若src.depth()=CV_64F,取ddepth=-1/ CV_64F

    • dxx方向上的差分阶数

    • dyy方向上的差分阶数

    • ksize:表示soble核的大小,必须取1357,默认值是3.

    • scale:计算拉普拉斯值的时候可选的比例因子,默认值为1

    • delta:表示在结果存入目标图之前可选的delta值,默认值为0

    • borderType:边界模式,默认值为BORDER_DEFAULT.

    实现代码:

    #include

    #include

    using namespace cv;

    using namespace std;

    int main()

    {

               Mat abs_dst,  dst,gray;

               Mat src =  imread("lena.jpg");

               imshow("原图",  src);

               //将原图像转换为灰度图像

               cvtColor(src,  gray, COLOR_BGR2GRAY);

               //使用Sobel算子,x方向上边缘检测

               Laplacian(gray,  dst, CV_16S, 3, 1, 0, BORDER_DEFAULT);

               convertScaleAbs(dst,  abs_dst);

               imshow("Laplacian边缘检测结果",  abs_dst);

               waitKey();

               return 0;

    }

    结果:

    3fddd99829ea9dd6fa8bcb81629ad1d8.png

    原图

    6c69e5cb55e3f7801c34b9ce6bdf59f5.png

    laplacian边缘检测结果

    4. Scharr边缘检测函数

    Scharr (InputArray src, OutputArray dst,int ddepth ,int ksize  = 1,

                  double scale = 1,double delta = 0,

                   int borderType = BORDER_DEFAULT)

    • src输入图像

    • dst:输出图像

    • ddepth:输出图像的深度,取值规则如下:

           若src.depth()=CV_8U,取ddepth=-1/CV_16S/CV_32F/CV_64F

           若src.depth()=CV_16U/CV_16S,取ddepth=-1/ CV_32F/CV_64F

           若src.depth()=CV_32F,取ddepth=-1/ CV_32F/CV_64F

           若src.depth()=CV_64F,取ddepth=-1/ CV_64F

    • dxx方向上的差分阶数

    • dyy方向上的差分阶数

    • ksize:表示soble核的大小,必须取1357,默认值是3.

    • scale:计算拉普拉斯值的时候可选的比例因子,默认值为1

    • delta:表示在结果存入目标图之前可选的delta值,默认值为0

    • borderType:边界模式,默认值为BORDER_DEFAULT.

    实现代码:

    #include

    #include

    using namespace cv;

    using namespace std;

    int main()

    {

               Mat grad_x,  grad_y,gray;

               Mat  abs_grad_x, abs_grad_y, dst;

               Mat src =  imread("

    lena.jpg");

               imshow("原图",  src);

               //将原图像转换为灰度图像

               cvtColor(src,  gray, COLOR_BGR2GRAY);

               //使用Sobel算子,x方向上边缘检测

               Scharr(gray,  grad_x, CV_16S, 1, 0, 1, 0, BORDER_DEFAULT);

               convertScaleAbs(grad_x,  abs_grad_x);

               imshow("x方向边缘检测结果",  abs_grad_x);

               //使用Sobel算子,y方向上边缘检测

              Scharr(gray,  grad_y, CV_16S, 0, 1, 1, 0, BORDER_DEFAULT);

               convertScaleAbs(grad_y,  abs_grad_y);

               imshow("y方向边缘检测结果",  abs_grad_y);

               addWeighted(abs_grad_x,  0.5, abs_grad_y, 0.5, 0, dst);

               imshow("完整边缘检测结果",  dst);

               waitKey();

               return 0;

    }

    结果:

    3fddd99829ea9dd6fa8bcb81629ad1d8.png

    原图

    850666023fd6660334af3e2ce588c98d.png

    x方向边缘检测结果

    6b047d64efd1821aa592220b93c8533d.png

    y方向边缘检测结果

    eb9612cb4238b73b29594549ad71ab9b.png

    完整边缘检测结果

    到此图像边缘检测常见的四种方法介绍完毕,欢迎留言指正,如有对图像处理、计算机视觉感兴趣的小伙伴关注公众号,一起学习进步330f6154dc38b7caed2b4df496839635.png330f6154dc38b7caed2b4df496839635.png330f6154dc38b7caed2b4df496839635.png330f6154dc38b7caed2b4df496839635.png330f6154dc38b7caed2b4df496839635.png330f6154dc38b7caed2b4df496839635.png330f6154dc38b7caed2b4df496839635.png。本文为电脑编辑,手机查看可能会出现文字不整齐,敬请谅解!!!

    展开全文
  • canny边缘检测算法Canny edge detector is a multi-step algorithm to detect the edges for any input image. It involves below mentioned steps to be followed while detecting edges of an image. Canny边缘...

    canny边缘检测算法

    Canny edge detector is a multi-step algorithm to detect the edges for any input image. It involves below mentioned steps to be followed while detecting edges of an image.

    Canny边缘检测器是一种多步算法,可检测任何输入图像的边缘。 它涉及检测图像边缘时要遵循的下述步骤。

    1. Removal of noise in input image using Gausian filter.

    1.使用高斯滤波器消除输入图像中的噪声。

    2. Computing the derivative of Gausian filter in order to calculate the gradient of image pixels to obtain magnitude along x and y dimension.

    2.计算高斯滤波器的导数,以便计算图像像素的梯度以获得沿x和y维度的幅度。

    3. Considering a group of neighbours for any curve in direction perpendicular to given edge supress the non-max edge contributor pixel points.

    3.考虑在垂直于给定边缘的方向上的任何曲线的一组邻居抑制非最大边缘贡献者像素点。

    4. Lastly use the Hysteresis Thresholding method to preserve the pixels higher than gradient magnitude and neglect the ones lower than the low threshold value.

    4.最后,使用滞后阈值方法来保留高于梯度幅度的像素,而忽略低于低阈值的像素。

    Before deep diving into the steps below are the three conclusions that J.K Canny who derived the algorithm :

    在深入研究以下步骤之前,请先得出算法的JK Canny的三个结论:

    - Good Detection : The optimal detector must eliminate the possibility of getting false positives and false negatives.

    - 良好的检测:最佳检测器必须消除出现假阳性和假阴性的可能性。

    - Good Localisation : The detected edges must be as close to true edges.

    - 良好的本地化:检测到的边缘必须尽可能接近真实边缘。

    - Single Response Constraint : The detector must return one point only for each edge point.

    - 单一响应约束:检测器必须仅对每个边缘点返回一个点。

    Steps to followed during Canny Algorithm:

    Canny算法期间要遵循的步骤:

    Noise Removal or Image Smoothing:

    去噪或图像平滑:

    During the noise presence the pixel may not be close to being similar to its neigbouring pixels. This might result in obtaining improper or inappropriate detection of edges . In order to avoid the same we use the Gausian filter which is convolved with the image and removes the noise which prevents from getting the desired edges in output images.

    在噪声存在期间,像素可能与其附近像素不太接近。 这可能导致获得不正确或不合适的边缘检测。 为了避免同样的情况,我们使用了高斯滤波器,该滤波器与图像进行卷积,并去除了噪声,从而阻止了在输出图像中获得所需的边缘。

    In the below example we are convolving gausian filter or kernel g(x,y) with image I. Here we wish to make sure that any given pixel must be alike its neighbouring pixels in output and so we use the matrix [1 1 1] in order to maintain the similarity between pixels and remove the noise.

    在下面的示例中,我们将高斯滤波器或核g(x,y)与图像I卷积在一起。在这里,我们希望确保任何给定的像素在输出中都必须与其相邻像素相似,因此我们使用矩阵[1 1 1]为了保持像素之间的相似度并消除噪点。

    Image for post

    g(x,y)= Gausian Distribution

    g(x,y)=高斯分布

    I = input image

    I =输入图像

    Derivative :

    导数:

    Calculate the derivative of filter w.r.t X and Y dimensions and convolve it with I to give the gradient magnitude along the dimensions. Also the direction of image can be calculated using the tangent of angle between the two dimensions.

    计算滤波器X和Y尺寸的导数,并将其与I卷积,以得出沿尺寸的梯度幅度。 同样,可以使用两个维度之间的角度切线来计算图像方向。

    Image for post

    The above convolution results in gradient vector which has magnitude and direction.

    上述卷积导致具有大小和方向的梯度矢量。

    Image for post

    Below is an example of Gausian Derivatives which finally contribute to edges in output images.

    下面是高斯导数的一个示例,它们最终有助于输出图像中的边缘。

    Image for post

    Non Max Suppression

    非最大抑制

    Along an edge it is generally observed that the presence of few points make the visibility of edge more clearer. So we can neglect those edge points which don’t contribute more towards feature visibility. In order to achieve the same we use the Non Maximum Supression method . Here we mark the points on the curve of edge where the magnitude is largest . This can be obtained by looking for a maximum along a slice normal to the curve.

    通常沿着边缘观察到很少的点会使边缘的可见性更加清晰。 因此,我们可以忽略那些对特征可见性没有更多贡献的边缘点。 为了达到相同的目的,我们使用非最大压缩方法。 在这里,我们在边缘曲线上标记幅度最大的点。 这可以通过沿着垂直于曲线的切片寻找最大值来获得。

    Consider the edge in below figure which has 3 edge points. Assume point (x,y) as point having largest gradient of edge. Check for the edge points in direction perpendicular to the edge and verify if their gradient is less than (x,y) . If the values are less than (x,y) gradient then we can suppress those non maxima points along the curve .

    考虑下图中的边缘,该边缘具有3个边缘点。 假设点(x,y)为边缘的最大倾斜点。 检查垂直于边缘方向的边缘点,并验证它们的坡度是否小于(x,y)。 如果值小于(x,y)梯度,则我们可以抑制沿曲线的那些非最大值点。

    Image for post
    Image for post

    Hysteresis Thresholding :

    磁滞阈值:

    Image for post

    If the gradient at a pixel is :

    如果一个像素处的渐变为:

    - Above “High” declare it as a ‘edge pixel’.

    -在“高”上方,将其声明为“边缘像素”。

    - Below “Low” declare it as a ‘non-edge pixel’.

    -在“低”以下将其声明为“非边缘像素”。

    - Between “low” and “high”

    -在“低”和“高”之间

    • Consider its neighbours iteratively then declare it an “edge pixel” if its connected to an “edge pixel” or via pixels between “low” and “high”.

      反复考虑其邻居,然后将其声明为“边缘像素”(如果其连接到“边缘像素”或通过“低”与“高”之间的像素连接)。

    Thanks for reading !!

    谢谢阅读 !!

    Source Reference of Dr Mubarak Shah youtube videos.

    Mubarak Shah博士youtube视频的来源参考。

    翻译自: https://medium.com/analytics-vidhya/what-is-canny-edge-detection-algorithm-95defef75492

    canny边缘检测算法

    展开全文
  • 边缘检测算法.mp4

    2020-03-29 13:03:45
    边缘检测算法.mp4
  • 语音边缘检测算法VAD检测,零熵法检测matlab
  • 《数字图像中边 缘检测算法研究》内容主要包括:绪论、图像预处理 技术、整像素边缘检测算法、基于拟合的亚像素边缘 检测算法、基于矩的亚像素边缘检测算法、基于插值 的亚像素边缘检测算法、光条中心线检测方法、...
  • Canny边缘检测算法

    千次阅读 2019-09-26 14:10:15
    大部分边缘检测算法都是上个世纪的,OpenCV的使用的算法是Canny边缘检测算法,大概是1986年提出了,似乎说明边缘检测算法的研究已经到达了瓶颈期。跟人眼系统相比,边缘检测算法仍然逊色不少。 Canny边缘检测算法是...

    提取图片的边缘信息是底层数字图像处理的基本任务之一。边缘信息对进一步提取高层语义信息有很大的影响。大部分边缘检测算法都是上个世纪的,OpenCV的使用的算法是Canny边缘检测算法,大概是1986年提出了,似乎说明边缘检测算法的研究已经到达了瓶颈期。跟人眼系统相比,边缘检测算法仍然逊色不少。

    Canny边缘检测算法是比较出色的算法,它包含以下四个步骤:

    1. 高斯滤波

    滤波的主要目的是降噪,一般的图像处理算法都需要先进行降噪。而高斯滤波主要使图像变得平滑(模糊),同时也有可能增大了边缘的宽度。

    高斯函数是一个类似与正态分布的中间大两边小的函数。

    对于一个位置(m,n)的像素点,其灰度值(这里只考虑二值图)为f(m,n)。

    那么经过高斯滤波后的灰度值将变为:

    [公式]

    简单说就是用一个高斯矩阵乘以每一个像素点及其邻域,取其带权重的平均值作为最后的灰度值。

    2. 计算梯度值和梯度方向

    边缘是什么?边缘就是灰度值变化较大的的像素点的集合。一道黑边一道白边中间就是边缘,它的灰度值变化是最大的,在图像中,用梯度来表示灰度值的变化程度和方向。

    它可以通过点乘一个sobel或其它算子得到不同方向的梯度值 [公式] , [公式] 。

    综合梯度通过以下公式计算梯度值和梯度方向:

    [公式]

    [公式]

    3. 过滤非最大值

    在高斯滤波过程中,边缘有可能被放大了。这个步骤使用一个规则来过滤不是边缘的点,使边缘的宽度尽可能为1个像素点:如果一个像素点属于边缘,那么这个像素点在梯度方向上的梯度值是最大的。否则不是边缘,将灰度值设为0。

    4. 使用上下阀值来检测边缘

    一般情况下,使用一个阀值来检测边缘,但是这样做未免太武断了。如果能够使用启发式的方法确定一个上阀值和下阀值,位于下阀值之上的都可以作为边缘,这样就可能提高准确度。

    它的步骤是这样的。

    它设置两个阀值(threshold),分别为maxVal和minVal。其中大于maxVal的都被检测为边缘,而低于minval的都被检测为非边缘。对于中间的像素点,如果与确定为边缘的像素点邻接,则判定为边缘;否则为非边缘。

    参考链接:

    1.canny edge detector tutorial

    2.canny edge detection

    3.fundamental of computer vision(p45-p48)

    4.edge detection

    展开全文
  • 数字图像处理中边缘检测,canny是最优的边缘检测算法。对图像高斯滤波、求梯度、局部非极大值抑制、设置图像边缘为不可能的边缘点
  • 针对嵌入式图像处理中边缘检测算法要求越来越高的实时性,通过Xilinx的Vivado HLS工具加速实现嵌入式图像处理中的边缘检测算法。基于Vivado HLS工具,选用ALINX-7020作为开发平台对Sobel边缘检测进行加速。根据...
  • 一种边缘检测算法

    2018-07-17 21:39:24
    利用4邻域差值和4邻域方差两种检测算法融合,得到一种新的边缘检测算法。里面参数可以根据实际应用自己调整。编着玩玩,matlab 2014a,可直接运行。想学习的留言再交流。
  • matlab开发-边缘检测算法。本演示演示了如何序列化图像并在其上应用Sobel运算符来检测其边缘。
  • 边缘检测算法一般包含如下四个步骤:  1.滤波(去噪)  2.增强(一般是通过计算梯度幅值)  3.检测(在图像中有许多点的梯度幅值会比较大,而这些点并不都是边缘,所以应该用某种方法来确定边缘点,比如最简单...

    首先回顾一下边缘检测的一般步骤:

    边缘检测算法一般包含如下四个步骤:

      1.滤波(去噪)

      2.增强(一般是通过计算梯度幅值)

      3.检测(在图像中有许多点的梯度幅值会比较大,而这些点并不都是边缘,所以应该用某种方法来确定边缘点,比如最简单的边缘检测判据:梯度幅值阈值)

      4.定位(有的应用场合要求确定边缘位置,可以在子像素水平上来估计,指出边缘的位置和方向)

     

    边缘检测方法比较常用的有基于各种算子的方法,有基于一阶导数的各种算子(Roberts、Sobel、Prewitt等),还有基于二阶导数的拉普拉斯算子等。

    其中一阶导数一般找梯度极大值。

    二阶导数找过零点(需要忽略无意义的过零点(即均匀零区))。

    本文主要概述一下边缘检测中比较有代表性的的Canny和LoG算法。

    其中Canny基于一阶导数,而LoG算法基于二阶导数。

     

    Canny边缘检测器

    Canny边缘检测的算法步骤:

      1.用高斯滤波器平滑图像(不同尺度的Canny检测子由高斯的不同标准差来表示)

      2.用一阶偏导有限差分计算梯度幅值和方向(梯度方向为边缘法向)

      3.对梯度幅值进行非极大值抑制(Non-Maxima Suppression, NMS)

      4.用双阈值算法检测和连接边缘

      其中非极大值抑制细化了幅值图像中的屋脊带,只保留幅值局部变化最大的点。

      双阈值算法:用两个阈值得到两个阈值图像,然后把高阈值的图像中的边缘连接成轮廓,连接时到达轮廓的端点时,在低阈值图像上找可以连接的边缘。不断收集,直到所有的间隙连接起来为止。

     

    LoG边缘检测算法

    LoG边缘检测算法步骤:

      1.平滑:高斯滤波器

      2.增强:Laplacian算子计算二阶导

      3.检测:二阶导零交叉点并对应于一阶导数的较大峰值

      4.定位:线性内插

    根据卷积的求导法则,先卷积后求导和先求导后卷积是相等的,所以可以把第1、2步合并为一步,先对高斯滤波器做拉普拉斯变换,得到墨西哥草帽算子,然后再用这个算子与图像做卷积。

    这个算子还有一个有效的近似:使用两个具有明显不同的标准差的高斯平滑掩模的差(DoG, difference of Gaussians)。

    转载于:https://www.cnblogs.com/mengdd/archive/2012/10/20/2732179.html

    展开全文
  • 提出了一种完全不涉及梯度运算、只基于周边像素灰度比较的SUSAN边缘检测算法。主要介绍了SUSAN算法的原理,并用MATLAB编程实现了该算法。在对噪声图像的边缘检测中,与其他传统经典检测算子进行比较,结果表明,该...
  • 本文件包为canny边缘检测算法代码,matlab编写,用于检测图像边缘。
  • 数字图像处理中的拉普拉斯边缘检测算法,先计算图像直方图,灰度值分割阈值,并计算各阈值下的前景和背景概率密度函数,再进行像素的累计熵
  • 本资源内包含几种常见的边缘检测算法的MATLAB代码,下载直接可用。边缘检测算法包括prewitt,sobel,roberts等。
  • 边缘检测算法汇总

    千次阅读 2018-07-02 20:43:31
    Canny边缘检测算子Canny边缘检测算子是一个多级边缘检测算法。通常情况下边缘检测的目的是在保留原有图像属性的情况下,显著减少图像的数据规模。最优边缘准则Canny 的目标是找到一个最优的边缘检测算法,最优边缘...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,934
精华内容 1,573
关键字:

边缘检测算法