一種圖像索引的查找表實現方法(VisualSFM點雲數據存儲基準從物方到像方的轉換)

本文介紹一種利用查找表技術實現圖像索引的方式,由於無需遍歷整個圖像序列從而提高檢索效率。

一,問題的提出

利用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的開銷也得到減少,節省了內存;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章