Explanation for the algorithm to generate the 3D model and the distance fields of the 2D slides for the tongue data:
The whole Algorithm to generate the volume.vol from which we generate the distance field images and the 3D .smf model :
1) Read the 2D input contour images (30 slides in case of tongue data) and form a 3D volume dataset. The dataset indicates the 3D coordinates of all the data points read from the input contour images.
2) From the input images also read the input/output information of each of the points, -1 indicating an outside point, 0 indicating a point on the contour, and 1 indicating a point within the closed contour. Store these values in a file (name it Inside_Outside).
3) If provided a Z-scale, multiply the Z-values of the 3D volume dataset (that we received from Step 1) to generate a Z-scaled volume dataset. (So if the Z values are from 0 to 29 in the original dataset, and the Z-scale is 8, then they would now be from 0 to 233 (29*8+1). This is our DATA file that we would provide to the ANN library for computing shortest distance.
4) Reading the DATA file, we calculate the coordinates of the end points of the Bounding Box. The end points are the minimum and maximum values present in the X and Y axes, thus producing the ends of the Bounding Box. So lets say the Bounding Box of the Z-scaled contours has coordinates from (X1, Y1, Z1) to (X2, Y2, Z2). (X1, Y1,Z1) is the BoundingBoxOrigin.
5) User provides a padding parameter and a resolution parameter.
6) We create a QUERY file such that it contains coordinates starting from ((X1, Y1, Z1) - (PAD/RES) * (1,1,1)) till ((X2, Y2, Z2) + (PAD/RES) * (1, 1, 1)). Sampling is done at every 1/RES point. This is the Query File that we will send to the ANN library for shortest distance calculation.
7) To generate the inside/outside information for each of the Query points, we use trilinear interpolation on the values stored in modified Inside/Outside file. The modified Inside/Outside file is the original Inside/Outside file plus the PAD where each PAD point is considered as an outside point (with the value -1). Interpolation is again done at every 1/RES point. Let us store these values in a file called Interpolated_Inside_outside. These values are not just 0, 1, -1 but are double values that lie in between -1 and +1. The total number of these points is exactly equal to the QUERY points that we have.
8) Now, we calculate the shortest distance using ANN library. We feed the ANN library with the DATA and QUERY files which return us an unsigned distance. We multiply this unsigned distance with the values stored at Interpolated_Inside_outside. We keep these calculated signed distances in a 3D double array. Then we feed it to BreenVolume to generate the Volume.vol.
[BreenVolume* vol = NULL;
vol = new BreenVolume ("volume.vol", COLUMNS, ROWS, DEPTH);]
9) Running Marching Cubes on Volume.vol we generate the Volume.smf files.
10) We generate the Distance Images from Volume.vol using Ilya's code.
Dist = setUnNormalizedPixel (xpoints[i], ypoints[i], distance[i]) is calculated for a particular i, where I starts from 0 and goes till (row*column) of a particular slide. The distance[i] is signed.
setUnNormalizedPixel (c, r, val) {
image.pixelColor(c, r, ColorGray(normalize(val, -max_dist, max_dist)));
}
normalize(double num, double min, double max){
if(num < min) return 0;
if(num > max) return 1;
return (num-min)/(max-min);
}
11) To generate the contour images, we first make all +ve points white and all non positive points black. Then we use Edge Detect function of ImageMagick to generate the edge. It represents those points where +ve meets -ve.