图像局部显著性—点、块、线

        基于古老的Marr视觉理论,视觉识别和场景重建的基础即第一阶段为局部显著性探测。探测到的主要特征为直觉上可刺激底层视觉的局部显著性——特征点、特征线、特征块。

       SalientDetection 已经好就没有复习过了,DNN在识别领域的超常表现在各个公司得到快速应用,在ML上耗了太多时间,求职时被CV的知识点虐死...


一:点探测总结(SIft、PCA-SIft、Surf、GLOH)


        原文链接(SIFT):http://www.cnblogs.com/cfantaisie/archive/2011/06/14/2080917.html ,文章有修改!为个人意见。

(一)、Sift特征点生成的主要步骤 

  1)尺度空间的生成

   2)、检测尺度空间极值点;

  3)、精确定位极值点;

  4)、为每个关键点指定方向参数;

  5)、关键点描述子的生成。
 
 1.尺度空间:在一个合适的范围内,使用高斯卷积核模拟图像的多尺度化
 
图像局部显著性—点、块、线_第1张图片
        图像局部显著性—点、块、线_第2张图片
              L(x,y,σ), σ= 1.6 a good tradeoff
     
               D(x,y,σ), σ= 1.6 a good tradeoff
         图像局部显著性—点、块、线_第3张图片
      图像局部显著性—点、块、线_第4张图片
              关于尺度空间的理解说明:图中的2是必须的,尺度空间是连续的。

       在 Lowe的论文中 ,  将第0层的初始尺度定为1.6,图片的初始尺度定为0.5. 在检测极值点前对原始
图像的高斯平滑以致图像丢失高频信息,所以 Lowe 建议在建立尺度空间前首先对原始图像长宽扩展一
倍,以保留原始图像信息,增加特征点数量。尺度越大图像越模糊。   
     图像局部显著性—点、块、线_第5张图片
                         next octave 是由 first octave 降采样得到(如2
          
            尺度空间的所有取值,s为每组层数,一般为3~5

2、检测空间极值点
 
图像局部显著性—点、块、线_第6张图片
      同一组中的 相邻尺度(由于k的取值关系,肯定是上下层)之间进行寻找
           图像局部显著性—点、块、线_第7张图片
     在极值比较的过程中,每一组图像的首末两层是无法进行极值比较的, 为了满足尺度
     变化的连续性,我们在每一组图像的顶层继续用高斯模糊生成了 3 幅图像,高斯金字
     塔有每组S+3层图像。DOG金字塔每组有S+2层图像.
 

3、精确定位极值点
图像局部显著性—点、块、线_第8张图片
                                 

       If ratio > (r+1)2/(r), throw it out (SIFT uses r=10)
                 表示DOG金字塔中某一尺度的图像x方向求导两次
       通过拟和三维二次函数以精确确定关键点的位置和尺度(达到亚像素精度)?
 
 
 
 4、主方向的确定
 
图像局部显著性—点、块、线_第9张图片
   直方图中的峰值就是主方向,其他的达到最大值80%的方向可作为辅助方向
       图像局部显著性—点、块、线_第10张图片
   Identify peak and assign orientation and sum of magnitude to key point
  The user may choose a threshold to exclude key points based on their
                             assigned sum of magnitudes.
 
      利用关键点邻域像素的梯度方向分布特性为每个关键点指定方向参数,使算子具备
      旋转不变性。以关键点为中心的邻域窗口内采样,并用直方图统计邻域像素的梯度
      方向。梯度直方图的范围是0~360度,其中每10度一个柱,总共36个柱。随着距
      中心点越远的领域其对直方图的贡献也响应减小.Lowe论文中还提到要使用高斯函
      数对直方图进行平滑,减少突变的影响。
      图像局部显著性—点、块、线_第11张图片
 
                
                                      关键点描述子的生成步骤
       图像局部显著性—点、块、线_第12张图片
     通过对关键点周围图像区域分块,计算块内梯度直方图,生成具有独特性
          的向量,这个向量是该区域图像信息的一种抽象,具有唯一性。

5、特征描述子生成

图像局部显著性—点、块、线_第13张图片
      每一个小格都代表了特征点邻域所在的尺度空间的一个像素 ,箭头方向代表了像素梯
      度方向,箭头长度代表该像素的幅值。然后在4×4的窗口内计算8个方向的梯度方向直
      方图。 绘制每个梯度方向的累加可形成一个种子点。
          图像局部显著性—点、块、线_第14张图片
      每个直方图有8方向的梯度方向,每一个描述符包含一个位于关键点附近的四个直方图
      数组. 这就导致了SIFT的特征向量有128维.(先是一个4×4的来计算出一个直方图,
      每个直方图有8个方向。所以是4×4×8=128维)将这个 向量归一化之后,就进一步
      去除了光照的影响。
 
           图像局部显著性—点、块、线_第15张图片
                   旋转为主方向
   图像局部显著性—点、块、线_第16张图片
     图像局部显著性—点、块、线_第17张图片
     图像局部显著性—点、块、线_第18张图片
     图像局部显著性—点、块、线_第19张图片

       图像局部显著性—点、块、线_第20张图片
              
 
 
(二)、Sift特征总结(概念补充)

什么是局部特征?
  •局部特征从总体上说是图像或在视觉领域中一些有别于其周围的地方
  •局部特征通常是描述一块区域,使其能具有高可区分度
  •局部特征的好坏直接会决定着后面分类、识别是否会得到一个好的结果

  局部特征需具备的特性
  •重复性
  •可区分性
  •准确性
  •数量以及效率
  •不变性

  局部特征提取算法-sift
  •SIFT算法由D.G.Lowe 1999年提出,2004年完善总结。后来Y.Ke将其描述子部分用PCA代替直方图的方式,对其进行改进。
   •SIFT算法是一种提取局部特征的算法,在尺度空间寻找极值点,提取位置,尺度,旋转不变量
  • SIFT特征是图像的局部特征,其对旋转、尺度缩放、亮度变化保持不变性,对视角变化、仿射变换、噪声也保持一定程度的稳定性。
  •独特性好,信息量丰富,适用于在海量特征数据库中进行快速、准确的匹配。
  •多量性,即使少数的几个物体也可以产生大量 SIFT特征向量。
  •可扩展性,可以很方便的与其他形式的特征向量进行联合。

尺度空间理论
  •尺度空间理论目的是模拟图像数据的多尺度特征
  •其基本思想是在视觉信息图像信息处理模型中引入一个被视为尺度的参数, 通过连续变化尺度参数获得不同尺度下的视觉处理信息, 然后综合这些信息以深入地挖掘图像的本质特征。

描述子生成的细节
  •以极值点为中心点,并且以此点所处于的高斯尺度sigma值作为半径因子。对于远离中心点的梯度值降低对其所处区域的直方图的贡献,防止一些突变的影响。
  •每个极值点对其进行三线性插值,这样可以把此极值点的贡献均衡的分到直方图中相邻的柱子上

归一化处理
  •在求出4*4*8的128维特征向量后,此时 SIFT特征向量已经去除了尺度变化、旋转等几何变形因素的影响。而图像的对比度变化相当于每个像素点乘上一个因子,光照变化是每个像素点加上一个值,但这些对图像归一化的梯度没有影响。因此将特征向量的长度归一化,则可以进一步去除光照变化的影响。
  •对于一些非线性的光照变化,SIFT并不具备不变性,但由于这类变化影响的主要是梯度的幅值变化,对梯度的方向影响较小,因此作者通过限制梯度幅值的值来减少这类变化造成的影响。

PCA-SIFT算法

  • PCA-SIFT与标准SIFT 有相同的 亚像素位置 ,尺度 和 主方向。但在第4步 计算描述子的 设计,采用的 主成分分析 的技术。
  •下面介绍一下其特征描述子计算的部分:
    •不用原先的4*4*8的特征描述,而用特征点周围的41×41的像斑计算它的主元,并用 PCA-SIFT将原来的2×39×39(或者XY两个方向)即3042维的向量降成20或X维,以达到更精确的表示方式。
    •它的主要步骤为,对每一个关键点:在关键点周围提取一个41×41的像斑于给定的尺度,旋转到它的主方向 ;计算39×39水平和垂直的梯度,形成一个大小为3042的矢量;用 预先计算好的投影矩阵n×3042与此矢量相乘;这样生成一个 大小为n的PCA-SIFT描述子。


(三)、工程师角度理解SIFT(目的驱动)

1、SIft的主要价值在于:
        缩放不变性:这一点 以来尺度空间理论来解决,使用 高斯滤波 理论上可以解决尺度上的差异。在特征点检测过程中,受到尺度的影响不大;在特征点的描述上,仍然要考虑到尺度对特征向量的影响。
       旋转不变性:通过对关键点指定主方向来实现。在检测到的特征点邻域内,寻找局部的梯度方向,作为主方向即世界坐标轴。图像局部旋转后以世界坐标轴标定,可以重新对齐,即实现旋转不变。
        特征点位置确定:位置确定是Sift特征算法可以改进的地方,并且应对与不同的场景要使用不同的方法,即不是sift特征的特异之处。
        PCA—sift:在超量图像检测的场景下,PCA化并不一定能取得好的效果,也有可能适得其反。


(四)、GLOH特征(梯度位置方向直方图)

2005年MIko等人提出的SIFT的变子,改进为关键点周围的区间划分,由 田字格划分修改为 八象限圆格划分,如下图:

      图像局部显著性—点、块、线_第21张图片

       在很大的一个训练集上训练得到PCA模型,再将 272维直方图映射到一个128维的描述子。在整体的测试中,比SIFT性能有显著的提高。

       GLOH以 建立训练模型的方式对特征描述施加影响,在一般情况下可以学习到特定领域图像的特征流形分布,比SIFT要好很多;对于更为广泛的应用,其性能也会受到预训练影响。

(五)、点-区块检测总结:

       参考链接:特征提取方法 SIFT,PCA-SIFT,GLOH,SURF 对比总结

      总结论文:A comparison of SIFT, PCA-SIFT and SURF 对三种方法给出了性能上的比较,源图片来源于Graffiti datase对原图像进行尺度、旋转、模糊、亮度变化、仿射变换等变化后,再与原图像进行匹配,统计匹配的效果。效果以可重复出现性为评价指标

method

Time

Scale

Rotation

Blur

Illumination

Affine

Sift

common

best

best

common

common

good

PCA-sift

good

good

good

best

good

best

Surf

best

common

common

good

best

good

        由此可见,SIFT在尺度和旋转变换的情况下效果最好,SURF在亮度变化下匹配效果最好,在模糊方面优于SIFT,而尺度和旋转的变化不及SIFT,旋转不变上比SIFT差很多。速度上看,SURFSIFT速度的3倍。

        采用NN作为匹配策略的特征描述子性能测评结果:

图像局部显著性—点、块、线_第22张图片

 



二、线检测--快速几何形状检测

          参考: 【OpenCV入门指南】第七篇 线段检测与圆检测

(一)、边缘检测

       一维显著特征常见表示为边缘。边缘检测的预处理常用 高斯模糊;主要数学运算为计算一阶和二阶导数,寻找梯度和零交叉点,其中梯度计算可用快速卷积码实现;常见的算子有:
              一阶::Roberts Cross算子,Prewitt算子,Sobel算子, Kirsch算子,罗盘算子;
              二阶: Marr-Hildreth,在梯度方向的二阶导数过零点,Canny算子,Laplacian算子。
       图像处理过程使用卷积实现边缘检测:常用的边缘检测模板有Laplacian算子、Roberts算子、Sobel算子、log(Laplacian-Gauss)算子、Kirsch算子和Prewitt算子等。

       常见算子Sobel和Canny比较:Soble边缘检测算法比较简,实际应用中效率比canny边缘检测效率要高,但是边缘不如Canny检测的准确,但是很多实际应用的场合,sobel边缘却是首选,尤其是对效率要求较高,而对细纹理不太关心的时候,也可以作为预检测。


(二):快速几何形状检测

1. 线段检测和圆检测:

     线段检测与圆检测主要运用Hough变换,Hough变换是一种利用图像的全局特征将特定形状的边缘连接起来,形成连续平滑边缘的一种方法。它通过将源图像上的点影射到用于累加的参数空间,实现对已知解析式曲线进行识别。

      在OpenCV编程中,线段检测和圆检测已经封装成函数了,直接使用cvHoughLines2cvHoughCircles即可。
 

Hough线检测函数原型:

CvSeq* cvHoughLines2(
  CvArr* image, //第一个参数表示输入图像,必须为二值图像(黑白图)
  void* line_storage,//第二个参数表示存储容器,和上一篇的轮廓检测一样,可以传入CvMemStorage类型的指针
  int method,//第三个参数表示变换变量,可以取下面的值:
 //CV_HOUGH_STANDARD - 标准 Hough 变换. 每一线段由两浮点数(ρ,θ)表示,其中ρ是线段与原点(0,0)之间的距离,θ线段与 x-轴之间的夹角。
 //CV_HOUGH_PROBABILISTIC - 概率Hough变换(若图像包含一些长的线性分割,效率更高)。返回线段分割而非整个线段。每个分割用起点和终点表示。
 //CV_HOUGH_MULTI_SCALE - 传统 Hough 变换的多尺度变种。线段的编码方式与 CV_HOUGH_STANDARD 的一致。
  double rho,//第四个参数表示与象素相关单位的距离精度。
  double theta,//第五个参数表示弧度测量的角度精度。
  int threshold,//第六个参数表示检测线段的最大条数,如果已经检测这么多条线段,函数返回。
  double param1=0, //第七个参数与第三个参数有关,其意义如下:
  //对传统 Hough 变换,不使用(0); 对概率 Hough 变换,它是最小线段长度.
  对多尺度 Hough 变换,它是距离精度 rho 的分母 (大致的距离精度是 rho 而精确的应该是 rho / param1 ).
double param2=0//第八个参数与第三个参数有关,其意义如下:
  //对传统 Hough 变换,不使用 (0).
  //对概率 Hough 变换,此参数表示在同一线段上进行碎线段连接的最大间隔值(gap), 即当同一线段两碎线段间的间隔小于param2时,将其合二为一。
  //对多尺度 Hough 变换,它是角度精度 theta 的分母 (大致的角度精度是 theta 而精确的角度应该是 theta / param2). 
);

函数实现:

// 图像中的线段检测  
#include <opencv2/opencv.hpp>  
using namespace std;  
#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")  
int main()  
{     
const char *pstrWindowsSrcTitle = "原图(http://blog.csdn.net/MoreWindows)";  
const char *pstrWindowsLineName = "线段检测";  
      
// 从文件中加载原图    
Mat SrcImage = imread("D:/Circle.jpg", CV_LOAD_IMAGE_UNCHANGED);  
// 灰度图  
Mat GrayImage= Mat(Size(SrcImage.rows, SrcImage.cols), CV_8SC1);//CV_32FC1);  
//cvCvtColor(pSrcImage, pGrayImage, CV_BGR2GRAY);  
// 边缘图  
Mat CannyImage= Mat(Size(SrcImage.rows, SrcImage.cols), CV_8SC1);//CV_32FC1);  
cvCanny(pGrayImage, pCannyImage, 30, 90);  //1、使用了Canny检测的方法!!!
//cvSmooth(pCannyImage, pCannyImage);  

//线段检测(只能针对二值图像)  //以下代码待修改!!!!
CvMemStorage *pcvMStorage = cvCreateMemStorage();  
double fRho = 1;  
double fTheta = CV_PI / 180;  
int nMaxLineNumber = 50;   //最多检测条直线  
double fMinLineLen = 50;   //最小线段长度  
double fMinLineGap = 10;   //最小线段间隔  
CvSeq *pcvSeqLines = cvHoughLines2(pCannyImage, pcvMStorage, CV_HOUGH_PROBABILISTIC, fRho, fTheta, nMaxLineNumber, fMinLineLen, fMinLineGap);  
          
// 绘制线段  
        IplImage *pColorImage = cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 3);  
        cvCvtColor(pCannyImage, pColorImage, CV_GRAY2BGR);   
        for(int i = 0; i < pcvSeqLines->total; i++)   {  
            CvPoint* line = (CvPoint*)cvGetSeqElem(pcvSeqLines, i);  
            cvLine(pColorImage, line[0], line[1], CV_RGB(255,0,0), 2);  
        }  
      
        cvNamedWindow(pstrWindowsSrcTitle, CV_WINDOW_AUTOSIZE);  
        cvShowImage(pstrWindowsSrcTitle, pSrcImage);  
        cvNamedWindow(pstrWindowsLineName, CV_WINDOW_AUTOSIZE);  
        cvShowImage(pstrWindowsLineName, pColorImage);  
      
        
      
        cvReleaseMemStorage(&pcvMStorage);  
        cvDestroyWindow(pstrWindowsSrcTitle);  
        cvDestroyWindow(pstrWindowsLineName);  
        //cvReleaseImage(&pSrcImage);  
        //cvReleaseImage(&pGrayImage);  
        //cvReleaseImage(&pCannyImage);  
        //cvReleaseImage(&pColorImage);  
    cvWaitKey(0);  
    return 0;  
}  

引用原结果:

         图像局部显著性—点、块、线_第23张图片


Hough圆检测的代码:

#include <opencv2/opencv.hpp>  
using namespace std;  
#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")  
int main()  
{     
    const char *pstrWindowsSrcTitle = "原图(http://blog.csdn.net/MoreWindows)";  
    const char *pstrWindowsLineName = "圆检测";  
  
    // 从文件中加载原图  
    IplImage *pSrcImage = cvLoadImage("201.jpg", CV_LOAD_IMAGE_UNCHANGED);  
    // 灰度图  
    IplImage *pGrayImage =  cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 1);  
    cvCvtColor(pSrcImage, pGrayImage, CV_BGR2GRAY);  
    //cvSmooth(pGrayImage, pGrayImage);  
  
    // 圆检测(灰度图)  
    CvMemStorage *pcvMStorage = cvCreateMemStorage();  
    double fMinCircleGap = pGrayImage->height / 10;  
    CvSeq *pcvSeqCircles = cvHoughCircles(pGrayImage, pcvMStorage, CV_HOUGH_GRADIENT, 1, fMinCircleGap);  
    //每个圆由三个浮点数表示:圆心坐标(x,y)和半径  
  
    // 绘制直线  
    IplImage *pColorImage = cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 3);  
    cvCvtColor(pGrayImage, pColorImage, CV_GRAY2BGR);  
    int i;  
    for (i = 0; i < pcvSeqCircles->total; i++)  {  
        float* p = (float*)cvGetSeqElem(pcvSeqCircles, i);  
        cvCircle(pColorImage, cvPoint(cvRound(p[0]), cvRound(p[1])), cvRound(p[2]), CV_RGB(255, 0, 0), 2);  
    }  
  
    cvNamedWindow(pstrWindowsSrcTitle, CV_WINDOW_AUTOSIZE);  
    cvShowImage(pstrWindowsSrcTitle, pSrcImage);  
    cvNamedWindow(pstrWindowsLineName, CV_WINDOW_AUTOSIZE);  
    cvShowImage(pstrWindowsLineName, pColorImage);  
  
    cvWaitKey(0);  
  
    cvReleaseMemStorage(&pcvMStorage);  
    cvDestroyWindow(pstrWindowsSrcTitle);  
    cvDestroyWindow(pstrWindowsLineName);  
    cvReleaseImage(&pSrcImage);  
    cvReleaseImage(&pGrayImage);  
    cvReleaseImage(&pColorImage);  
    return 0;  
}

快速检测矩形的题目可以借鉴上述OpenCV原型里面的算法.....


基本应用:矩形检测
待完成.....
han and zhu (2005)提出使用潜在的匹配矩形形状和嵌套结构(矩形和消失点之间)的语法来推导 矩形框 最有可能的对应线段...
计算机视觉:算法与应用 p196-p197


你可能感兴趣的:(图像局部显著性—点、块、线)