图像坐标的归一化
图像坐标的归一化
/***************************************************
功能:归一化数据
1、对点坐标进行平移使其形心位于原点(0,0);
2、对点坐标进行缩放使它们到原点的平均距离为sqrt(2);
****************************************************/
//图象坐标向量
typedef struct
{
float x;
float y;
float w;
} imageCoord, *pImageCoord;
#define MAX_TOTAL 500
imageCoord coords[MAX_TOTAL];
void CvMat2Array(CvMat *cvArr, float *arr, int row, int col)
{
for(int i = 0; i < row; i++)
{
for(int j = 0; j < col; j++)
{
arr[i*col+j] = (float)cvmGet(cvArr, i, j);
}
}
}
void Arrayt2CvMat(float *arr, CvMat *cvArr, int row, int col)
{
for(int i = 0; i < row; i++)
{
for(int j = 0; j < col; j++)
{
cvmSet(cvArr, i, j, arr[i*col+j]);
}
}
}
void normalizeImageCoord(imageCoord coords[], int total, CvMat* T)
{
float sumX = 0;
float sumY = 0;
for(int i = 0; i < total; i++)
{
sumX =+ coords[i].x;
sumY =+ coords[i].y;
}
float meanX = 0;
float meanY = 0;
meanX = sumX/total;
meanY = sumY/total;
float meanDist = 0;
for(int j = 0; j < total; j++)
{
meanDist += (float)pow( (meanX-coords[j].x), 2) + (float)pow( (meanY-coords[j].y), 2);
}
meanDist = (float)sqrt(meanDist)/4;
float scale = (float)sqrt(2.0)/meanDist;
float t[] = {scale, 0, -scale*meanX,
0, scale, -scale*meanY,
0, 0, 1};
Arrayt2CvMat(t, T, 3, 3);
for(int k = 0; k < total; k++)
{
float tempX = t[0]*coords[k].x + t[1]*coords[k].y + t[2]*coords[k].w;
float tempY = t[3]*coords[k].x + t[4]*coords[k].y + t[5]*coords[k].w;
float tempW = t[6]*coords[k].x + t[7]*coords[k].y + t[8]*coords[k].w;
coords[k].x = tempX/tempW;
coords[k].y = tempY/tempW;
}
}
测试如下:
int main()
{
srand( (unsigned)time( NULL ) );
for(int n = 0; n < 5; n++)
{
coords[n].x = (float)( rand() % 800);
coords[n].y = (float)( rand() % 600);
coords[n].w = 1;
printf("x = %f, y =%f, w = %f\n", coords[n].x, coords[n].y, coords[n].w);
}
CvMat *T = cvCreateMat(3, 3, CV_32FC1);
CvMat *invertT = cvCreateMat(3, 3, CV_32FC1);
normalizeImageCoord(coords, 5, T);
printf("图象坐标数据归一化后:\n");
for(int t = 0 ; t < 5; t++)
{
printf("xx = %f, yy =%f, ww = %f\n", coords[t].x, coords[t].y, coords[t].w);
}
float test[9];
CvMat2Array(T, test, 3, 3);
float invertArray[9];
/***************图象坐标数据解除归一化***********************/
cvInvert(T, invertT);
CvMat2Array(invertT, invertArray, 3, 3);
for(int c = 0; c < 5; c++)
{
float tempX = invertArray[0]*(coords[c].x) + invertArray[1]*(coords[c].y) + invertArray[2]*(coords[c].w);
float tempY = invertArray[3]*(coords[c].x) + invertArray[4]*(coords[c].y) + invertArray[5]*(coords[c].w);
float tempW = invertArray[6]*(coords[c].x) + invertArray[7]*(coords[c].y) + invertArray[8]*(coords[c].w);
coords[c].x = tempX/tempW;
coords[c].y = tempY/tempW;
}
printf("图象坐标数据解除归一化后:\n");
for(int l = 0 ; l < 5; l++)
{
printf("x = %f, y =%f, w = %f\n", coords[l].x, coords[l].y, coords[l].w);
}
』
运行效果如图:

您当前的位置: