赞
踩
1.SIFT
特点
图像的局部特征,对旋转、尺度缩放、亮度变化保持不变,对视角变化、仿射变换、噪声也保持一定程度的稳定性。
可以解决的问题
目标的自身状态、场景所处的环境和成像器材的成像特性等因素影响图像配准/目标识别跟踪的性能,SIFT算法在一定程度上可以解决:
2.SURF
在积分图像上使用了高斯滤波器对二阶微分模板进行了简化,从而构建了Hessian矩阵元素值,进而缩短了特征提取的时间,提高了效率。
主要特点是快速性,同时也具有尺度不变的特性,对光照变化和仿射、透视变化也具有较强的鲁棒性(系统在其特性或参数发生摄动时仍可使品质指标保持不变的性能)
- static void fastHessianDetector(const Mat& sum, const Mat& msum, vector<KeyPoint>& keypoints,
- int nOctaves, int nOctaveLayers, float hessianThreshold)
- {
- /*first Octave图像采样的步长,第二组的时候加倍,以此内推
- 增加这个值,将会加快特征点检测的速度,但是会让特征点的提取变得不稳定*/
- const int SAMPLE_STEP0 = 1;
-
- int nTotalLayers = (nOctaveLayers + 2)*nOctaves; // 尺度空间的总图像数
- int nMiddleLayers = nOctaveLayers*nOctaves; // 用于检测特征点的层的 总数,也就是中间层的总数
-
- vector<Mat> dets(nTotalLayers); // 每一层图像 对应的 Hessian行列式的值
- vector<Mat> traces(nTotalLayers); // 每一层图像 对应的 Hessian矩阵的迹的值
- vector<int> sizes(nTotalLayers); // 每一层用的 Harr模板的大小
- vector<int> sampleSteps(nTotalLayers); // 每一层用的采样步长
- vector<int> middleIndices(nMiddleLayers); // 中间层的索引值
-
- keypoints.clear();
-
- // 为上面的对象分配空间,并赋予合适的值
- int index = 0, middleIndex = 0, step = SAMPLE_STEP0;
-
- for (int octave = 0; octave < nOctaves; octave++)
- {
- for (int layer = 0; layer < nOctaveLayers + 2; layer++)
- {
- /*这里sum.rows - 1是因为 sum是积分图,它的大小是原图像大小加1*/
- dets[index].create((sum.rows - 1) / step, (sum.cols - 1) / step, CV_32F); // 这里面有除以遍历图像用的步长
- traces[index].create((sum.rows - 1) / step, (sum.cols - 1) / step, CV_32F);
- sizes[index] = (SURF_HAAR_SIZE0 + SURF_HAAR_SIZE_INC*layer) << octave;
- sampleSteps[index] = step;
-
- if (0 < layer && layer <= nOctaveLayers)
- middleIndices[middleIndex++] = index;
- index++;
- }
- step *= 2;
- }
- // Calculate hessian determinant and trace samples in each layer
- for (int i = 0; i < nTotalLayers; i++)
- {
- calcLayerDetAndTrace(sum, sizes[i], sampleSteps[i], dets[i], traces[i]);
- }
-
- // Find maxima in the determinant of the hessian
- for (int i = 0; i < nMiddleLayers; i++)
- {
- int layer = middleIndices[i];
- int octave = i / nOctaveLayers;
- findMaximaInLayer(sum, msum, dets, traces, sizes, keypoints, octave, layer, hessianThreshold, sampleSteps[layer]);
- }
-
- std::sort(keypoints.begin(), keypoints.end(), KeypointGreater());
- }
3.ORB
使用FAST进行特征点检测,然后用BREIF进行特征点的特征描述,但是BRIEF并没有特征点方向的概念,所以ORB在BRIEF基础上引入了方向的计算方法,并在点对的挑选上使用贪婪搜索算法,挑出了一些区分性强的点对用来描述二进制串。
对于SIFT SURF ORB
4.LoG
因为拉普拉斯算子对噪声很敏感,所以首先利用高斯对图像进行降噪处理,再采用拉普拉斯算子进行边缘检测,就可以提高对噪声和离散点的鲁棒性
即利用二阶高斯导数(也叫拉普拉斯变换)与原始信号(图像)卷积,通过检测局部极值获得角点。
特别适用于以突出图像中的孤立点、孤立线或线端点为目的的场合
LoG的斑点检测(类似SIFT):
1.预定义一组方差值(因为不知道待检信号的尺度),对每个方差生成一个二阶高斯模板(待完善)
2.对每个方差,将对应的高斯模板与原始信号做卷积(DOH需要将三个模板分别与原始图做卷积,然后计算其加权行列式),得到一组不同尺度的图像集
3.对每个空间位置,比较其在图像集里26(3*3*3-1)个位置(图1-4)的值,如果为极值,则认为在该点有一个斑点(高斯金字塔极值检测)
- Mat Feat::getHOGKernel(Size& ksize, double sigma)
- {
- Mat kernel(ksize, CV_64F);
- Point centPoint = Point((ksize.width -1)/2, ((ksize.height -1)/2));
- // first calculate Gaussian
- for (int i=0; i < kernel.rows; i++)
- {
- double* pData = kernel.ptr<double>(i);
- for (int j = 0; j < kernel.cols; j++)
- {
- double param = -((i - centPoint.y) * (i - centPoint.y) + (j - centPoint.x) * (j - centPoint.x)) / (2*sigma*sigma);
- pData[j] = exp(param);
- }
- }
- double maxValue;
- minMaxLoc(kernel, NULL, &maxValue);
- for (int i=0; i < kernel.rows; i++)
- {
- double* pData = kernel.ptr<double>(i);
- for (int j = 0; j < kernel.cols; j++)
- {
- if (pData[j] < EPS* maxValue)
- {
- pData[j] = 0;
- }
- }
- }
-
- double sumKernel = sum(kernel)[0];
- if (sumKernel != 0)
- {
- kernel = kernel / sumKernel;
- }
- // now calculate Laplacian
- for (int i=0; i < kernel.rows; i++)
- {
- double* pData = kernel.ptr<double>(i);
- for (int j = 0; j < kernel.cols; j++)
- {
- double addition = ((i - centPoint.y) * (i - centPoint.y) + (j - centPoint.x) * (j - centPoint.x) - 2*sigma*sigma)/(sigma*sigma*sigma*sigma);
- pData[j] *= addition;
- }
- }
- // make the filter sum to zero
- sumKernel = sum(kernel)[0];
- kernel -= (sumKernel/(ksize.width * ksize.height));
-
- return kernel;
- }
5.DoH Determinant of Hessian
基本思路和LoG差不多,只不过使用了Hessian矩阵
一张图计算xx,yy,xy三个方向的卷积,然后计算其加权行列式:
理论上,与LOG相比,DOH对细长结构的斑点有较好的抑制作用。
利用像素点Hessian矩阵(二阶微分)及其行列式值
无论是LoG还是DoH,它们对图像中的斑点进行检测,其步骤都可以分为以下两步:
1)使用不同的σ生成(∂2g∂x2+∂2g∂y2)(∂2g∂x2+∂2g∂y2)或∂2g∂x2,∂2g∂y2,∂2g∂x∂y∂2g∂x2,∂2g∂y2,∂2g∂x∂y模板,并对图像进行卷积运算;
2)在图像的位置空间与尺度空间中搜索LoG与DoH响应的峰值。
6.DoG
高斯差分法,SIFT的第一步。通过将目标图像与高斯函数进行卷积运算得到一幅目标图像的低通滤波结果
LoG比DoG明显需要更多的加法运算和乘法运算。虽然DoG需要在每层金字塔多做一次高斯操作,但通过减法取代LoG核的计算过程,显著减少了运算次数,大大节省了运算时间。
通过数学公式可以发现(待补充):可以用DoG 算子来近似 LoG算子
7.Harris
基于图像灰度的一阶导数矩阵检测方法。检测器的主要思想是局部自相似性/自相关性,即在某个局部窗口内图像块与在各个方向微小移动后的窗口内图像块的相似性。
Harris 算子的优越性有:
Harris 算子的局限性有:
8.FAST
基于加速分割测试的FAST算法可以快速地提取出角点特征。
上述算法效率很高,但是缺点如下所示:
前3个问题可以通过机器学习的方法解决(待完善),最后一个问题可以使用非最大值抑制的方法解决。
非极大值抑制,如下所示:
总体来说,FAST算子比其它角点检测算法都快,但是当图像中的噪点较多时,它的健壮性并不好,而且算法的效果还依赖于阈值。并且FAST算子不产生多尺度特征而且FAST角点没有方向信息,这样就会失去旋转不变性。
9.BRIEF
BRIEF是对已检测到的特征点进行描述,它是一种二进制编码的描述子,摈弃了利用区域灰度直方图描述特征点的传统方法,大大的加快了特征描述符建立的速度,同时也极大的降低了特征匹配的时间,是一种非常快速,很有潜力的算法。
BRIEF仅仅是特征描述子,所以事先要得到特征点的位置,可以利用FAST特征点检测算法或Harris角点检测算法或SIFT、SURF等算法检测特征点的位置。接下来在特征点邻域利用BRIEF算法建立特征描述符。
特征点周围邻域内选取若干个像素点对,通过对这些点对的灰度值比较,将比较的结果组合成一个二进制串字符串用来描述特征点。最后,使用汉明距离来计算在特征描述子是否匹配。
算法步骤如下:
1、为减少噪声干扰,先对图像进行高斯滤波(方差为2,高斯窗口为9x9)。
2、以特征点为中心,取SxS的邻域窗口。在窗口内随机选取一对(两个)点,比较二者像素的大小,进行如下二进制赋值。
其中,p(x),p(y)分别是随机点x=(u1,v1),y=(u2,v2)的像素值。
3、在窗口中随机选取N对随机点,重复步骤2的二进制赋值,形成一个二进制编码,这个编码就是对特征点的描述,即特征描述子。(一般N=256)
关于一对随机点的选择方法,原作者测试了以下5种方法,其中方法(2)比较好。
10.BRISK
具有较好的旋转不变性、尺度不变性,较好的鲁棒性等。在图像配准应用中,速度比较:SIFT<SURF<BRISK<FREAK<ORB,在对有较大模糊的图像配准时,BRISK算法在其中表现最为出色。
BRISK算法主要利用FAST9-16进行特征点检测(为什么是主要?因为用到一次FAST5-8)。要解决尺度不变性,就必须在尺度空间进行特征点检测,于是BRISK算法中构造了图像金字塔进行多尺度表达。
步骤:
特征点检测
特征点描述
11.FREAK Fast Retina Keypoint(待完善)
可以看出来该算法的一个特点是快速,另外一个特点就是该算法是被人眼识别物体的原理上得到启发提出的。
BRIEF、ORB和BRISK都是特征点周围的邻域像素点对之间的比较形成的二进制串作为特征点的描述符,这种做法有着快速和占用内存低的优点,在如今的移动计算中有很大的优势,但是也遗留了一些问题。比如,如何确定特征点邻域中哪些像素点对进行比较,如何匹配它们呢?
特征点检测方法与BRISK中特征点检测方法相同
上图中每一个黑点代表一个采样点,每个圆圈代表一块感受野,具体在处理时时对该部分图像进行高斯模糊处理,以降低噪声的影响,而且每个圆圈的半径表示了高斯模糊的标准差。这种采样模式与BRISK算法的不同之处在于,每个感受野与感受野之间有重叠的部分。与ORB和BRIEF算法的不同之处在于,ORB和BRIEF算法中的高斯模糊半径都是相同的,而这里采用了这种不同大小的高斯模糊的核函数。作者提出,正是这些不同之处,导致最后的结果更加优秀。通过重叠的感受野,可以获得更多的信息,这些信息可以使最终的描述符更具有独特性。而不同大小的感受野在人体的视网膜中也有这样类似的结构。
最终FREAK算法的采样结构为6、6、6、6、6、6、6、1,这里的6代表每层中有6个采样点并且这6个采样点在一个同心圆中,一共有7个同心圆,最后的1代表的是特征点。
根据视网膜原理进行点对采样,中间密集一些,离中心越远越稀疏。并且由粗到精构建描述子,穷举贪婪搜索找相关性小的。
Canny、Sobel、Prewitt、LoG、Roberts
比Sobel、Prewitt等算子,Canny算法更为优异。Sobel、Prewitt等算子有如下缺点:
而Canny算法基于这两点做了改进,提出了:
Robert算子定位比较精确,但由于不包括平滑,所以对于噪声比较敏感。Prewitt算子和Sobel算子都是一阶的微分算子,而前者是平均滤波,后者是加权平均滤波且检测的图像边缘可能大于2个像素。这两者对灰度渐变低噪声的图像有较好的检测效果,但是对于混合多复杂噪声的图像,处理效果就不理想了。LOG滤波器方法通过检测二阶导数过零点来判断边缘点。LOG滤波器中的a正比于低通滤波器的宽度,a越大,平滑作用越显著,去除噪声越好,但图像的细节也损失越大,边缘精度也就越低。所以在边缘定位精度和消除噪声级间存在着矛盾,应该根据具体问题对噪声水平和边缘点定位精度要求适当选取。
讨论和比较了几种常用的边缘检测算子。梯度算子计算简单,但精度不高,只能检测出图像大致的轮廓,而对于比较细的边缘可能会忽略。Prewitt 和Sobel 算子比Roberts 效果要好一些。LOG 滤波器和Canny 算子的检测效果优于梯度算子,能够检测出图像较细的边缘部分。不同的系统,针对不同的环境条件和要求,选择合适的算子来对图像进行边缘检测。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。