精华内容
下载资源
问答
  • FAST角点检测算法MATLAB程序

    热门讨论 2013-09-02 17:18:03
    FAST是一种经典的特征快速检测算法,在网上逛了很久才找到这个matlab程序。分享给大家。
  • 该压缩包是对fast角点检测代码的总结,包括matlab,c++,opencv代码实现以及参考的文献和代码使用说明,适合于初学者使用。
  • Harris 角点检测实现原理OpenCV 函数优化GFTT 在图像处理和计算机视觉领域,兴趣(inter points),也被称作关键(key points)、特征(feature points)。它被大量用于解决物体识别、图像识别、图像匹配、...

    在图像处理和计算机视觉领域,兴趣点(inter points),也被称作关键点(key points)、特征点(feature points)。它被大量用于解决物体识别、图像识别、图像匹配、视觉跟踪、三维重建等一系列的问题。我们不再观察整幅图,而是选择某些特殊的点,然后对它们进行局部有的放矢地分析。如果能检测到足够多的这种点,同时它们的区分度很高,并且可以精确定位稳定的特征,那么这个方法就具有实用价值。

    图像特征类型可以被分为如下三种:

    • 边缘
    • 角点(感兴趣关键点)
    • 斑点(Blobs)(感兴趣区域)

    对于边缘检测之前已经讲过,见 边缘检测1 边缘检测2 。其中角点是个很特殊的存在。如果某一点在任意方向的一个微小变动都会引起灰度很大的变化,那么我们就把它称之为角点。角点作为图像上的特征点,包含有重要的信息,在图像融合和目标跟踪及三维重建中有重要的应用价值。他们在图像中可以轻易地定位,同时,在人造物体场景,比如门、窗、桌等处也随处可见。因为角点位于两条边缘的角点处,代表了两个边缘变化的方向上的点,所以它们是可以精确定位的二维特征,甚至可以达到亚像素的精度。又由于其图像梯度有很高的变化,这种变化是可以用来帮助检测角点的。需要注意的是,角点与位于相同强度区域上的点不同,与物体轮廓上的点也不同,因为轮廓点难以在相同的其他物体上精确定位。

    另外,关于角点的具体描述可以有如下几种:

    • 一阶导数(即灰度的梯度)的局部最大所对应的像素点;
    • 两条及以上边缘的交点;
    • 图像中梯度值和梯度方向的变化速率都很高的点;
    • 角点处的一阶导数最大,二阶导数为零,它指示了物体边缘变化不连续的方向

    现有的角点检测算法并不是都十分健壮。很多方法都要求有大量的训练集和冗余数据来防止减少错误特征的出现。另外,角点检测方法的一个很重要的评价标准是其对多幅图像种相同或相似的检测能力,并且能够应对光照变换、图像旋转等图像变化。

    在当前的图像处理领域,角点检测算法可归纳为以下三类:

    • 基于灰度图像的角点检测
    • 基于二值图像的角点检测
    • 基于轮廓曲线的角点检测

    而基于灰度图像的角点检测又可分为基于梯度、基于模板和基于模板梯度组合三类方法。其中基于模板的方法主要考虑像素领域点的灰度变化,即图像亮度的变化,将与邻点亮度对比足够大的点定义为角点。常见的基于模板的角点检测算法有 Kitchen-Rosenfeld 角点检测算法、Harris 角点检测算法、KLT角点检测算法及SUSAN角点检测算法。

    Harris 角点检测

    Harris 角点检测是一种直接基于灰度图像的角点提取算法,稳定性高,尤其对L型角点检测精度高。但由于采用了高斯滤波,运算速度相对较慢,角点信息有丢失和位置偏移的现象,而且角点提取有聚簇现象。

    实现原理

    为了定义图像中角点的概念,Harris 特征检测方法在假定的兴趣点周围放置了一个小窗口,并观察窗口内某个方向上强度值的平均变化。如果位移向量为 ( u , v ) (u, v) (u,v) ,那么可以用均方差之和表示强度的变化:
    R = ∑ ( I ( x + u , y + v ) − I ( x , y ) ) 2 R = \sum (I(x+u,y+v) - I(x, y))^2 R=(I(x+u,y+v)I(x,y))2
    累加的范围是该像素周围一个预先定义的邻域(邻域的尺寸取决于 cv::cornerHarris函数的第三个参数)。在所有方向上计算平均强度变化值,如果不止一个方向的变化值很高,就认为这个点是角点。根据这个定义,Harris测试的步骤应为:首先获得平均强度值变化最大的方向,然后检查垂直方向上的平均强度变化值,看它是否也很大;如果是,就说明这是一个角点。

    从数学的角度看,可以用泰勒展开式近似地计算上述公式,验证这个判断:
    R ≈ ∑ ( ( I ( x , y ) + ∂ I ∂ x u + ∂ I ∂ y v − I ( x , y ) ) 2 = ∑ ( ( ∂ I ∂ x u ) 2 + ( ∂ I ∂ y v ) 2 + 2 ∂ I ∂ x ∂ I ∂ y u v ) ) R \approx \sum \left((I(x,y) + \frac{\partial I}{\partial x}u + \frac{\partial I}{\partial y}v - I(x,y)\right)^2 = \sum \left( (\frac{\partial I}{\partial x}u)^2 + (\frac{\partial I}{\partial y}v)^2 + 2 \frac{\partial I}{\partial x} \frac{\partial I}{\partial y}uv) \right) R((I(x,y)+xIu+yIvI(x,y))2=((xIu)2+(yIv)2+2xIyIuv))
    写成矩阵形式就是:
    R ≈ [ u , v ] [ ∑ ( δ I δ x ) 2 ∑ ( δ I δ x δ I δ y ) ∑ ( δ I δ x − δ I δ y ) ∑ ( δ I δ y ) 2 ] [ u v ] R \approx [u, v] \begin{bmatrix} \sum(\frac{\delta I}{\delta x})^2 & \sum(\frac{\delta I}{\delta x}\frac{\delta I}{\delta y}) \\ \sum(\frac{\delta I}{\delta x}-\frac{\delta I}{\delta y})&\sum(\frac{\delta I}{\delta y})^2 \end{bmatrix} \begin{bmatrix} u \\ v \end{bmatrix} R[u,v][(δxδI)2(δxδIδyδI)(δxδIδyδI)(δyδI)2][uv]
    这是一个协方差矩阵,表示在所有方向上强度值变化的速率。这个定义包括了图像的一阶导数,通常用 Sobel 计算。这个协方差矩阵的两个特征值分别表示最大平均强度值变化和垂直方向的平均强度值变化。如果这两个特征值都很小,就说明是在相对同质的区域;如果一个特征值很大,另一个很小,那肯定是在边缘上;如果两者都很大,那么就是在角点上。因此判断一个点为角点的条件是它的协方差矩阵的最小特征值要大于指定的阈值。

    Harris角点算法的原始定义用到了特征分解理论的一些属性,从而避免显式地计算特征值带来的开销。这些属性是:

    • 矩阵的特征值之积等于它的行列式值
    • 矩阵的特征值之和等于它的对角元素之和(也就是矩阵的迹)

    通过计算下面的评分,可以验证矩阵的特征值高不高:
    D s t ( x , y ) = D e t ( C ( x , y ) ) − k ⋅ ( t r C ( x , y ) ) 2 Dst(x,y) = Det(C^{(x,y)}) - k \cdot (tr C^{(x,y)})^2 Dst(x,y)=Det(C(x,y))k(trC(x,y))2
    只要两个特征值都高,就很容易证明这个评分肯定也高。这个评分在每个像素的位置计算得到。数值 k k k 是参数,确定这个参数的最佳值是比较困难的。但是根据经验,0.05~0.5 通常是比较好的选择。

    OpenCV 函数

    cornerHarris

    void cv::cornerHarris(InputArray		src,
                          OutputArray		dst,
                          int				blockSize,
                          int				ksize,
                          double			k,
                          int				borderType = BORDER_DEFAULT 
                          )		
    //Python:
    dst	= cv.cornerHarris(src, blockSize, ksize, k[, dst[, borderType]])
    

    参数解释

    参数解释
    src输入图像,8 位或浮点型图像
    dst输出图像,存储函数调用后的运算结果,即 harris 角点检测的输出结果。类型为CV_32FC1,大小与src相同
    blockSize邻域的大小
    ksizeSobel 算子的孔径大小
    kHarris 参数
    borderType图像的边界模式,默认 BORDER_DEFAULT

    C++ 示例

    void myHarris(Mat& image){
        Mat cornerStrenth, harrisTh;
      	// 检测 Harris 角点
        cornerHarris(image, cornerStrenth, 2, 3, 0.01);
      	// 对角点强度阈值化
        threshold(cornerStrenth, harrisTh, 0.0001, 255, CV_THRESH_BINARY);
        imwrite("harrisTh.jpg", harrisTh);
    }
    int main(){
        Mat image = imread("test.jpg");
        Mat imageGray;
        cvtColor(image, imageGray, COLOR_BGR2GRAY);
        myHarris(image);
        return 0;
    }
    

    效果如下:

    在这里插入图片描述

    由此得到的角点分布图中包含很多聚集的角点像素,而不是我们想要检测的具有明确定位的角点。接下来通过定义一个检测 Harris 角点的类,改进角点检测方法。

    优化

    为了提升检测效果,使用了一个额外的非最大值抑制步骤,作用是排除掉紧邻的 Harris 角点。因此,Harris 角点不仅要有高于指定阈值的评分,还必须是局部范围内的最大值。为了检查这个条件,对 Harris 使用了膨胀运算,膨胀运算会在邻域中把每个像素值替换成最大值,因此只有局部最大值的像素是不变的。

    文件 harrisDetector.h

    #include<iostream>
    using namespace std;
    #include<opencv2/opencv.hpp>
    #include<opencv2/highgui.hpp>
    using namespace cv;
    
    class HarrisDetector{
    
    private:
        // 32 位浮点数型的角点强度图像
        Mat cornerStrength;
        // 32 位浮点数型的阈值化角点图像
        Mat cornerTh;
        // 局部最大值
        Mat localMax;
        // 平滑导数的邻域尺寸
        int neighborhood;
        // 梯度计算的口径
        int aperture;
        // Harris 参数
        double k;
        // 阈值计算的最大强度
        double maxStrength;
        // 计算得到的阈值(内部)
        double threshold;
        // 非最大值抑制的邻域尺寸
        int nonMaxSize;
        // 非最大值抑制的内核
        Mat kernel;
    
    public:
        Mat getCornerTh(){return cornerTh;}
    
        HarrisDetector() : neighborhood(3), aperture(3), k(0.01), maxStrength(0.0), threshold(0.01), nonMaxSize(3){
            // 创建用于非最大值一直的内核
            setLocalMaxWindowSize(nonMaxSize);
        }
        // 计算 Harris 角点
        void detect(const Mat& image);
        // 用 Harris 值得到角点分布图
        Mat getCornerMap(double qualityLevel);
        // 用 Harris 得到特征点
        void getCorners(vector<Point>& points, double qualityLevel);
        // 用角点分布图得到特征点
        void getCorners(vector<Point>& points, const Mat& cornerMap);
        // 在特征点的位置画圆形
        void drawOnImage(Mat& image, const vector<Point>& points, Scalar color=Scalar(0, 0, 255), int radius=3, int thickness=1);
    
        void setLocalMaxWindowSize(int nonMaxSize);
    };
    

    文件 harrisDetector.cpp

    #include "harrisDetector.h"
    
    
    /**
     * 计算 Harris 角点
     * */
    void HarrisDetector::detect(const Mat& image){
        // 计算 Harris
        cornerHarris(image, cornerStrength, neighborhood, aperture, k);
        // 计算内部阈值
        minMaxLoc(cornerStrength, 0, &maxStrength);
        // 检测局部最大值
        Mat dilated; // 临时图像
        dilate(cornerStrength, dilated, Mat());
        compare(cornerStrength, dilated, localMax, CMP_EQ);
    }
    
    /**
     * 用指定的阈值获得特征点
     * */
    Mat HarrisDetector::getCornerMap(double qualityLevel){
        Mat cornerMap;
        // 对角点强度阈值化
        threshold = qualityLevel * maxStrength;
        cv::threshold(cornerStrength, cornerTh, threshold, 255, THRESH_BINARY);
        // 转换成 8 位图像
        cornerTh.convertTo(cornerMap, CV_8U);
        // 非最大值抑制
        bitwise_and(cornerMap, localMax, cornerMap);
        return cornerMap;
    }
    
    void HarrisDetector::getCorners(vector<Point>& points, double qualityLevel){
        // 获得角点分布
        Mat cornerMap = getCornerMap(qualityLevel);
        // 获得角点
        getCorners(points, cornerMap);
    }
    
    void HarrisDetector::getCorners(vector<Point>& points, const Mat& cornerMap){
        // 迭代遍历,得到所有特征
        for(int y = 0; y < cornerMap.rows; y++){
            const uchar* rowPtr = cornerMap.ptr<uchar>(y);
            for(int x = 0; x < cornerMap.cols; x++){
                // 如果它是一个特征点
                if (rowPtr[x]){
                    points.push_back(Point(x, y));
                }
            }
        }
    }
    
    void HarrisDetector::drawOnImage(Mat& image, const vector<Point>& points, Scalar color, int radius, int thickness){
        for(int i = 0; i < points.size(); i++){
            circle(image, points[i], 3, color, thickness);
        }
    }
    
    void HarrisDetector::setLocalMaxWindowSize(int nonMaxSize){
        kernel = getStructuringElement(MORPH_RECT, Size(nonMaxSize, nonMaxSize));
    }
    

    文件 main.cpp

    #include "harrisDetector.h"
    
    
    int main(){
        Mat image = imread("test.jpg");
        Mat imageGray;
        cvtColor(image, imageGray, COLOR_BGR2GRAY);
        // 创建 Harris 检测器实例
        HarrisDetector harris;
        // 计算 Harris 值
        harris.detect(imageGray);
        // 检测 Harris 角点
        vector<Point> pts;
        harris.getCorners(pts, 0.02);
        // 画出 Harris 角点
        harris.drawOnImage(image, pts);
        // 保存画出角点的图像
        imwrite("harris.jpg", image);
        return 0;
    

    效果如下:

    在这里插入图片描述

    尽管引入了局部最大值这个条件,兴趣点仍不会在图像中均匀分布,而是聚集在高度纹理化的位置。接下来介绍 OpenCV 的一个角点检测优化,可以让兴趣点均匀分布在图像中。

    Shi-Tomasi 角点检测

    实现原理

    通过限制两个兴趣点之间的最短距离解决特征点聚集的问题,使角点在图像中的分布更加均匀。从 Harris 值最强的点开始(即具有最大的最低特征值),只允许一定距离之外的点成为兴趣点。在 OpenCV 中用 good-features-to-track(GFTT)实现这个算法。这个算法得名于它检测的特征非常适合作为视觉跟踪程序的起始集合,可以使用类 从cv::GFTTDetector ,也可以使用方法 cv::goodFeaturesToTrack 做角点检测。

    在内部,cv::goofFeaturesToTrack()cv::GFTTDetector() 有一定特定的阶段:自相关矩阵 C 的计算、该矩阵的分析以及应用的某种阈值。关键步骤使用函数 cv::cornerharris()cv::cornerMinEigenVal() 完成,这两个函数的参数完全类似于函数 cv::goodFeatureTotrack() ,首先使用 Harris 使用的特征值填充 dst,第二次使用 Shi 和 Tomasi 使用的特征值填充 dst,即自相关矩阵 C 的最小特征值。

    GFTTDetector 使用方法如下:

    // 计算适合跟踪的特征
    vector<KeyPoint> keypoints;
    // GTFF 检测器
    Ptr<GFTTDetector> ptrGFTT = GFTTDetector::create(500, 0.01, 10);
    // 检测 GFTT
    ptrGFTT->detect(image, keypoints);
    

    首先使用特定的静态函数(cv::GFTTDetector::create)创建特征检测器,并初始化参数。除了质量等级阈值和兴趣点间的最小距离,该函数还需要提供允许返回的最大点数(这些点是按照强度排序的)。函数返回一个执行检测器实例的智能指针。构建完这个实例后,就可以调用检测方法了。其中 cv::KeyPoint 类,封装了每个检测到的特征点的属性,可以使用 drawKeypoints 画出关键点。对于 Harris 角点来说,只与关键点位置和它的反馈强度有关。

    方法goodFeaturesToTrack 见以下 OpenCV 函数:

    OpenCV 函数

    cv::GFTTDetector::create

    static Ptr<GFTTDetector> cv::GFTTDetector::create (
    		    int			maxCorners = 1000,
    			double		qualityLevel = 0.01,
    			double 		minDistance = 1,
    			int			blockSize = 3,
    			bool		useHarrisDetector = false,
    			double 		k = 0.04 
    	) 		
    static Ptr<GFTTDetector> cv::GFTTDetector::create (
    			int 		maxCorners,
    			double		qualityLevel,
    			double		minDistance,
    			int			blockSize,
    			int			gradiantSize,
    			bool		useHarrisDetector = false,
    			double		k = 0.04 
    	) 	
    //Python:
    retval = cv.GFTTDetector_create([,maxCorners[,qualityLevel[,minDistance[, blockSize[,useHarrisDetector[, k]]]]]])
    retval = cv.GFTTDetector_create(maxCorners, qualityLevel, minDistance, blockSize, gradiantSize[, useHarrisDetector[, k]])
    

    OpenCV 特征检测公共接口定义了一个虚拟类 cv::Feature2DGFTTDetector 继承于这个虚拟类,它可以确保其他类包含以下格式的 detect 方法:

    detect

    void detect(InputArray image,
                CV_OUT std::vector<KeyPoint>& keypoints,
                InputArray mask=noArray() );
    void detect(InputArrayOfArrays images,
                CV_OUT std::vector<std::vector<KeyPoint> >& keypoints,
                InputArrayOfArrays masks=noArray() );
    

    第二个方法,可以检测多个图像的关键点。

    参数解释
    image要检测的图像
    keypoints检测到的关键点,在方法的第二个变体中,keypoints[i] 是在 images[i] 中检测到的一组关键点
    mask指定在哪里寻找关键点的掩码(可选)。 它必须是一个8位整数矩阵,在感兴趣的区域中具有非零值。

    drawKeypoints

    void cv::drawKeypoints( InputArray			image,
    						const std::vector< KeyPoint > &	keypoints,
    						InputOutputArray	outImage,
    						const Scalar &		color = Scalar::all(-1),
    						int					flags = DrawMatchesFlags::DEFAULT 
    	) 		
    //Python:
    outImage = cv.drawKeypoints(image, keypoints, outImage[, color[, flags]])
    
    参数解释
    image源图像
    keypoints源图像的关键点
    outImage输出图像,它的内容取决于 flags,flags 定义了在输出图像中绘制的内容。
    color关键点的颜色
    flags设置绘制方式。

    使用负数作为关键点的颜色,画每个圆时会随机选取不同的颜色。

    flags:

    • DEFAULT = 0
      将创建输出图像矩阵,即可以重用输出图像的现有内存。将绘制两个源图像,匹配项和单个关键点。 对于每个关键点,只会绘制中心点(没有围绕关键点的圆以及关键点的大小和方向)。
    • DRAW_OVER_OUTIMG = 1
      将不创建输出图像矩阵。匹配项将在现有的输出图像上进行绘制。
    • NOT_DRAW_SINGLE_POINTS = 2
      不会绘制单个关键点。
    • DRAW_RICH_KEYPOINTS = 4
      对于每个关键点,将在关键点周围绘制带有关键点大小和方向的圆圈。

    Note : For Python API, flags are modified as cv2.DRAW_MATCHES_FLAGS_DEFAULT, cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS, cv2.DRAW_MATCHES_FLAGS_DRAW_OVER_OUTIMG, cv2.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS

    goodFeaturesToTrack

    void cv::goodFeaturesToTrack( InputArray		image,
                                  OutputArray		corners,
                                  int				maxCorners,
                                  double			qualityLevel,
                                  double			minDistance,
                                  InputArray		mask = noArray(),
                                  int				blockSize = 3,
                                  bool				useHarrisDetector = false,
                                  double			k = 0.04 
    )		
    // Python:
    corners	=cv.goodFeaturesToTrack(image, maxCorners, qualityLevel, minDistance[, corners[, mask[, blockSize[, useHarrisDetector[, k]]]]])
    corners	= cv.goodFeaturesToTrack(	image, maxCorners, qualityLevel, minDistance, mask, blockSize, gradientSize[, corners[, useHarrisDetector[, k]]])
    
    
    参数解释
    image输入图像,8位或32位单通道图像
    corners检测到的角点的输出向量
    maxCorners角点的最大数量
    qualityLevel角点检测可接受的最小特征值,其实实际用于过滤角点的最小特征值是 qualityLevel 与图像中最大特征值的乘积。所以 qualityLevel 通常不会超过1(常用的值为0.10 或 0.01)。而检测完所有的角点后,还要进一步剔除掉一些距离较近的角点
    minDistance角点之间的最小距离,此参数用于保证返回的角点之间的距离不小于 minDistance 个像素
    mask可选参数,表示感兴趣区域,有默认值 noArray()。若此参数非空(需为 CV_8UC1 类型,且和第一个参数 image 有相同的尺寸),便用于指定角点检测区域。
    blockSize默认值3,计算导数自相关矩阵时指定的邻域范围
    useHarrisDetector默认值 false,指示是否使用 Harris 角点检测
    k默认值 0.04,为用于设置 Hessian 自相关矩阵行列式的相对权重的权重系数

    C++示例

    
    #include<iostream>
    using namespace std;
    
    #include<opencv2/opencv.hpp>
    #include<opencv2/highgui.hpp>
    using namespace cv;
    
    
    void myHarris(Mat& image){
        // 计算适合跟踪的特征
        vector<KeyPoint> keypoints;
        // GTFF 检测器
        Ptr<GFTTDetector> ptrGFTT = GFTTDetector::create(500, 0.01, 10);
        // 检测 GFTT
        ptrGFTT->detect(image, keypoints);
    	// 画出关键点    
    	drawKeypoints(image, keypoints, image, Scalar::all(-1), DrawMatchesFlags::DRAW_OVER_OUTIMG);
    
        imwrite("harrisThGFTT.jpg", image);
    }
    
    void myHarris2(Mat& image){
        vector<Point> corner;
        goodFeaturesToTrack(image, corner, 500, 0.01, 10);
        for (int i = 0; i < corner.size(); i++){
            circle(image, corner[i], 3, Scalar::all(-1), 1);
        } 
    }
    
    int main(){
        Mat image = imread("test.jpeg");
        Mat imageGray;
        cvtColor(image, imageGray, COLOR_BGR2GRAY);
        myHarris(imageGray);
        return 0;
    }
    

    效果如下:

    在这里插入图片描述

    由于需要让兴趣点按照 Harris 评分排序,因此该检测方法的复杂度有所提高,但是它也明显改进了兴趣点在整幅图像中的分布情况。此函数还有一个可选的标志,该标志要求在检测 Harris 角点时,采用经典的角点评分定义(使用协方差矩阵的行列式值和迹)。

    FAST 角点检测

    Harris 算子对角点(或者更通用的兴趣点)做出了规范的数学定义,该定义基于强度值在两个互相垂直的方向上的变化率。但是它需要计算图像的导数,而计算导数是非常耗时的。尤其要注意的是,检测兴趣点通常只是更复杂的算法中的第一步。

    本篇文章将介绍另一种特征点算子,叫做 FAST(Features from Accelerated Segment Test,加速分割测试获得特征)。这种算子专门用来快速检测兴趣点——只需对比几个像素,就可以判断它是否为关键点。

    实现原理

    跟 Harris 检测器的情况一样,FAST 特征算法源于“什么构成了角点”的定义。FAST 对角点的定义基于候选特征点周围的图像强度值。以某个点为中心做一个圆,根据原上的像素值判断该点是否为关键点。如果存在这样一段圆弧,它的连续长度超过周长的 3/4,并且它上面所有像素的强度值都与圆心的强度值明显不同(全部更暗或更亮),那么就认定这是一个关键点。

    这种测试方法非常简单,计算速度也很快。而且在它的原始公式中,算法还用了一个技巧来进一步提高处理速度。如果我们测试圆周上相隔 90 度的四个点(例如取上、下、左、右四个位置),就很容易证明:为了满足前面的条件,其中必须有三个点都比圆心更亮或都比圆心更暗。

    如果不满足该条件,就可以立即排除这个点,不需要检查圆周上的其他点。这种方法非常高效,因为在实际应用中,图像中大部分像素都可以用这种“四点比较法”排除。

    从概念上讲,用于检查像素的圆的半径作为方法的一个参数。但是根据经验,半径为 3 时可以得到好的结果和较高的计算效率。因此需要在圆周上检查 16 个像素,如下图所示。

    在这里插入图片描述

    这里用来预测试的像素时1、5、9 和 13,至少需要 9 个比圆心更暗(或更亮)的连续像素。这种设置通常称为 FAST-9 角点检测器,也是 OpenCV 默认采用的方法。你可以在构建检测器实例时指定 FAST 检测器的类型。

    一个点与圆心强度值的差距必须达到一个指定的值,才能被认为是明显更暗或更亮;这个值就是创建检测器实例时指定的阈值参数。这个阈值越大,检测到的角点数量就越少。

    至于 Harris 特征,通常最好在发现的角点上执行非最大值抑制。因此,需要定义一个角点强度的衡量方法。有多种衡量方法可供选择,可以通过以下方法获取角点强度——计算中心点像素与认定的连续圆弧上的像素的差值,然后将这些差值的绝对值累加,就能得到角点强度。可以从 cv::KeyPoint 实例的 response 属性获取角点强度。

    用这个算法检测兴趣点的速度非常快,因此十分适合需要优先考虑速度的应用,包括实时视觉跟踪、目标识别等,它们需要在实时视频流中跟踪或匹配多个点。

    OpenCV 函数

    FastFeatureDetector

    static Ptr<FastFeatureDetector> cv::FastFeatureDetector::create(
      		int		threshold = 10,
          	bool	nonmaxSuppression = true,
          	int		type = FastFeatureDetector::TYPE_9_16 
    )		
    // Python:
    retval = cv.FastFeatureDetector_create([, threshold[, nonmaxSuppression[, type]]])
    

    参数解释

    参数解释
    threshold与圆心强度值的阈值
    nonmaxSuppression非最大值抑制
    type圆的大小

    每种类型都指定圆的周长和该圆的中心被认为是关键点所需的临近点的数量,type:

    • TYPE_5_8 = 0
      圆半径为1,表示表示 8 点中的 5 点应该比中心点都更亮或者都要暗
    • TYPE_7_12 = 1
      圆半径为2,表示表示 12 点中的 7 点应该比中心点都更亮或者都要暗
    • TYPE_9_16 = 2
      圆半径为3,表示 16 点中的 9 点应该比中心点都更亮或者都要暗

    C++示例

    void myFAST(Mat& image){
        // 关键点的向量
        vector<KeyPoint> keypoints;
        // FAST 特征检测器,阈值为 40
        Ptr<FastFeatureDetector> ptrFAST = FastFeatureDetector::create(40);
        // 检测关键点
        ptrFAST->detect(image, keypoints);
        // 画出关键点
        drawKeypoints(image, keypoints, image, Scalar::all(-1), DrawMatchesFlags::DRAW_OVER_OUTIMG);
    }
    
    int main()
    {
        string outDir = "./";
        Mat image = imread("img7.jpg");
        if (image.empty()) {
            cout << "could not load image..." << endl;
            return -1;
        }
        myFAST(image);
        imwrite(outDir + "FAST.jpg", image);
        return 0;
    }
    

    效果图

    在这里插入图片描述

    优化

    应用程序不同,检测特征点时采用的策略也不同。

    例如在事先明确兴趣点数量的情况下,可以对检测过程进行动态适配。简单的做法就是采用范围较大的阈值检测出很多兴趣点,然后从中提取出 n 个强度最大的。为此可以使用这个标准 C++ 函数 std::nth_element()

    if(numberOfPoint < keypoints.size())
    	std::nth_element(
      				keypoints.begin(),
                    keypoints.begin()+numberOfPoints,
                    keypoints.end(),
                    [](cv::KeyPoint& a, cv::KeyPoint& b){
                    return a.response > b.response;})
    

    函数解释

    函数中 keypoints 类型是 std::vector,表示检测到的兴趣点, numberOfPoints 是需要的兴趣点数量。最后一个参数 lambda 比较器,用于提取最佳的兴趣点。如果检测到的兴趣点太少(少于需要的数量),那就要采用更小的阈值,但是阈值太宽松又会加大计算量,所以需要权衡利弊,选取最佳的阈值。

    检测图像特征点时还会遇到一种情况,就是兴趣点分布很不均匀。keypoint 通常会聚集在纹理较多的区域。对此有一种常用的处理方法,就是把图像分割成网格状,对每个小图像进行单独检测。

    C++示例

    void myFAST2(Mat& image){
        int totalPoints = 100;  // 总共 100 个关键点
        int cols = image.cols;
        int rows = image.rows;
        int vstep = 10;					// 垂直分 10 份
        int hstep = 10;					// 水平分 10 份
        int hsize = cols / hstep;
        int vsize = rows / vstep;
        int subtotal = totalPoints / (vstep * hstep); // 每个子块中的关键点
        Mat imageROI;
        // 关键点
        vector<KeyPoint> keypoints;
        vector<KeyPoint> gridpoints;
        // FAST 特征检测器
        Ptr<FastFeatureDetector> ptrFAST = FastFeatureDetector::create(40);
        // 检测每个网格
        for(int i = 0; i < vstep; i++){
            for(int j = 0; j < hstep; j++){
                // 在当前网格创建ROI
                imageROI = image(Rect(j*hsize, i*vsize, hsize, vsize));
    //            imageROI = image(Range(), Range());
                // 在网格中检测关键点
                gridpoints.clear();
                ptrFAST->detect(imageROI, gridpoints);
                // 获取强度最大的 FAST 特征
                auto itEnd(gridpoints.end());
                if(gridpoints.size() > subtotal){
                    // 选取最强的特征
                    nth_element(gridpoints.begin(), gridpoints.begin()+subtotal, gridpoints.end(), [](cv::KeyPoint& a, cv::KeyPoint& b){return a.response > b.response;});
                    itEnd = gridpoints.begin() + subtotal;
                }
                for(auto it = gridpoints.begin(); it != itEnd; ++it){
                    // 转成图像上的坐标
                    it->pt += cv::Point2f(j*hsize, i*vsize);
                    keypoints.push_back(*it);
                }
            }
        }
        // 画出关键点
        drawKeypoints(image, keypoints, image, Scalar::all(-1), DrawMatchesFlags::DRAW_OVER_OUTIMG);
    }
    
    int main()
    {
        string outDir = "./";
        Mat image = imread("img7.jpg");
        if (image.empty()) {
            cout << "could not load image..." << endl;
            return -1;
        }
        Mat imageGray;
        cvtColor(image, imageGray, COLOR_BGR2GRAY);
        myFAST2(image);
        imwrite(outDir + "FAST2.jpg", image);
        return 0;
    
    }
    

    网格优化

    利用 ROI 对每个网格的小图像进行关键点检测,这样的到的关键点分布较为均匀。


    这一篇文章介绍的特征检测器可以比较好的解决方向不变性问题,即图像旋转后仍能检测到相同的特征点。下一篇文章介绍可以解决尺度不变性问题的方法,不仅在任何尺度下拍摄的物体都能检测到一致的关键点,而且每个被检测的特征点都对应一个尺度因子。

    展开全文
  • fast角点检测c++

    2015-01-26 15:17:02
    该压缩包是关于fast角点检测的c++实现的,适用于初学者。
  • 计算机视觉(角点检测)- FAST角点检测

    学习前言

      关于角点检测呢,就是检测图像中角点的算法,常见的有四种常见的算法:Moravec角点检测算法、 Harris角点检测算法.、 Shi-Tomasi 算法.、FAST角点检测算法,不过常用的就两种吧——Harris角点检测算法、FAST角点检测算法
    在这里插入图片描述

    一、FAST角点检测

      FAST角点检测,它叫FAST,这命名就是在说明它快,优秀。接下来,我们详细解析一下FAST角点检测方法。
      我们看到了几个特征检测器,其中很多真的很棒。但是,从实时应用程序的角度来看,它们不够快。最好的例子是具有有限计算资源的SLAM(同时定位和制图)移动机器人。
      作为对此的解决方案,Edward Rosten和Tom Drummond在2006年的论文“用于高速拐角检测的机器学习”中提出了FAST(加速段测试的特征)算法(后来在2010年对其进行了修订)。


      总的来说FAST角点检测还是比较简单的,那么让我们来看看作者是怎么定义FAST角点的 - FAST角点:若某像素与其周围邻域内足够多的像素点相差较大,则该像素可能是角点。 我们来看一个例子,帮助理解:
    在这里插入图片描述
      这个例子是很经典的,基本上所有跟FAST角点检测介绍的都会引用这个例子。慢慢按照步骤来讲就是:

       1. 先选取一个像素点—— p p p,其灰度值我们用 I ( p ) I(p) I(p)表示。以像素 p p p为中心,画一个半径为3像素的圆,我们取圆上的16个像素点,记作 p 1 . . . . p 16 p_1....p_{16} p1....p16,灰度值分别表示为 I ( p 1 ) . . . . . I ( p 16 ) I(p_1).....I(p_{16}) I(p1).....I(p16)

       2. 我们选定一个阈值 t t t

       3. 首先计算 p 1 、 p 9 、 p 5 、 p 13 p1、p9、p5、p13 p1p9p5p13(分别在四个方向的四个点)与中心 p p p的像素差,若它们的绝对值有至少3个超过阈值 t t t,则当做候选角点,再进行下一步考察;否则,不可能是角点。

       4. 在 p p p是候选点的情况下,计算 p 1 p1 p1 p 16 p16 p16这16个点与中心 p p p的像素差, 若它们有至少连续 9 9 9个超过阈值(也可以测试其他大小,实验表明9的效果更好),则是角点;否则,不是角点。一般情况下,n是取12,所以这个标准定义为FAST-12,而实际上当n=9时,往往能取得较好的效果。

       5. 将1~4步的操作,遍布整个图像。

       6. 对整个图片进行计算后,很可能大部分检测出来的点彼此之间相邻,我们要去除一部分这样的点。为了解决这一问题,我们采用了 非极大值抑制的算法,目的去除小区域内多个重复的特征点:

          - 计算特征点处的FAST得分值 V V V(或者说响应值),即16个点与中心差值的绝对值总和。

          - 判断以特征点p为中心的一个邻域(可以设为3x3或着5x5)内,若有多个特征点,则判断每个特征点的响应值,如果 p p p是其中最大的,则保留,否则,删除。如果只有一个特征点,就保留。

          - 得分计算公式如下(公式中用 V V V表示得分, t t t表示阈值):

    在这里插入图片描述

       对比一下,之前介绍的两种算法: Harris角点检测算法.、 Shi-Tomasi 算法.,FAST角点检测还是蛮简单的,而且计算速度也是相对于其他方式也是非常快的,但是还是有一些缺点:

    • 在首先的四点检测里,只有2个点同中心点不相似,也并不能说明这不是角点。
    • 前面的四点检测结果和后面的16点检测的计算有一定重复。
    • 检测出来的角点不一定是最优的,这是因为它的效率取决于问题的排序与角点的分布。

    二、OpenCV中API介绍

      1、retval = cv2.FastFeatureDetector_create([, threshold[, nonmaxSuppression])

        API功能:初始化FAST对象,创建一个FAST角点检测器。 cv2.FastFeatureDetector类。

        参数:
          threshold:阈值 t t t(就是上面提到的那个阈值 t t t);默认值为10.
          nonmaxSuppression:是否开启非极大值抑制。默认为Ture。
        返回:
          retval :一个FAST角点检测器

      2、keypoints = cv2.FastFeatureDetector.detect(image)

        API功能:查找角点

        参数:
          image: 需要进行角点检测的图像。
        返回:
          keypoints :输出角点。列表的形式。

      3、outImage = cv2.drawKeypoints( image, keypoints, outImage[, color[, flags]])

        API功能:绘制关键点。

        参数:
          image: 源图像。
          keypoints:(列表)源图像中的关键点。
          color:关键点的颜色。RGB格式,如:(255, 0, 0)
        返回:
          outImage:输出图像。它的内容取决于标志值,该标志值定义了在输出图像中绘制的内容。

    三、代码&效果图

    import numpy as np
    import cv2 as cv
    from matplotlib import pyplot as plt
    
    img = cv.imread('simple.jpg',0)
    # 使用默认值初始化FAST对象
    fast = cv.FastFeatureDetector_create()
    
    # 查找并绘制关键点
    kp = fast.detect(img,None)
    img2 = cv.drawKeypoints(img, kp, None, color=(255,0,0))
    
    # 打印所有默认参数
    print( "Threshold: {}".format(fast.getThreshold()) )
    print( "nonmaxSuppression:{}".format(fast.getNonmaxSuppression()) )
    print( "neighborhood: {}".format(fast.getType()) )
    print( "Total Keypoints with nonmaxSuppression: {}".format(len(kp)) )
    cv.imwrite('fast_true.png',img2)
    
    # 禁用nonmaxSuppression
    fast.setNonmaxSuppression(0)
    kp = fast.detect(img,None)
    print( "Total Keypoints without nonmaxSuppression: {}".format(len(kp)) )
    
    img3 = cv.drawKeypoints(img, kp, None, color=(255,0,0))
    cv.imwrite('fast_false.png',img3)
    
    

      查看结果。第一张图片显示了带有nonmaxSuppression的FAST,第二张图片显示了没有nonmaxSuppression的FAST:
    在这里插入图片描述

    展开全文
  • 作为对此的解决方案,Edward Rosten和Tom Drummond在2006年的论文“用于高速拐角检测的机器学习”中提出了FAST(加速分段测试的特征)算法(后来在2010年对其进行了修订)。该算法的基本内容如下。有关更多详细信息...
  • FAST角点检测方法详解

    千次阅读 2019-02-19 23:09:55
    FAST(Features from Accelerated Segment Test)由Edward Rosten和Tom Drummond在2006年首先提出,是近年来一总倍受关注的基于模板和机器学习的角点检测方法,它不仅计算速度快,还具有较高的精确度。本文将通过其...

    FAST(Features from Accelerated Segment Test)由Edward Rosten和Tom Drummond在2006年首先提出,是近年来一总倍受关注的基于模板和机器学习的角点检测方法,它不仅计算速度快,还具有较高的精确度。本文将通过其2006年的原文,详细介绍FAST的基本原理。

    √ FAST 角点检测是一种的快速角点特征检测算法。
    √ FAST 角点定义为:若某像素点与其周围领域内足够多的像素点处于不同的区域,则该像素点可能为角点,也就是某些属性与众不同。
    √ FAST特征点检测是对兴趣点所在圆周上的16个像素点进行判断,若判断后的当前中心像素点为暗或亮,将决定其是否为角点。

    √ 确定一个阙值t, 观察某像素点为中心的一个半径等于3像素的离散化的圆,这个圆的边界上有16个像素。
    如果在这个大小为16个像素的圆上有n(一般n为12)个连续的像素点,它们的像素值I要么都比IP+t大,要么都比Ip-t小,则p它就是一个角点。


    一、FAST算法原理

    FAST的方法主要是考虑像素点附近的圆形窗口上的16个像素,如下图所示,p为中心像素点,而白框标示的点像素则是我们需要考虑的点。


    最初的检测方法就是检测在这样的圆环上的16个像素点中,如果有n个连续的点都比中心像素p的强度都大,或都小的话,这样的中心点就是角点,实际上比较强度时,需要加上阈值t。


    上图的公式说明了这一过程,一般情况下,n是取12,所以这个标准定义为FAST-12,而实际上当n=9时,往往能取得较好的效果。


    如果要提高检测速度的话,只需要检测四个点就可以了,首先比较第1和第9个像素,如果两个点像素强度都在中心像素强度t变化范围内(及都同中心点相似),则说明这不是角点,如果接下来检测第5和13点时,发现上述四点中至少有三个点同中心点不相似,则可以说明这是个角点。之后为了提高精度,我们还可以对上面运算后的剩下的候选角点进行全部的16点检测,从而确定其是不是角点。

    然后这个方法也有如下的几个缺点:

    (1)如果在首先的四点检测里,只有2个点同中心点不相似,也并不能说明这不是角点。

    (2)检测的效率严重依赖于检测点的顺序和角点附近的分布,很难说明所选择比较的像素位置能最好的反应角点性能。

    (3)前面的四点检测结果没能充分用到后面检测上来。

    (4)并连在一起的特征点很可能检测到了相邻的位置。

    所以,为了解决上述问题,接下来,本文将重点介绍FAST算法最为精髓的地方——通过机器学习来改善速度和通用性。

     

    二、机器学习改善速度及通用性

    通过机器学习的方法,我们可以解决上面提到的前三个问题,而第四个问题可以通过非极大值抑制来解决(之后会介绍)。机器学习方法采用的是决策树方法,通过对像素点进行分类,找到角点附近的16点位置中最能区分这个分类的位置(实际上就指决策树每层的根),而叶则用来指明是否是角点。其主要分为两个部分,首先给定n,对所以的16像素圆环建立FAST-n检测,然后从一组图像内(最好是同目标图像相似)提取大量的角点。

    (1)对于这个16个像素的每个位置x[1,16],将其同中心像素比较,获得三个状态,如下


    选择一个位置x,将所有训练图像中的所以像素点(记为集P)同其该位置点进行上述等式比较,分别计算每点的状态 ,由此以来,对于每个位置x,我们都可以都得到一个状态集,而每个状态就是指一个像素(集P内的每个像素)同其附近(圆环上)该位置像素的状态。

    (2)然后我们选择一个x位置的状态集,可以将集P内的像素点根据其在状态集对应位置上状态,分成三个部分,其意思是指该子集内的像素,其附近圆环x位置的像素同比较,是更暗(d集),相似(s集)或更亮(b)。

    (3)之后再定义一个布尔变量来确定当前像素点p是否是角点。对于任意一个点集Q,我们可以计算总共的熵值:


    对于一个位置x来说,它分类的信息量为:


    (4)接下来,我们就是选择信息量最大的x位置,同时在其下面的子集内继续迭代选择信息量最大的x位置(每个子集内选择x位置可以分别写成xd,xs,xb),然后继续将子集再次分割,如将。每一次分割所选的x都是通将集分类成拥有最大信息量的位置。

    为什么要是最大信息量的位置呢?最大信息量表明分成的子集的信息量最少,也就意味着子集内的点都是具有相同类似的点(即都是角点,或都不是角点),所以最后我们将通过训练集得到一个决策树,其能将像素点较好的区分是否是角点。下图是决策树模型。


    (5)为了更好的优化,我们强制让xd,xs,xb相等,这样的话,我们选择第二个测试的位置点将会一样,只需要两个位置点的比较,我们就能排除绝大多数的点,如此以来将让速度大大提高。

     

    三、非极大值抑制

    因为FAST方法没有计算角响应度,所以我们很难采用常规的方法来直接进行非极大值抑制,对于一个给定的n,如果阈值t增加,那么检测的角点数将会减少,因为角点强度可以被定义为如果这个点可以被检测成角点时,t所能取到的最大值。

    决策树能根据一个给定的t,非常高效的确定一个点是否是角点,由此以来,我们可以通过变化t,来确定找到该点由角点变为非角点时的t值,而这个t值就是让该点检测为角点的最大阈值,这个查找方法可以用二分法的解决。或者,我们也可以用一个迭代的方法。

    找到了角响应度的衡量后,我们就可以应用原来的非极大值抑制方法了,最终得到我们想要的角点。

    总结

    FAST算法比其他已知的角点检测法要快很多倍。
    但是当图片的噪点较多时,它的健壮性并不好。这依靠一个阙值。

    优缺点

    (优) FAST角点检测计算的时间复杂度小,检测效果好,效率高/快速。
    (缺) FAST不产生多尺度特征,也没有方向信息,这样就会失去旋转不变性。

    OpenCV中的FAST特征检测

    和OpenCV中其他特征检测器的调用相同。如果你想,你可以指定一个阙值,或者决定是否使用non-maximal suppression来判断邻近特征点。

    对于相邻特征点,OpenCV定义了三个flags:
    cv2.FAST_FEATURE_DETECTOR_TYPE_5_8
    cv2.FAST_FEATURE_DETECTOR_TYPE_7_12
    cv2.FAST_FEATURE_DETECTOR_TYPE_9_16

    sample:

    import numpy as np
    import cv2
    from matplotlib import pyplot as plt
     
    img = cv2.imread('simple.jpg',0)
     
    # Initiate FAST object with default values
    fast = cv2.FastFeatureDetector()
     
    # find and draw the keypoints
    kp = fast.detect(img,None)
    img2 = cv2.drawKeypoints(img, kp, color=(255,0,0))
     
    # Print all default params
    print "Threshold: ", fast.getInt('threshold')
    print "nonmaxSuppression: ", fast.getBool('nonmaxSuppression')
    print "neighborhood: ", fast.getInt('type')
    print "Total Keypoints with nonmaxSuppression: ", len(kp)
     
    cv2.imwrite('fast_true.png',img2)
     
    # Disable nonmaxSuppression
    fast.setBool('nonmaxSuppression',0)
    kp = fast.detect(img,None)
     
    print "Total Keypoints without nonmaxSuppression: ", len(kp)
     
    img3 = cv2.drawKeypoints(img, kp, color=(255,0,0))
     
    cv2.imwrite('fast_false.png',img3)
    
    
    

    下面是测试结果。左边是使用了nonmaxSuppression的FAST,右边则没有使用。
    在这里插入图片描述

     

    参考文献

    Machine Learning for High-Speed CornerDetection

    展开全文
  • fast角点检测算法matlab代码,只要替换程序中图片路径即可运行
  • FAST角点检测算法

    千次阅读 2017-03-24 22:35:31
    FAST角点检测算法author@Jason http://blog.csdn.net/lql07161、FAST角点检测原理 算法步骤: 1、在图像中任选一点p, 假定其像素(亮度)值为 Ip 2、以3为半径画圆,覆盖p周围的16个像素,如下图所示 3、...

    FAST角点检测算法


    author@Jason_ql(lql0716)
    http://blog.csdn.net/lql0716


    1、FAST角点检测原理

    • 算法步骤:

    1、在图像中任选一点p, 假定其像素(亮度)值为 Ip

    2、以3为半径画圆,覆盖p点周围的16个像素,如下图所示

    3、设定阈值t,如果这周围的16个像素中有连续的n个像素的像素值都小于 Ip−t或者有连续的n个像素都大于Ip+t, 那么这个点就被判断为角点。 在OpenCV的实现中n取值为12(16个像素周长的 3/4).

    4、一种更加快的改进是: 首先检测p点周围的四个点,即1, 5, 9, 12四个点中是否有三个点满足超过Ip+t, 如果不满足,则直接跳过,如果满足,则继续使用前面的算法,全部判断16个点中是否有12个满足条件。

    此处输入图片的描述

    • 以上算法的缺点:很可能大部分检测出来的点彼此之间相邻,我们要去除一部分这样的点。为了解决这一问题,我们采用了非极大值抑制的算法

    • 非极大值抑制
      对一个角点P建立一个3*3(或5*5,7*7)的窗口,如果该窗口内出现了另一个角点Q,则比较P与Q的大小,如果P大,则将Q点删除,如果P小,则将P点删除。

    • FAST 算法特点

    1、在速度上要比其他算法速度快很多

    2、受图像噪声以及设定的阈值影响很大

    3、FAST不产生多尺度特征而且FAST特征点没有方向信息,这样就会失去旋转不变性。

    2、opencv-Fast角点检测算法C++版代码

    • C++代码(opencv2.4.13)
    #include <QCoreApplication>  //该行为Qt环境使用。VS下请注释或删除该行。
    #include <opencv2/opencv.hpp>
    
    using namespace cv;
    using namespace std;
    
    //**********************************************************************************************
    //                                     【fast角点检测算法】
    //**********************************************************************************************
    
    int main()
    {
        string path = "/home/jason/1.jpg";  //图片路径
        cv::Mat img, gray;
    
        img = cv::imread(path);  //读取图片
        cv::cvtColor(img, gray, cv::COLOR_BGR2GRAY);  //转换为灰度图
        std::vector<KeyPoint> kp;  //特征点向量
    
        cv::FastFeatureDetector fast(32);  //FAST特征检测器, 32为阈值,阈值越大,特征点越少
        fast.detect(gray, kp);  //检测fast特征点
    
        cv::drawKeypoints(img, kp, img, cv::Scalar(0, 255, 0), cv::DrawMatchesFlags::DRAW_OVER_OUTIMG);  //画特征点
    
        cv::namedWindow("img", cv::WINDOW_NORMAL);
        cv::imshow("img", img);
        cv::waitKey(0);
    
        cv::imwrite("/home/jason/1.jpg", img);
    
        return 0;
    }
    

    原图:
    这里写图片描述
    效果图:
    这里写图片描述

    3、opencv-Fast角点检测算法python版代码

    • python版代码(opencv2.4.13)
      该代码和C++代码略有不同,且未设置阈值,故角点可能不太一致。
    # -*- coding: utf-8 -*-
    """
    Created on Mon Mar 13 21:06:59 2017
    
    @author: lql0716
    """
    
    import cv2
    
    img = cv2.imread('D:/photo/01.jpg')
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    fast = cv2.FeatureDetector_create('FAST')
    kp = fast.detect(gray, None)
    img2 = cv2.drawKeypoints(img, kp, (0, 0, 255))
    
    cv2.namedWindow('img', cv2.WINDOW_NORMAL)
    cv2.imshow('img', img2)
    cv2.imwrite('D:/photo/01_1.jpg', img2)
    cv2.waitKey(0)
    
    

    原图:
    这里写图片描述
    效果图:
    这里写图片描述

    python调用以下算法时,调用方法同上面FAST的调用方法相同。

    Parameters:

    detectorType – Feature detector type.

    The following detector types are supported:

    “FAST” – FastFeatureDetector

    “STAR” – StarFeatureDetector

    “SIFT” – SIFT (nonfree module)

    “SURF” – SURF (nonfree module)

    “ORB” – ORB

    “BRISK” – BRISK

    “MSER” – MSER

    “GFTT” – GoodFeaturesToTrackDetector

    “HARRIS” – GoodFeaturesToTrackDetector with Harris detector enabled

    “Dense” – DenseFeatureDetector

    “SimpleBlob” – SimpleBlobDetector

    • 相关资料
    展开全文
  • 代码及解析 import numpy as np import cv2 img = cv2.imread("fast_check3.jpg",0) # 读取图片 # Initiate FAST object with default values ...kp = fast.detect(img, None) # 找出图片中的关键 img2 ..
  • fast角点检测C源代码

    热门讨论 2011-04-15 19:14:44
    fast角点检测c实现程序,fast角点检测适合在dsp上实现
  • Opencv中fast角点检测源码分析

    千次阅读 2017-09-17 22:22:04
    FAST是Edward Rosten和Tom Drummond两位大神在《Features From Accelerated Segment Test》提出的一种特征点检测的方法,相对于其他的角点检测方法,该方法以快著称。
  • FAST算法检测角点,代替差分高斯金字塔取极值检测角点的方法,速度块;接着用SIFT特征描述符描述角点,省略尺度空间值,只用原图像中角点邻域的梯度值和方向计算角点主方向,接着计算32个方向向量来描述角点。之...
  • OpenCv学习笔记12--FAST角点检测

    千次阅读 2018-11-23 14:23:48
    此opencv系列博客只是为了记录本人对&lt;&lt;opencv3计算机视觉-pyhton语言实现&...在前面我们已经陆续介绍了许多特征检测算子,我们可以根据图像局部的自相关函数求得Harris角点,后面又提到了两种十分优秀...
  • Fast角点检测算法

    千次阅读 2018-05-08 08:51:17
    1.角点定义 角点是一种局部...2.Fast检测角点1)基本思想 E.Rosten和T.Drummond两位大佬在06年一篇文章中提出了FAST特征算法,基本思想十分简单:以某个像素为圆心,某半径的圆周上其他像素与圆心像素特性差...
  • FAST角点检测和BRIEF描述子提取算法

    千次阅读 2019-01-19 17:58:00
    FAST角点检测 Edward Rosten和Tom Drummond在2006年发表的“Machine learning for high-speed corner detection”,并在2010年稍作修改后发表了《Features From Accelerated Segment Test》,以后简称FAST。 ...
  • Harris角点检测  2. FAST特征检测  3. 尺度不变的SURF特征检测  4.SURF检测描述 一、引言  在计算机视觉中,特征或称兴趣角点(即图像的极值,线段的终点,曲线曲率最大的或水平、竖直...
  • 在前面我们已经陆续介绍了许多特征检测算子,我们可以根据图像局部的自相关函数求得Harris角点,后面又提到了两种十分优秀的特征以及他们的描述方法SIFT特征和SURF特征。SURF特征是为了提高运算效率对SIFT特征的一...
  • fast角点检测算法参考文章《fast角点检测算法》(涵盖fast角点检测原理及C++、python代码,以及效果图) 非极大值抑制,就是对于一个3*3(或5*5,7*7等奇数窗口)的窗口,如果存在多个特征,则删除响应值较小的特征
  • 图像FAST角点检测算法的FPGA实现与系统集成.pdf
  • imshow("FAST特征", image); struct timeval t1,t2; gettimeofday(&t1,NULL); cout; drawKeypoints(image,keypoints,image,cv::Scalar(0,255,0)); gettimeofday(&t2,NULL); cout; cout; imshow("FAST特征...
  • 基于windows10系统的VS2013,CUDA8.0 GTX950平台实现的FAST角点检测程序,很好的学习CUDA的实例
  • 如图所示,P为要检测,我们以P为圆点,做半径为3的bresenham圆。 1、在圆上按顺时针方向从1到16的顺序对像素进行编号。 2、如果,圆周上有N个连续的像素的亮度都比圆点P的亮度加上阈值t还要亮,或者比圆点P...
  •  Oriented FAST and Rotated BRIEF,简称ORB,该特征检测算子是在著名的FAST特征检测和BRIEF特征描述子的基础上提出来的,其运行时间远远优于SIFT和SURF,可应用于实时性特征检测。ORB特征检测具有尺度和旋转不变性...
  • opencv35:FAST角点检测

    2021-12-01 14:09:15
    在之前的文章中,已经了解了几个特征检测器,其中很多表现是非常优秀的。但是,从实时应用程序的角度来看,它们并不够快。最好的例子是计算资源有限的SLAM(同时定位和制图)移动机器人 为了解决这个问题,Edward ...
  • 原文站点:https://senitco.github.io/2017/06/30/image-feature-fast/  前面已经介绍多种图像特征(角点、斑点、极值)的检测算法,包括Harris、LoG、HoG以及SIFT、SURF等,这些方法大多涉及图像局部邻域的梯度...
  • fast角点检测具体实现: 该算法考虑以角p为中心的圆,其边与图像像素相交的像素位置,例如上图边所在的16个像素位置,如果存在一组n个连续的像素其灰度值全部大于p灰度值加上阈值或者全部小于p灰度值减掉...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 13,027
精华内容 5,210
关键字:

fast角点检测