1.什么是数据归一化?
归一化是一种无量纲处理手段,使物理系统数值的绝对值变成某种相对值关系。简化计算,缩小量值的有效办法。
2.数据归一化的必要性
在RANSAC算法中,计算2D homography过程中,需要依赖图像的坐标系,那么图像的相似变换T就不能够保证不变性,归一化的方法能够消除坐标系的影响
3.数据归一化的好处
RANSAC中:能够保证即便是不同坐标系的两幅图像也能够有着相同的平均梯度
4.数据归一化如何实现?
1)原理:
①将点转换到重心,使得重心作为起点;
②将点进行尺度变换,使得点到重心的距离为原来的根号2
2)实现:
①RANSAC算法中的实现:
本文中的RANSAC算法的实现来自于http://download.csdn.net/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