精华内容
下载资源
问答
  • Sift算法的优点是特征稳定,对旋转、尺度变换、亮度保持不变性,对视角变换、噪声也有一定程度的稳定性;缺点是实时性不高,并且对于边缘光滑目标的特征提取能力较弱。 Surf(Speeded Up Robust Features)改进了...

    1.原理:

    Sift算法的优点是特征稳定,对旋转、尺度变换、亮度保持不变性,对视角变换、噪声也有一定程度的稳定性;缺点是实时性不高,并且对于边缘光滑目标的特征点提取能力较弱。
    Surf(Speeded Up Robust Features)改进了特征的提取和描述方式,用一种更为高效的方式完成特征的提取和描述。

    2.Surf实现流程

    2.1 构建Hessian(黑塞矩阵),生成所有的兴趣点,用于特征的提取

    黑塞矩阵(Hessian Matrix)是一个多元函数的二阶偏导数构成的方阵,描述了函数的局部曲率。由德国数学家Ludwin Otto Hessian于19世纪提出。
    surf构造的金字塔图像与sift有很大不同,Sift采用的是DOG图像,而surf采用的是Hessian矩阵行列式近似值图像。
    Hessian矩阵是Surf算法的核心,构建Hessian矩阵的目的是为了生成图像稳定的边缘点(突变点),为下文的特征提取做好基础。
    每一个像素点都可以求出一个Hessian矩阵。
    在这里插入图片描述
    Hessian矩阵的判别式为:
    在这里插入图片描述
    当Hessian矩阵的判别式取得局部极大值时,判定当前点是比周围邻域内其他点更亮或更暗的点,由此来定位关键点的位置。
    在SURF算法中,图像像素l(x,y)即为函数值f(x,y)。但是由于我们的特征点需要具备尺度无关性,所以在进行Hessian矩阵构造前,需要对其进行高斯滤波,选用二阶标准高斯函数作为滤波器。
    在这里插入图片描述
    通过特定核间的卷积计算二阶偏导数。通过特定核间的卷积计算二阶偏导数,这样便能计算出H矩阵的三个矩阵元素L_xx, L_xy, L_yy从而计算出H矩阵:
    在这里插入图片描述
    由于高斯核是服从正态分布的,从中心点往外,系数越来越低,为了提高运算速度,Surf使用了盒式滤波器来近似替代高斯滤波器,提高运算速度。
    盒式滤波器(Boxfilter)对图像的滤波转化成计算图像上不同区域间像素和的加减运算问题,只需要简单几次查找积分图就可以完成。
    每个像素的Hessian矩阵行列式的近似值:
    在这里插入图片描述
    在Dxy上乘了一个加权系数0.9,目的是为了平衡因使用盒式滤波器近似所带来的误差。

    2.2构建尺度空间

    同Sift一样,Surf的尺度空间也是由O组L层组成,不同的是,Sift中下一组图像的尺寸是上一组的一半,同一组间图像尺寸一样,但是所使用的高斯模糊系数逐渐增大;而在Surf中,不同组间图像的尺寸都是一致的,但不同组间使用的盒式滤波器的模板尺寸逐渐增大,同一组间不同层间使用相同尺寸的滤波器,但是滤波器的模糊系数逐渐增大。
    在这里插入图片描述

    2.3特征点定位

    特征点的定位过程Surf和Sift保持一致,将经过Hessian矩阵处理的每个像素点与二维图像空间和尺度空间邻域内的26个点进行比较,初步定位出关键点,再经过滤除能量比较弱的关键点以及错误定位的关键点,筛选出最终的稳定的特征点。
    在这里插入图片描述

    3.4特征点主方向分配

    Sift特征点方向分配是采用在特征点邻域内统计其梯度直方图,而在Surf中,采用的是统计特征点圆形邻域内的harr小波特征。
    在特征点的圆形邻域内,统计60度扇形内所有点的水平、垂直harr小波特征总和,然后扇形以一定间隔进行旋转并再次统计该区域内harr小波特征值之后,最后将值最大的那个扇形的方向作为该特征点的主方向。
    在这里插入图片描述

    3.5生成特征点描述子

    在Sift中,是取特征点周围44个区域块,统计每小块内8个梯度方向,用着4×4×8=128维向量作为Sift特征的描述子。
    Surf算法中,也是在特征点周围取一个4×4的矩形区域块,但是所取得矩形区域方向是沿着特征点的主方向。每个子区域统计25个像素的水平方向和垂直方向的haar小波特征,这里的水平和垂直方向都是相对主方向而言的。该haar小波特征为水平方向值之后、垂直方向值之后、水平方向绝对值之后以及垂直方向绝对值之和4个方向。
    在这里插入图片描述
    把这4个值作为每个子块区域的特征向量,所以一共有4×4×4=64维向量作为Surf特征的描述子,比Sift特征的描述子减少了一半。

    2.6 特征点匹配

    与Sift特征点匹配类似,Surf也是通过计算两个特征点间的欧式距离来确定匹配度,欧氏距离越短,代表两个特征点的匹配度越好。
    不同的是Surf还加入了Hessian矩阵迹的判断,如果两个特征点的矩阵迹正负号相同,代表这两个特征具有相同方向上的对比度变化,如果不同,说明这两个特征点的对比度变化方向是相反的,即使欧氏距离为0,也直接予以排除。

    原文链接

    SURF算法

    参考阅读

    图像特征提取算法:尺度不变特征变换SIFT
    SURF算法详解
    SURF原理与源码解析

    展开全文
  • 针对目前语言识别系统所采用的特征参数没有充分考虑人耳听觉机制,鲁棒性较差的问题,提出一种符合人耳听觉感知特性的鲁棒语言识别参数提取算法。该算法主要从两个方面提高特征参数的鲁棒性:在计算各子带能量时采用...
  • 根据其便利性和便利性,最适用于图像特征点提取和匹配的算法是加速鲁棒特征(SURF)。 尺度不变特征变换(SIFT)算法的增强功​​能提高了算法的有效性,并提高了可能性,同时该算法的应用正在当前的计算机视觉系统...
  • 基于鲁棒高效特征提取和BPNN算法的中文车牌识别方法
  • BRISK特征提取算法

    2020-03-21 14:56:50
    BRISK特征提取算法 简介 BRISK算法是2011年ICCV上《BRISK:Binary Robust Invariant Scalable Keypoints》文章中,提出来的一种特征提取算法,也是一种二进制的特征描述算子。 它具有较好的旋转不变性、尺度不变...

    BRISK特征提取算法

    简介

            BRISK算法是2011年ICCV上《BRISK:Binary Robust Invariant Scalable Keypoints》文章中,提出来的一种特征提取算法,也是一种二进制的特征描述算子。

           它具有较好的旋转不变性、尺度不变性,较好的鲁棒性等。在图像配准应用中,速度比较:SIFT<SURF<BRISK<FREAK<ORB,在对有较大模糊的图像配准时,BRISK算法在其中表现最为出色。

    BRISK算法

    特征点检测

            BRISK算法主要利用FAST9-16进行特征点检测(为什么是主要?因为用到一次FAST5-8),可参见博客:FAST特征点检测算法。要解决尺度不变性,就必须在尺度空间进行特征点检测,于是BRISK算法中构造了图像金字塔进行多尺度表达。

    建立尺度空间

            构造n个octave层(用ci表示)和n个intra-octave层(用di表示),文章中n=4,i={0,1,...,n-1}。假设有图像img,octave层的产生:c0层就是img原图像,c1层是c0层的2倍下采样,c2层是c1层的2倍下采样,以此类推。intra-octave层的产生:d0层是img的1.5倍下采样,d1层是d0层的2倍下采样(即img的2*1.5倍下采样),d2层是d1层的2倍下采样,以此类推。

    则ci、di层与原图像的尺度关系用t表示为:

    ci、di层与原图像大小关系为:

            由于n=4,所以一共可以得到8张图,octave层之间尺度(缩放因子)是2倍关系,intra-octave层之间尺度(缩放因子)也是2倍关系。

    特征点检测

            对这8张图进行FAST9-16角点检测,得到具有角点信息的8张图,对原图像img进行一次FAST5-8角点检测(当做d(-1)层,虚拟层),总共会得到9幅有角点信息的图像。

    非极大值抑制

            对这9幅图像,进行空间上的非极大值抑制(同SIFT算法的非极大值抑制):特征点在位置空间(8邻域点)和尺度空间(上下层2x9个点),共26个邻域点的FAST的得分值要最大,否则不能当做特征点;此时得到的极值点还比较粗糙,需要进一步精确定位。

    亚像素插值

            进过上面步骤,得到了图像特征点的位置和尺度,在极值点所在层及其上下层所对应的位置,对FAST得分值(共3个)进行二维二次函数插值(x、y方向),得到真正意义上的得分极值点及其精确的坐标位置(作为特征点位置);再对尺度方向进行一维插值,得到极值点所对应的尺度(作为特征点尺度)。

    特征点描述

    高斯滤波

           现在,我们得到了特征点的位置和尺度(t)后,要对特征点赋予其描述符。均匀采样模式:以特征点为中心,构建不同半径的同心圆,在每个圆上获取一定数目的等间隔采样点(所有采样点包括特征点,一共N个),由于这种邻域采样模式会引起混叠效应,所以需要对同心圆上的采样点进行高斯滤波。

           采样模式如下图,蓝圈表示;以采样点为中心,为方差进行高斯滤波,滤波半径大小与高斯方差的大小成正比,红圈表示。最终用到的N个采样点是经过高斯平滑后的采样点。下图是t=1时的。(文章中:N=60)

    局部梯度计算

             由于有N个采样点,则采样点两两组合成一对,共有N(N-1)/2钟组合方式,所有组合方式的集合称作采样点对,用集合表示,其中像素分别是,δ表示尺度。用表示特征点局部梯度集合,则有:

    定义短距离点对子集、长距离点对子集(L个):

    其中,,t是特征点所在的尺度。

    现在要利用上面得到的信息,来计算特征点的主方向(注意:此处只用到了长距离子集),如下:

    特征描述符

             要解决旋转不变性,则需要对特征点周围的采样区域进行旋转到主方向,旋转后得到新的采样区域,采样模式同上。BRISK描述子是二进制的特征,由采样点集合可得到N(N-1)/2对采样点对,就可以得到N(N-1)/2个距离的集合(包含长、短距离子集),考虑其中短距离子集中的512个短距离点对,进行二进制编码,判断方式如下:

    其中,带有上标,表示经过旋转a角度后的,新的采样点。由此可得到,512Bit的二进制编码,也就是64个字节(BRISK64)。

    匹配方法

    汉明距离进行比较,与其他二进制描述子的匹配方式一样。

    实验

    opencv代码

    
        #include <cv.h>  
        #include <opencv2/highgui/highgui.hpp>  
        #include <opencv2/core/core.hpp>  
        #include <opencv2/nonfree/features2d.hpp>  
        #include <opencv2/nonfree/nonfree.hpp>  
        #include <Windows.h>  
          
        using namespace cv;  
        using namespace std;  
          
        int main()  
        {  
            //Load Image  
            Mat c_src1 =  imread( "1.png");  
            Mat c_src2 = imread("2.png");  
            Mat src1 = imread( "1.png", CV_LOAD_IMAGE_GRAYSCALE);  
            Mat src2 = imread( "2.png", CV_LOAD_IMAGE_GRAYSCALE);  
            if( !src1.data || !src2.data )  
            {  
                cout<< "Error reading images " << std::endl;  
                return -1;  
            }  
            //feature detect  
            BRISK detector;  
            vector<KeyPoint> kp1, kp2;  
            double start = GetTickCount();  
            detector.detect( src1, kp1 );  
            detector.detect( src2, kp2 );  
            //cv::BRISK extractor;  
            Mat des1,des2;//descriptor  
            detector.compute(src1, kp1, des1);  
            detector.compute(src2, kp2, des2);  
            Mat res1,res2;  
            int drawmode = DrawMatchesFlags::DRAW_RICH_KEYPOINTS;  
            drawKeypoints(c_src1, kp1, res1, Scalar::all(-1), drawmode);//画出特征点  
            drawKeypoints(c_src2, kp2, res2, Scalar::all(-1), drawmode);  
            cout<<"size of description of Img1: "<<kp1.size()<<endl;  
            cout<<"size of description of Img2: "<<kp2.size()<<endl;  
          
            BFMatcher matcher(NORM_HAMMING);  
            vector<DMatch> matches;  
            matcher.match(des1, des2, matches);  
            double end = GetTickCount();  
            cout<<"耗时:"<<(end - start) <<"ms"<<endl;  
            Mat img_match;  
            drawMatches(src1, kp1, src2, kp2, matches, img_match);  
            cout<<"number of matched points: "<<matches.size()<<endl;  
            imshow("matches",img_match);  
            cvWaitKey(0);  
            cvDestroyAllWindows();  
            return 0;  
        }  
    

     

     

    实验结果

    视频地址

    http://v.youku.com/v_show/id_XMTI5MzI3Mzk0OA==.html

    代码分析

    由于代码都很长,只列出了brisk类的两个方法,其余详见:..\opencv\sources\modules\features2d\src\brisk.c

    
        // construct the image pyramids(构造图像金字塔)  
        void  
        BriskScaleSpace::constructPyramid(const cv::Mat& image)  
        {  
          
          // set correct size:  
          pyramid_.clear();  
          
          // fill the pyramid:  
          pyramid_.push_back(BriskLayer(image.clone()));  
          if (layers_ > 1)  
          {  
            pyramid_.push_back(BriskLayer(pyramid_.back(), BriskLayer::CommonParams::TWOTHIRDSAMPLE));//d0层是2/3  
          }  
          const int octaves2 = layers_;  
          
          for (uchar i = 2; i < octaves2; i += 2)  
          {  
            pyramid_.push_back(BriskLayer(pyramid_[i - 2], BriskLayer::CommonParams::HALFSAMPLE));//c?层是前两层的1/2  
            pyramid_.push_back(BriskLayer(pyramid_[i - 1], BriskLayer::CommonParams::HALFSAMPLE));//d?层是前两层的1/2(除d0层外)  
          }  
        }  
    
    
        //提取特征点  
        void  
        BriskScaleSpace::getKeypoints(const int threshold_, std::vector<cv::KeyPoint>& keypoints)  
        {  
          // make sure keypoints is empty  
          keypoints.resize(0);  
          keypoints.reserve(2000);  
          
          // assign thresholds  
          int safeThreshold_ = (int)(threshold_ * safetyFactor_);  
          std::vector<std::vector<cv::KeyPoint> > agastPoints;  
          agastPoints.resize(layers_);  
          
          // go through the octaves and intra layers and calculate fast corner scores:  
          for (int i = 0; i < layers_; i++)  
          {  
            // call OAST16_9 without nms  
            BriskLayer& l = pyramid_[i];  
            l.getAgastPoints(safeThreshold_, agastPoints[i]);  
          }  
          
          if (layers_ == 1)  
          {  
            // just do a simple 2d subpixel refinement...  
            const size_t num = agastPoints[0].size();  
            for (size_t n = 0; n < num; n++)  
            {  
              const cv::Point2f& point = agastPoints.at(0)[n].pt;  
              // first check if it is a maximum:  
              if (!isMax2D(0, (int)point.x, (int)point.y))  
                continue;  
          
              // let's do the subpixel and float scale refinement:  
              BriskLayer& l = pyramid_[0];  
              int s_0_0 = l.getAgastScore(point.x - 1, point.y - 1, 1);  
              int s_1_0 = l.getAgastScore(point.x, point.y - 1, 1);  
              int s_2_0 = l.getAgastScore(point.x + 1, point.y - 1, 1);  
              int s_2_1 = l.getAgastScore(point.x + 1, point.y, 1);  
              int s_1_1 = l.getAgastScore(point.x, point.y, 1);  
              int s_0_1 = l.getAgastScore(point.x - 1, point.y, 1);  
              int s_0_2 = l.getAgastScore(point.x - 1, point.y + 1, 1);  
              int s_1_2 = l.getAgastScore(point.x, point.y + 1, 1);  
              int s_2_2 = l.getAgastScore(point.x + 1, point.y + 1, 1);  
              float delta_x, delta_y;  
              float max = subpixel2D(s_0_0, s_0_1, s_0_2, s_1_0, s_1_1, s_1_2, s_2_0, s_2_1, s_2_2, delta_x, delta_y);  
          
              // store:  
              keypoints.push_back(cv::KeyPoint(float(point.x) + delta_x, float(point.y) + delta_y, basicSize_, -1, max, 0));  
          
            }  
          
            return;  
          }  
          
          float x, y, scale, score;  
          for (int i = 0; i < layers_; i++)  
          {  
            BriskLayer& l = pyramid_[i];  
            const size_t num = agastPoints[i].size();  
            if (i == layers_ - 1)  
            {  
              for (size_t n = 0; n < num; n++)  
              {  
                const cv::Point2f& point = agastPoints.at(i)[n].pt;  
                // consider only 2D maxima...  
                if (!isMax2D(i, (int)point.x, (int)point.y))  
                  continue;  
          
                bool ismax;  
                float dx, dy;  
                getScoreMaxBelow(i, (int)point.x, (int)point.y, l.getAgastScore(point.x, point.y, safeThreshold_), ismax, dx, dy);  
                if (!ismax)  
                  continue;  
          
                // get the patch on this layer:  
                int s_0_0 = l.getAgastScore(point.x - 1, point.y - 1, 1);  
                int s_1_0 = l.getAgastScore(point.x, point.y - 1, 1);  
                int s_2_0 = l.getAgastScore(point.x + 1, point.y - 1, 1);  
                int s_2_1 = l.getAgastScore(point.x + 1, point.y, 1);  
                int s_1_1 = l.getAgastScore(point.x, point.y, 1);  
                int s_0_1 = l.getAgastScore(point.x - 1, point.y, 1);  
                int s_0_2 = l.getAgastScore(point.x - 1, point.y + 1, 1);  
                int s_1_2 = l.getAgastScore(point.x, point.y + 1, 1);  
                int s_2_2 = l.getAgastScore(point.x + 1, point.y + 1, 1);  
                float delta_x, delta_y;  
                float max = subpixel2D(s_0_0, s_0_1, s_0_2, s_1_0, s_1_1, s_1_2, s_2_0, s_2_1, s_2_2, delta_x, delta_y);  
          
                // store:  
                keypoints.push_back(  
                    cv::KeyPoint((float(point.x) + delta_x) * l.scale() + l.offset(),  
                                 (float(point.y) + delta_y) * l.scale() + l.offset(), basicSize_ * l.scale(), -1, max, i));  
              }  
            }  
            else  
            {  
              // not the last layer:  
              for (size_t n = 0; n < num; n++)  
              {  
                const cv::Point2f& point = agastPoints.at(i)[n].pt;  
          
                // first check if it is a maximum:  
                if (!isMax2D(i, (int)point.x, (int)point.y))  
                  continue;  
          
                // let's do the subpixel and float scale refinement:  
                bool ismax=false;  
                score = refine3D(i, (int)point.x, (int)point.y, x, y, scale, ismax);  
                if (!ismax)  
                {  
                  continue;  
                }  
          
                // finally store the detected keypoint:  
                if (score > float(threshold_))  
                {  
                  keypoints.push_back(cv::KeyPoint(x, y, basicSize_ * scale, -1, score, i));  
                }  
              }  
            }  
          }  
        }  
    

     

    参考文献

    1、BRISK:binary robust invariant scalable keypoints,2011,ICCV.

    2、多种角度比较SIFT、SURF、RISK、ORB、FREAK算法[J],2014.

    3、基于颜色不变量的特征匹配算法研究[硕士论文],2014.

    展开全文
  • SURF:Speed Up Robust Features是继SIFT算法后有H Bay提出的一特征提取算法,其灵感来自于SIFT,所以该算法的几个步骤和SIFT算法相似,但其速度是SIFT算法的多倍之多(基于hessian的快速计算方法),下面我们就来...

    SURF:Speed Up Robust Features是继SIFT算法后有H Bay提出的一特征点提取算法,其灵感来自于SIFT,所以该算法的几个步骤和SIFT算法相似,但其速度是SIFT算法的多倍之多(基于hessian的快速计算方法),下面我们就来看看该算法实现的过程:(ps:本文纯属个人理解,如有错误望指正)

    1、初始化图像:将图像转变成32位单精度单通道图像

    2、得到图像积分图:积分图是为下面计算fast-hessian做准备

    3、hessian矩阵计算:采用近似计算,加快计算速度

    4、构建尺度空间:保持图片不变,增大高斯核的尺度

    5、找出关键点:利用hessian矩阵发现关键点,同时关键点还需是临近26个像素中最大或最小值

    6、确定描述因子方向:为了保持特征点的旋转不变性,确定描述因子主方向

    7、计算描述因子:利用harr小波变换计算描述因子


    接下来介绍几个主要知识点:

    1、积分图像:


    X代表点(x,y),即输入图像的原点和点X所组成的矩阵内所有像素的和。将图像所有像素点计算即可


    2、hessian matrix

    点X的hessian matrix 可由下式定义:


    其中Lxx为高斯二阶导数和图像在X点的卷积,Lxy、Lyy 类似

    算法提出一种hessian matrix 的近似求解方法:即box filters

    下图为二阶高斯导数的近似图像:


    左边为二阶高斯导数图像,右边为二阶高斯近似图像

    采用近似方法的好处是,hessian matrix的求解速度可以得到很大的提高,然后采用此方法也会造成结果出现一定的误差,因此我们在计算det(H)时加上一个系数w


    w取0.9,具体是由下面式子计算而来:



    3、构建尺度空间

    为了满足尺度不变性,特征点必须在不同的尺度空间下提取。SIFT采用的是高斯图像金字塔。由于使用了box filters 和积分图像,所以没有必要重复的计算采样层,不需要像SIFT算法那样去直接建立金字塔图像,不同尺度的采样层只需计算一次即可,采用不断增大的盒子滤波模板的尺寸的间接方法。通过不同尺寸盒子滤波模板和积分图像求取Hessian矩阵行列式的响应图像,然后,在响应图像上采用3D非最大值抑制,求取各种不同尺度的斑点。




    与SIFT相类似,SURF也将尺度空间划分成若干组(Octaves)。一个组代表了逐步放大的滤波模板对同一个输入图像进行滤波的一系列响应图像。每一组又有若干固定的层组成

    尺度空间被分成5组(five ostavls),每组4层(four intervals),高斯核的尺度空间如下:

     

    // Oct1: 9,  15, 21, 27
    // Oct2: 15, 27, 39, 51
    // Oct3: 27, 51, 75, 99
    // Oct4: 51, 99, 147,195
    // Oct5: 99, 195,291,387


    4、找出关键点

          为了在目标影像上确定SURF特征点,我们使用了3*3*3的模板在3维尺度空间进行非最大化抑制,根据预设的Hessian阈值H,当h大于H,而且比临近的26个点的响应值都大的点才被选为兴趣点。最后进行插值精确。



    5、特征点主方向确定

          为了保证特征矢量具有旋转不变形,需要对每一个特征点分配一个主要方向。需要以特征点为中心,以6ss为特正点的尺度)为半径的圆形区域内,对图像进行Haar小波响应运算。这样做实际就是对图像进行了梯度运算,但是利用积分图像,可以提高计算图像梯度的效率。为了求取主方向值,需要设计一个以方向为中心,张角为PI/3的扇形滑动窗口,以步长为0.2弧度左右,旋转这个滑动窗口,并对窗口内的图像Haar小波的响应值进行累加。 主方向为最大的Haar响应累加值对应的方向 。


    6、描述因子形成

      生成特征点的特征矢量需要计算图像的Haar小波响应。在一个矩形的区域内,以特征点为中心,沿主方向将20s*20s的图像划分成4*4个子块,每个子块利用尺寸2sHaar小波模板进行响应计算,然后对响应值进行统计形成的特征矢量 



    到此,SURF的描述因子就已经形成,我们就可以利用该描述因子去做我们想做的事情了!





    转载于:https://www.cnblogs.com/Black-Small/p/3258467.html

    展开全文
  • 针对加速鲁棒特征算法用于井下视频拼接时实时性不高的问题,通过降低特征点维度和仅在感兴趣区域提取特征点来改进加速鲁棒特征算法,在此基础上提出了一种井下视频拼接算法。首先,利用改进的加速鲁棒特征算法提取视频...
  • 鲁棒性人脸特征提取

    2012-12-14 22:16:10
    鲁棒人脸特征提取算法做了详细介绍和研究
  • 图像的特征提取可理解为从高维图像空间到低维特征空间的映射,是基于机器视觉的表面缺陷检测的重要一环,其有效性对后续缺陷目标识别精度、计算复杂度、鲁棒性等均有重大影响。特征提取的基本思想是使目标在得到的子...

    图像的特征提取可理解为从高维图像空间到低维特征空间的映射,是基于机器视觉的表面缺陷检测的重要一环,其有效性对后续缺陷目标识别精度、计算复杂度、鲁棒性等均有重大影响。特征提取的基本思想是使目标在得到的子空间中具有较小的类内聚散度和较大的类间聚散度。目前常用的图像特征主要有纹理特征、颜色特征、形状特征等。

    d4f47c84ab32cb14d15639550bad939f.png

    纹理是表达图像的一种重要特征,它不依赖于颜色或亮度而反映图像的同质现象,反映了表面结构组织排列的重要信息以及它们与周围环境的联系。与颜色特征和灰度特征不同,纹理特征不是基于像素点的特征,它需要在包含多个像素点的区域中进行统计计算,即局部性;同时,局部纹理信息也存在不同程度的重复性,即全局性。纹理特征常具有旋转不变性,并且对于噪声有较强的抵抗能力。基于的纹理特征提取方法有统计法、信号分析法、模型法、结构法和几何法。

    统计方法将纹理看用随机现象,从统计学的角度来分析随机变量的分布,从而实现对图像纹理的描述。直方图特征是最简单的统计特征,但它只反映了图像灰度出现的概率,没有反映像素的空间分布信息;灰度共生矩(GLCM)是基于像素的空间分布信息的常用统计方法;局部二值模式(LBP)具有旋转不变性和多尺度性、计算简单;此外,还有行程长度统计法、灰度差分统计法等,因计算量大、效果不突出而限制了其应用。

    130660013bb299e557f3759387db2fc3.png1. 直方图特征

    图像的直方图提供了图像的许多信息和特征,常用的直方图特征有最大值、最小值、均值、中值、值域、熵、方差和熵等。此外,直方图对比统计特征,如L1范数、L2范数、Bhattacharyya距离、Matusita距离、归一化相关系统等,亦常用作统计特征[70]。

    直方图特征方法计算简单、具有平移和旋转不变性、对颜色像素的精确空间分布不敏感等,所以在表面检测、缺陷识别得到不少应用。

    2. 灰度共生矩 

    灰度共生矩是一种广泛应用的使用统计特征来描述纹理的方法。灰度共生矩阵就是从图像灰度级为的像素出发,统计与其距离为、灰度级为的像素同时出现的概率。一般取0°、45°、90°和135°这4个方向。灰度共生矩阵反映了图像灰度关于方向、相邻间隔、变化幅度的综合信息,所以可以作为分析图像基元和排列结构的信息。

    3. 局部二值模式(LBP)

    局部二值模式纹理基元,是一个简单但非常有效的纹理运算符。LBP将各个像素与其附近的像素进行比较,并把结果保存为二进制数,即它用二进制位表达局部邻域点与中心点的关系,所有邻域点的二进制位用来描述局部结构信息的模式。LBP对诸如光照变化等造成的图像灰度变化具有较强的鲁棒性,所以局部二值模式算法已广泛应用于表面缺陷检测,同时,在指纹识别、光学字符识别、人脸识别及车牌识别等领域也有应用。由于LBP计算简单,也可以用于实时检测。

    4. 自相关函数法

    自相关函数法从图像的自相关函数提取纹理特征,即通过对图像的能量谱函数的计算,提取纹理的粗细度及方向性等特征参数。对于规则纹理图像,因其自相关函数具有波峰和波谷,故可用其进行表面检测,但自相关函数法不适用于不规则纹理图像。

    5. 信号处理法

    将图像当作维分布的信号,从而可从信号滤波器设计的角度对纹理进行分析。信号处理方法也称滤波方法,即用某种线性变换、滤波器(组)将纹理转到变换域,然后应用相应的能量准则提取纹理特征。基于信号处理的方法主要有傅里叶变换、Gabor滤波器、小波变换、Laws纹理、LBP纹理等。

    6. 傅里叶变换方法

    傅里叶变换是基于频率的分析方法,傅里叶变换将图像变换到频率域上使用频谱能量或频谱熵等特征来表达纹理。纹理图像在空间分布上具有一定的周期性,其功率谱具有离散性和规律性;对于方向性纹理,方向性会在傅里叶频谱中很好的保持;对于随机性纹理,频谱的响应分布并不限制到某些特定的方向。

    根据相对于频率中心位置距离的频谱分布情况,可以大致判断纹理图像的相对粗糙程度。对于粗糙纹理,其纹理基元尺寸较大,图像的低频信号较多,功率谱的能量主要集中在离频率中心位置较近的低频区域;相反,对于基元尺寸较小的细致纹理,图像含有的高频信息较多,功率谱的能量分布较为分散,主要集中在距离频率中心位置较远的高频区域。但是,傅里叶变换作为一种全局性的变化,仍有一定的局限性,如不具备局部化分析能力、不能分析非平稳信号等。

    7. Gabor滤波方法

    尽管傅里叶变换在信号频域分析中有着重要作用,但它只能对整个时间段的信号的频率进行分析,没有信号的空间局部信息的刻画能力,如当需要对局部的图像纹理细节进行分析时,傅里叶变换无能为力。为克服傅里叶变换不能局部化分析的缺点,短时窗口傅里叶变换(STFT)被提出,它通过在变换时增加一个窗函数来实现,当窗函数是Gaussian函数时,即得到Gabor变换。

    Gabor滤波方法模拟了人类视觉感觉特性,具有很好的频率选择性和方位选择性。使用Gabor滤波器提取纹理特征的主要过程是:先设计滤波器,再从其输出结果中提取特征。滤波器设计包括单个滤波器参数的设计和滤波器组的布局。滤波器的输出结果可作为纹理特征,但维数较高,为此,常采用斯平滑处理、Gabor能量特征、复矩特征、独立成分分析等后处理方法以降低特征集的数据量。对于维数字图像,研究者们提出了Gabor函数形成的Gabor滤波器。

    8. 小波变换方法

    傅里叶变换没有局部分析能力,STFT虽然在一定程度上改善了这种局限性,但采用的的滑动窗函数一经选定就固定不变,故决定了其时频分辨率固定不变,不具备自适应能力,而小波分析很好的解决了这个问题。小波变换通过伸缩和平移等运算功能对函数或信号进行多尺度细化分析,达到高频处时间细分,低频处频率细分,能自动适应时频信号分析的要求,从而可聚焦到信号的任意细节。

    图像纹理往往表现为多尺度特征,对图像进行小波分解后,得到不同分辨率的一系列图像;不同分辨率的图像由代表不同方向信息的一系列高频子带图像构成,高频子带图像反映了图像的纹理特征。

    传统的金字塔小波变换仅对低频部分进行了分解,而纹理图像的高频部分可能也含有重要的特征信息,小波包分解或是树结构小波分解则可克服这一缺点。小波变换方法提取图像特征以进行表面缺陷检测已有大量的应用[95-98]。

    9. Laws纹理 

    Laws模板的纹理描述方法通过使用简单模板处理纹理图像,从而对纹理图像的特征进行描述。它使用一组小的模板对纹理图像卷积,对卷积后的图像的每一个像素的邻域进行统计计算,将统计量作为对应像素的纹理特征。

    展开全文
  • 并且在此博客的基础之上,增加了...一、SURF算法的概述 SURF,英文的全称为Speed Up Robust Features,直译为:加速版的具有鲁棒特性的特征算法,是由Bay在2006年首次提出的。该算法对经典的尺度不变特征变换算法(S...
  • 图像的特征提取可理解为从高维图像空间到低维特征空间的映射,是基于机器视觉的表面缺陷检测的重要一环,其有效性对后续缺陷目标识别精度、计算复杂度、鲁棒性等均有重大影响。特征提取的基本思想是使目标在得到的子...
  • 【特征检测】BRISK特征提取算法

    万次阅读 多人点赞 2015-07-24 22:59:21
    BRISK特征提取算法,具有较好的旋转不变性、尺度不变性,较好的鲁棒性。在图像配准应用中,对有较大模糊的图像时表现最为出色。
  • 【特征检测】FREAK特征提取算法

    万次阅读 2015-07-25 22:44:57
    FREAK算法是2012年CVPR上《FREAK: Fast Retina Keypoint》文章中,提出来的一种特征提取算法,也是一种二进制的特征描述算子,它具有尺度不变性、旋转不变性、对噪声的鲁棒性等优良特性。
  • 以下图像特征算法是计算机视觉入门必须了解的图像特征提取算法: MPEG-7标准中的视觉描述符 颜色和边缘的方向性描述符CEDD 模糊颜色和纹理直方图FCTH 颜色布局描述符Color ...图像特征提取算法:加速鲁棒特征SURF ...
  • 并且在此博客的基础之上,增加了一些新的内容。 ... SURF,英文的全称为Speed Up Robust Features,直译为:加速版的具有鲁棒特性的特征算法,是由Bay在2006年首次提出的。该算法对经典的尺度不变
  • SIFT(Scale Invariant Feature Transformation)特征提取算法是用于提取对尺度、旋转以及光照等鲁棒的图像局部特征并进行描述的经典算法,广泛应用于图像匹配等领域中,其主要步骤有以下几点: 1. 高斯差分尺度...
  • 用于图像拼接的特征提取算法研究 摘要:图像拼接是计算机视觉领域的一个重要分支,也是现在的研究热点。研究了用于图像拼接的特征提取算法,该算法 提取的特征能对旋转、尺度缩放、仿射变换、视角变化、光照变化、...
  • 基于特征提取模型和BPNN的鲁棒车牌检测与字符识别算法
  • 改进的MFCC特征提取与对称ICA算法相结合用于鲁棒语音识别
  • 针对数字水印算法特征区域选取不足以反映图像重要信息,导致鲁棒性减弱的问题,提出一种尺度空间特征区域的强鲁棒性水印算法。通过尺度空间特征点检测提取靠近载体图像重心且互不重叠的特征区域,合成特征区域矩阵...
  • 特征提取算法--Surf

    千次阅读 2016-03-16 20:57:12
    本文参考了 http://blog.csdn.net/a784763307/article/details/17289251 http://blog.csdn.net/yujiflying/article/details/8203511 ...SURF意指 加速的具有鲁棒性的特征
  • 首先通过正规化分谐波叠加算法提取基频,然后采用K-means算法对基频特征进行编码加强其稳定性,最后与水印图像异或生成零水印序列。此外,发生恶意窜改时,对比零水印中的基频信息得到不一致的部分,即可确定恶意...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 593
精华内容 237
关键字:

鲁棒特征提取算法