SIFT特征(三)
来源:互联网 发布:vj软件resolume 编辑:程序博客网 时间:2024/05/20 16:37
上一章节中,我们探讨了如何检测尺度空间上的极值点,以及如何排除掉不稳定的极值点。为了使得SIFT具有旋转不变性,我们需要利用关键点的邻域信息为每一个关键点分配一个方向,使得其具有局部结构的稳定方向。
5.关键点方向赋值
5.1 梯度方向及幅值的计算
对于DoG金字塔中检测出的稳定关键点,取关键点邻域
5.2 计算梯度直方图
上一步中计算了邻域内各个像素点的梯度大小和方向,接下来使用直方图对这些邻域像素点的方向和大小进行统计。直方图按照0-360度的方向范围划分为36个柱(bins),即每个柱的度数范围为10度。依次遍历邻域内每个像素点,按照像素点梯度方向找到该像素点所对应的柱的编号,并将像素点的梯度大小与权重的乘积累加到所对应的直方图柱中,这里的权重是指采用了参数为
上图右侧图示意将关键点邻域像素点根据其梯度方向和大小统计后的直方图。我们可以看出,在统计直方图中,会存在一个峰值方向,那么我们将这个峰值方向代表该关键点的主方向。为了增强匹配的鲁棒性,另外保留了直方图柱大于主方向峰值大小80%的方向,作为关键点的辅方向。在这种情况下,在相同的位置和尺度将会有多个关键点被创建但方向不同,其方向分别表示主方向与各个辅方向。如下图表示关键点检测示意图。
5.3 C++源码解读
/*计算关键点邻域的梯度直方图* pt:关键点xy坐标*radius: 3*1.5* scale,邻域窗口半径* sigma:1.5*scale,高斯函数sigma值*hist: 梯度方向直方图* n: 直方图bin数量*/static float calcOrientationHist( const Mat& img, Point pt, int radius, float sigma, float* hist, int n ){ int i, j, k, len = (radius*2+1)*(radius*2+1); float expf_scale = -1.f/(2.f * sigma * sigma); AutoBuffer<float> buf(len*4 + n+4); float *X = buf, *Y = X + len, *Mag = X, *Ori = Y + len, *W = Ori + len; float* temphist = W + len + 2; for( i = 0; i < n; i++ ) temphist[i] = 0.f; //遍历邻域内所有像素点统计直方图 for( i = -radius, k = 0; i <= radius; i++ ) { int y = pt.y + i; if( y <= 0 || y >= img.rows - 1 ) continue; for( j = -radius; j <= radius; j++ ) { int x = pt.x + j; if( x <= 0 || x >= img.cols - 1 ) continue; //计算当前像素点xy方向的梯度 float dx = (float)(img.at<sift_wt>(y, x+1) - img.at<sift_wt>(y, x-1)); float dy = (float)(img.at<sift_wt>(y-1, x) - img.at<sift_wt>(y+1, x)); //X存储x方向梯度大小;Y存储y方向梯度大小;W存放像素点权重 X[k] = dx; Y[k] = dy; W[k] = (i*i + j*j)*expf_scale; k++; } } //直方图统计总的像素点个数 len = k; // 计算邻域内像素点的梯度大小(magnitude)、方向(fastAtan2)和权值(exp) //计算矩阵元素W的自然e的W次幂。i.e. W=exp(W)。值为:exp((i^2+j^2)/2*sigma^2),距离关键点越远,权重越小 exp(W, W, len); //计算梯度方向,存放在Ori中 fastAtan2(Y, X, Ori, len, true); //计算梯度幅值,存放在Mag中。i.e. mag(I) = \sqrt(X^2+Y^2), X和Y 是xy方向的梯度大小,可以根据sobel等算法计算而来 magnitude(X, Y, Mag, len); //计算每个像素点所在bin的ID,并将值梯度大小*权重放在所对应的bin中 for( k = 0; k < len; k++ ) { int bin = cvRound((n/360.f)*Ori[k]); if( bin >= n ) bin -= n; if( bin < 0 ) bin += n; temphist[bin] += W[k]*Mag[k]; } // 平滑直方图(取距离为3的直方图柱插值) temphist[-1] = temphist[n-1]; temphist[-2] = temphist[n-2]; temphist[n] = temphist[0]; temphist[n+1] = temphist[1]; for( i = 0; i < n; i++ ) { hist[i] = (temphist[i-2] + temphist[i+2])*(1.f/16.f) + (temphist[i-1] + temphist[i+1])*(4.f/16.f) + temphist[i]*(6.f/16.f); } //计算关键点的主方向 float maxval = hist[0]; for( i = 1; i < n; i++ ) maxval = std::max(maxval, hist[i]); return maxval;}
1 0
- SIFT特征(三)
- SIFT解析(三)生成特征描述子
- SIFT解析(三)生成特征描述子
- SIFT特征(一)
- SIFT特征(二)
- SIFT特征(五)
- OpenCV SIFT特征学习 (三) 特征如何更好的匹配(上)
- 局部特征(2)--SIFT特征
- sift特征
- SIFT特征
- SIFT特征
- SIFT特征
- SIFT特征
- Sift特征
- sift特征
- SIFT特征
- SIFT特征
- SIFT特征
- python3 threading thread 模块学习
- [IOS]对视频、音频播放器添加缓冲进度条
- C#语法——const vs readonly
- Image图片的相关工具类
- leetcode 27. Remove Element
- SIFT特征(三)
- Android HeaderAndFooterRecyclerView、ExRecyclerView、PullRefreshLoadRecyclerView、PowerfulRecyclerView
- app store上传图片显示错误:未能创建 屏幕快照
- 加载数据之前的加载等待中效果
- 切换fragment回来的时候如果有类似viewpager的控件,会自动的被隐藏了,自动滑动了最上方的问题解决
- 总结项目中不支持emoji表情的问题的解决方法
- C/C++中const关键字详解
- java中枚举的使用
- 国内最火的五款HTML5前端开发框架