For a given view viewname, one needs to:
Once those files are created, save the names of the views (without extension) into a final file statue.3dp:
statue1
statue2
statue3
statue4
...
The alignment tool 3dpalign will take tat file name statue.3dp as only argument, and will let you align all the views (look at the page describing the 3dpalign tool).
Let us now look in details at the .range and .params files content: let's say that we are working on the 13th view of the statue. The two files we have to generate are statue13.range and statue13.params.
The first row of that matrix will correspond to pixel row rngy0 in the original image, and the first column will correspond to pixel column rngx0 (both quantities will most likely be larger than 0, since the region of interest covered by the object does not generally occupy the complete range of values for the {xpimg,ycimg} coordinates).
The format of the file stature13.range:
File content | |
1st line: | Nrow Ncol |
The subsequent Nrow x Ncol lines: | Xr Yr Zr [ C [ nx xny ny [ Cn [ color, other info]]]] |
where Xrange = [Xr,Yr,Zr] is the 3D range coordinates vector of a generic point after normalization. Notice that all the points are ordered row-wise, meaning that we first list all the points of the first row (from left to right) before moving to the second row (look at the example file). If a point does not exist, assign to it Xr=Yr=0 and Zr=-1e308 (Note that the [ and ] signs only symbolize the optionality aspects of some of the parameters. They should not appear in the file itself (only spaces between two consecutive values).
Those normalized coordinates are computed from the coordinates in the camera frame (Xcam = [Xc,Yc,Zc]) after subtraction of a 3D translation vector trc and scaled by a scalar coefficient src. In other words, we have:
Xr = (Xc - trc(1))/src; |
Yr = (Yc - trc(2))/src; |
Zr = (Zc - trc(3))/src; |
The two parameters trc and src can be chosen such that the center of mass of the cloud of points is located at the origin, and the maximum absolute value of the coordinates is "roughly" 1 (across the values Xr, Yr and Zr for all the points on the view).
VERY IMPORTANT: THE SCALE FACTOR scr HAS TO BE IDENTICAL FOR ALL THE VIEWS!!! One can compute src based on the points of the first view (statue1), and then used the same scale value for the all the subsequent views (statue2, statue3, ...). An alternative is to pick scr=1 for all views, and drop the coordinate normalization step all together (like in the example file). We recommend to choose that second alternative. This will prevent you from making mistakes. On the other hand, the normalizing translation vector trc does not need to be identical across views (it is recommended to set it so that the center of mass of the points is at the origin).
Those parameters will later be part of the parameter file statue13.params.
Notice that trc and src are in centimeters (like Xcam), however Xrange is unitless (if normalized by a non unitary scale src is applied).
Optionnally, one may also want to add to the 3D coordinates {Xr,Yr,Zr} some extra information on the points. You can successively add to each points:
We recommend to start with the minimal file format (the 3D coordinates only). That will prevent your files from being too large, and still allow you to perform the alignment task. Using that format, your file should look like:
236 246
|
Notice that we picked here src=1 (this is why the coordinates are not within -1 and 1). You don't have to do that, however, it is recommended.
We will in the future exploit the full potential given by the extra available information (especially confidence numbers, and surface normals).
The format of the file statue13.params (this is just an example here, the numerical values should be yours of course):
Parameter description | File content |
Scale normalization factor (src) Needs to be there even if equal to 1 |
src 1.00000000 |
Translation normalization vector(trc) Sets the center of mass to the origin |
trc -4.65601512 -1.59718542 172.60735398 |
Rigid body motion from camera to projector Translation vector: T (tcp) Rotation matrix: R (rcp) Entries of R (rcp) are stored row-wise |
tcp 76.80637107 -17.74639690 -35.14276573 rcp 0.88839168 0.09715148 -0.44868898 -0.02649762 0.98657392 0.16115139 0.45832095 -0.13127636 0.87903835 |
Intrinsic camera parameters Radial distortion factor: kc (kcam) Camera focal lengths: fc (fxcam,fycam) Camera optical center: cc (cxcam,cycam) |
kcam -0.44153276 fxcam 2689.85483872 fycam 2539.68919704 cxcam 319.50000000 cycam 239.50000000 |
Intrinsic projector parameters Projector focal length: fp (fxprj,fyprj) Projector optical center: cp (cxprj,cyprj) |
fxprj 1495.21893057 fyprj 1208.35520126 cxprj 319.00000000 cyprj 239.50000000 |
Origin of area of interest in the (xpimg,ycimg) grid: (rngx0,rngy0) |
rngx0 128 rngy0 88 |
Note that you can also add comments with the pound sign (#). In that case, everything up to the end of line is comment. A parameter file could very well look like this:
# Scale and translation from range date to camera frame (cm)
|
The alignement process will add to the file an additional parameter malign consisting of a 4x4 matrix describing the rigid motion bringing the range data coordinates to a common reference frame for all views. This reference frame will be next used for the volumetric representation (for voxels). Notice that malign will embed rotation R_align and translation T_align:
malign = |
|
The two following tables give a complete description of all the variables/parameters introduced here.
Xvol | 3D coordinates in common coordinate frame (after alignment) - voxels |
Xcam = [Xc,Yc,Zc] | 3D coordinates in camera frame (of each individual view) - centimeters |
Xrange = [Xr,Yr,Zr] | 3D coordinates in .range file. all components are between -1..1 - voxels |
xc, yc | 2D coordinates on camera focal plane (at z=1:after perspective division) - unitless |
Xprj = [Xp,Yp,Zp] | 3D coordinates in projector frame (of each individual view) - centimeters |
xcimg, ycimg | Coordinates in camera image; between 0..639,0..479 - pixels |
xpimg, ypimg | Coordinates in projector pattern; between 0..639,0..479 - pixels |
xrng, yrng | Integer indices in RANGE grid - pixels |
xtex, ytex | Inventor texture map coords in camera image (must be 0..1) |
Descriptions | Mathematical relations |
After alignment: From range coordinates to commom reference frame (malign is guaranteed to have only rotation/translation components) |
[Xvol,1] = malign * [Xrange,1] or: Xvol = R_align * Xrange + T_align |
Scale/Translation from range coordinates to camera coordinates |
Xcam = src * Xrange + trc |
Camera perspective projection | xc = Xc / Zc yc = Yc / Zc |
Conversion to image pixel coordinates | xcimg = cxcam + fxcam*xc*(1+kcam*(xc^2+yc^2)) ycimg = cycam + fycam*yc*(1+kcam*(xc^2+yc^2)) |
Rigid body motion between camera and projector frames (in old notations, rcp=R and tcp=T) |
Xprj = rcp * Xcam + tcp |
Projector perspective projection (in pixel) |
xpimg = cxprj + fxprj * Xp / Zp ypimg = cyprj + fyprj * Yp / Zp |
The column/row indices in the RANGE grid. |
xrng = xpimg - rngx0 yrng = ycimg - rngy0 |
Texture coordinates |
xtex = xcimg/639 ytex = 1 - ycimg/479 |
We recall that all coordinate frames have X going to the right, Y going down, Z going into the image.