本文介绍一种利用查找表技术实现图像索引的方式,由于无需遍历整个图像序列从而提高检索效率。
一,问题的提出
利用VisualSFM集成的CMVS/PMVS生成的patch文件保存了以物方为基准的点云信息,对于每个点,保存了该点的三维座标,法向量,相关系数等信息,也保存了生成该点的图像索引,格式如下所示:
PATCHS
0.701445 -1.50268 -5.60965 1
0.705198 -0.42948 0.56413 0
0.853315 0.0191083 0.737723
5
48 56 38 50 57
11
53 55 58 81 84 106 115 117 85 87 93
注:根据上面patch文件的格式,对于这个点,一共有5幅图像参与了点的重建,编号分别是48,56,38,50,57.
那么,问题就来了,如何进行这一转换?
我们需要对每幅影像计算其参与重建的点的信息,最简单的,我们认为,直接建立一个包括所有影像的数组进行转换即可。然而,CMVS并不是所有输入影像都会参与重建,例如上面的例子中,只有25幅影像是参与重建的(这一信息保存在ske文件当中,格式如下)
SKE
132 1
25 0
38 39 48 50 53 54 55 56 57 58 81 84 85 87 93 106 109 111 112 115 117 121 122 123 130
显然,如果建立132维的向量是没有必要的,我们只需要一个25维的向量images[]即可。但是,如果各自存储的话检索时需要遍历整个数组(比如对于上面的那个点,我们要给编号48的图像存储信息,这时要找到它在images[]中的位置),这显然是不可取的。
那么问题又来了,图像的索引和数组如何对应才能规避检索时的遍历?
二,方法介绍
方法是这样的,如下图所示,构建两个数组,一个是imageTable,用来存储原始影像编号和实际存储信息数组images的对应关系,一个是images是实际存储点位信息的数组,由它来对应实际的点的分类结果。
三,具体实现
具体地实现如下:
typedef struct
{
float x,y,z;
float nx,ny,nz;
float zncc;
}POINT;
typedef struct
{
int no;
int num_pts;
}IMG;
int num_valimages;
int num_allimages;
int *imageTable;
IMG *images;//保存每幅有效影像的编号及其点的个数
POINT **pt;
for (int i=0;i<num_allimages;i++)
{
imageTable[i] = -1;
}
for (int i=0;i<num_valimages;i++)
{
fscanf(fp,"%d",&ia);
imageTable[ia] = i;
images[i].no = ia;
}
以上是实现原始图像索引和images的对应。由此,开始从patch文件中存取信息:
for (int i=0;i<npoint;i++)
{
fscanf(fp,"PATCHS");
fscanf(fp,"%f%f%f%d",&t_pt.x,&t_pt.y,&t_pt.z,&fc);
fscanf(fp,"%f%f%f%d",&t_pt.nx,&t_pt.ny,&t_pt.nz,&fd);
fscanf(fp,"%f%f%f",&t_pt.zncc,&fc,&fd);
fscanf(fp,"%d",&ic);
for (int t=0;t<ic;t++)
{
fscanf(fp,"%d",&id);
int iImg = imageTable[id];
int iPt = images[iImg].num_pts;
pt[iImg][iPt] = t_pt;
images[iImg].num_pts++;
}
fscanf(fp,"%d",&ic);
for (int t=0;t<ic;t++)
{
fscanf(fp,"%d",&id);
}
}
保存结果时,如下实现:
for (int i=0;i<num_valimages;i++)
{
fprintf(fp,"\n%d\n\n",images[i].no);
for(int j=0;j<images[i].num_pts;j++)
{
fprintf(fp,"%f %f %f %f %f %f %f\n",pt[i][j].x,pt[i][j].y,pt[i][j].z,pt[i][j].nx,
pt[i][j].ny,pt[i][j].nz,pt[i][j].zncc);
}
}
四,总结
本文的方法有两个好处:
1. 通过查找表imageTable规避了图像的遍历检索,节省了时间;
2. 由于采用images为数据存储的基准,对应的点云数据pt的开销也得到减少,节省了内存;