1.什么是数据归一化?
归一化是一种无量纲处理手段,使物理系统数值的绝对值变成某种相对值关系。简化计算,缩小量值的有效办法。
2.数据归一化的必要性
在RANSAC算法中,计算2D homography过程中,需要依赖图像的坐标系,那么图像的相似变换T就不能够保证不变性,归一化的方法能够消除坐标系的影响
3.数据归一化的好处
RANSAC中:能够保证即便是不同坐标系的两幅图像也能够有着相同的平均梯度
4.数据归一化如何实现?
1)原理:
①将点转换到重心,使得重心作为起点;
②将点进行尺度变换,使得点到重心的距离为原来的根号2
2)实现:
①RANSAC算法中的实现:
本文中的RANSAC算法的实现来自于http://download.youkuaiyun.com/detail/beigua321/2843908
如果您有需要可以从此地址下载。
- //
- // function : DataNormalization
- // usage : DataNormalization(numOfx, x, T);
- // ------------------------------------------------------
- // This function normalizes x and returns the similarity
- // transform, T.
- // The centroid of x will be transformed into (0,0).
- // The average distance of normalized x will be sqrt(2).根号2
- // 数据归一化
- void DataNormalization(int numOfPositions, float positions[][2], CvMat *T)
- {
- int i;
- float sumI = 0, sumJ = 0, meanI = 0, meanJ = 0;
- float squareDist = 0, sumDist = 0, meanDist = 0;
- float scale = 0;
- float x, y, xx, yy, ww;
- // calculate the centroid
- //计算重心
- for(i = 0; i < numOfPositions; i++){
- sumI += positions[i][0];
- sumJ += positions[i][1];
- }
- meanI = sumI / numOfPositions;//重心点y坐标
- meanJ = sumJ / numOfPositions;//重心点x坐标
- // calculate the mean distance
- //计算平均距离
- //通过对每一个点到重心的距离求和然后求出平均距离
- for(i = 0; i < numOfPositions; i++){
- squareDist = pow(positions[i][0] - meanI, 2)
- + pow(positions[i][1] - meanJ, 2);
- sumDist += pow((double)squareDist, 0.5);
- }
- meanDist = sumDist / numOfPositions;
- // set the similarity transform
- //计算相似变换,1/平均距离=尺度
- scale = pow(1, 0.5) / meanDist;
- float t[9] = {scale, 0, -scale * meanI,
- 0, scale, -scale * meanJ,
- 0, 0, 1};
- Array2CvMat(t, T, 3, 3);
- // data normalization
- //数据归一化,通过计算
- for(i = 0; i < numOfPositions; i++){
- x = positions[i][0];
- y = positions[i][1];
- xx = t[0] * x + t[1] * y + t[2];
- yy = t[3] * x + t[4] * y + t[5];
- ww = t[6] * x + t[7] * y + t[8];
- xx = xx / ww;
- yy = yy / ww;
- positions[i][0] = xx;
- positions[i][1] = yy;
- }
- }
上述代码中,在计算相似变换时,实际的实现并没有使得点到重心的距离为原来的根号2,而是为1,我不知道是为什么另外,在数据归一化计算的时候,其计算步骤也不是很明白,在参看了Rob Hess实现SIFT算法中的归一化特征描述子部分也发现了同样的问题,即,实际的实现并没有使得点到重心的距离为原来的根号2,而是为1
②SIFT算法中特征描述子的归一化
- /*
- 归一化特征的描述子
- Normalizes a feature's descriptor vector to unitl length
- @param feat feature
- */
- static void normalize_descr( struct feature* feat )
- {
- double cur, len_inv, len_sq = 0.0;
- int i, d = feat->d;//为描述子长度128维
- //如何进行归一化特征描述子来降低对光照的影响
- //主要就是将每一个特征的平方求和,然后开方,然后去其倒数,然后乘以每一个特征描述子的梯度值,这样就得到了归一化的特征描述子
- for( i = 0; i < d; i++ )
- {
- cur = feat->descr[i];
- len_sq += cur*cur;
- }
- //尺度
- len_inv = 1.0 / sqrt( len_sq );
- //将每一个描述子乘以尺度即可归一化
- for( i = 0; i < d; i++ )
- feat->descr[i] *= len_inv;
- }
上述代码中的尺度计算和RANSAC的尺度计算是一样的,这的确是个问题,希望知道的人能够解答。关于具体的代码解释,这里在代码中给出了详尽的注释。
关于数据归一化的详细介绍可以参看:Multiple View Geometry in Computer Vision Senond Edition Richard Hartley / Andrew Zisserman Cambridge University Press
本文转自http://blog.youkuaiyun.com/xizero00/article/details/7454173