一种图像索引的查找表实现方法(VisualSFM点云数据存储基准从物方到像方的转换)
2014-11-16 17:18
393 查看
本文介绍一种利用查找表技术实现图像索引的方式,由于无需遍历整个图像序列从而提高检索效率。
一,问题的提出
利用VisualSFM集成的CMVS/PMVS生成的patch文件保存了以物方为基准的点云信息,对于每个点,保存了该点的三维坐标,法向量,相关系数等信息,也保存了生成该点的图像索引,格式如下所示:
注:根据上面patch文件的格式,对于这个点,一共有5幅图像参与了点的重建,编号分别是48,56,38,50,57.
然而,我们有时需要以像方为基准的点云信息,即对于每幅影像,有哪些三维点是落入该影像的,有了这个文件,我们可以生成每幅图像的深度图(depthmap),这对于三维重建是有用的。
那么,问题就来了,如何进行这一转换?
我们需要对每幅影像计算其参与重建的点的信息,最简单的,我们认为,直接建立一个包括所有影像的数组进行转换即可。然而,CMVS并不是所有输入影像都会参与重建,例如上面的例子中,只有25幅影像是参与重建的(这一信息保存在ske文件当中,格式如下)
那么问题又来了,图像的索引和数组如何对应才能规避检索时的遍历?
二,方法介绍
方法是这样的,如下图所示,构建两个数组,一个是imageTable,用来存储原始影像编号和实际存储信息数组images的对应关系,一个是images是实际存储点位信息的数组,由它来对应实际的点的分类结果。
三,具体实现
具体地实现如下:
本文的方法有两个好处:
1. 通过查找表imageTable规避了图像的遍历检索,节省了时间;
2. 由于采用images为数据存储的基准,对应的点云数据pt的开销也得到减少,节省了内存;
一,问题的提出
利用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的开销也得到减少,节省了内存;
相关文章推荐
- php实现数组中索引关联数据转换成json对象的方法
- 利用存储过程实现交叉表格式数据查询的一种通用方法
- php实现数组中索引关联数据转换成json对象的方法
- 利用存储过程实现交叉表格式数据查询的一种通用方法
- 介绍一种将ASCII码字符串转换为二进制字节数据的方法
- SQL2000+存储过程+触发器+DLL调用的方法来实现数据实时转换
- JSP中表单数据存储的一种通用方法
- 对于JSP中表单数据存储的一种通用方法
- 在vc中实现DIB图像镜像转换的两个方法
- 一种理想的在关系数据库中存储树型结构数据的方法
- 一种理想的在关系数据库中存储树型结构数据的方法 - Just do it - 博客园
- (原创)用verilog实现RGB格式图像到YCbCr或YUV格式的转换及其验证方法 (RGB2YCrCb)(RGB2YUV)
- SQL2000+存储过程+触发器+DLL调用的方法来实现数据实时转换
- 用VC,VB进行图像数据(二进制大对象)存储数据库的方法
- SQL Server存储图像数据的策略与方法
- 介绍一种将ASCII码字符串转换为二进制字节数据的方法
- 一种理想的在关系数据库中存储树型结构数据的方法
- SQL Server存储图像数据的策略与方法
- 递归实现与实现转换数据的方法
- 用ObjectDataProvider绑定方法,用IValueConverter实现数据类型转换,重载ValidationRule实现数据验证,BindsDirectlyToSource等