您的位置:首页 > 其它

一种图像索引的查找表实现方法(VisualSFM点云数据存储基准从物方到像方的转换)

2014-11-16 17:18 393 查看
本文介绍一种利用查找表技术实现图像索引的方式,由于无需遍历整个图像序列从而提高检索效率。

一,问题的提出

利用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.

然而,我们有时需要以像方为基准的点云信息,即对于每幅影像,有哪些三维点是落入该影像的,有了这个文件,我们可以生成每幅图像的深度图(depthmap),这对于三维重建是有用的。
那么,问题就来了,如何进行这一转换?

我们需要对每幅影像计算其参与重建的点的信息,最简单的,我们认为,直接建立一个包括所有影像的数组进行转换即可。然而,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的开销也得到减少,节省了内存;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: