/** SamplesToCoefficients.<br> Implement the algorithm that converts the image samples into B-spline coefficients. This efficient procedure essentially relies on the three papers cited above; data are processed in-place. Even though this algorithm is robust with respect to quantization, we advocate the use of a floating-point format for the data. @param Image Input / Output image (in-place processing) @param Width Width of the image @param Height Height of the image @param spline_degree Degree of the spline model @return Returns true if success, false otherwise */ static bool SamplesToCoefficients(double *Image, long Width, long Height, long spline_degree) { double *Line; double Pole[2]; long NbPoles; long x, y; // recover the poles from a lookup table switch (spline_degree) { case 2L: NbPoles = 1L; Pole[0] = sqrt(8.0) - 3.0; break; case 3L: NbPoles = 1L; Pole[0] = sqrt(3.0) - 2.0; break; case 4L: NbPoles = 2L; Pole[0] = sqrt(664.0 - sqrt(438976.0)) + sqrt(304.0) - 19.0; Pole[1] = sqrt(664.0 + sqrt(438976.0)) - sqrt(304.0) - 19.0; break; case 5L: NbPoles = 2L; Pole[0] = sqrt(135.0 / 2.0 - sqrt(17745.0 / 4.0)) + sqrt(105.0 / 4.0) - 13.0 / 2.0; Pole[1] = sqrt(135.0 / 2.0 + sqrt(17745.0 / 4.0)) - sqrt(105.0 / 4.0) - 13.0 / 2.0; break; default: // Invalid spline degree return false; } // convert the image samples into interpolation coefficients // in-place separable process, along x Line = (double *)malloc(Width * sizeof(double)); if (Line == NULL) { // Row allocation failed return false; } for (y = 0L; y < Height; y++) { GetRow(Image, y, Line, Width); ConvertToInterpolationCoefficients(Line, Width, Pole, NbPoles, DBL_EPSILON); PutRow(Image, y, Line, Width); } free(Line); // in-place separable process, along y Line = (double *)malloc(Height * sizeof(double)); if (Line == NULL) { // Column allocation failed return false; } for (x = 0L; x < Width; x++) { GetColumn(Image, Width, x, Line, Height); ConvertToInterpolationCoefficients(Line, Height, Pole, NbPoles, DBL_EPSILON); PutColumn(Image, Width, x, Line, Height); } free(Line); return true; }
/*--------------------------------------------------------------------------*/ int SamplesToCoefficients ( MRI *mri_vol, /* in-place processing */ long SplineDegree /* degree of the spline model */ ) { /* begin SamplesToCoefficients */ double *Line; double Pole[2]; long NbPoles; long x, y, z; long Width, Height, Depth; /* recover the poles from a lookup table */ switch (SplineDegree) { case 2L: NbPoles = 1L; Pole[0] = sqrt(8.0) - 3.0; break; case 3L: NbPoles = 1L; Pole[0] = sqrt(3.0) - 2.0; break; case 4L: NbPoles = 2L; Pole[0] = sqrt(664.0 - sqrt(438976.0)) + sqrt(304.0) - 19.0; Pole[1] = sqrt(664.0 + sqrt(438976.0)) - sqrt(304.0) - 19.0; break; case 5L: NbPoles = 2L; Pole[0] = sqrt(135.0 / 2.0 - sqrt(17745.0 / 4.0)) + sqrt(105.0 / 4.0) - 13.0 / 2.0; Pole[1] = sqrt(135.0 / 2.0 + sqrt(17745.0 / 4.0)) - sqrt(105.0 / 4.0) - 13.0 / 2.0; break; default: printf("Invalid spline degree\n"); return(1); } Width = mri_vol->width; Height = mri_vol->height; Depth = mri_vol->depth; /* convert the image samples into interpolation coefficients */ /* in-place separable process, along x */ Line = (double *)malloc((size_t)(Width * (long)sizeof(double))); if (Line == (double *)NULL) { printf("Row allocation failed\n"); return(1); } for (z = 0L; z < Depth; z++) { for (y = 0L; y < Height; y++) { GetRow(mri_vol, y, z, Line); ConvertToInterpolationCoefficients(Line, Width, Pole, NbPoles, DBL_EPSILON); PutRow(mri_vol, y, z, Line); } } free(Line); /* in-place separable process, along y */ Line = (double *)malloc((size_t)(Height * (long)sizeof(double))); if (Line == (double *)NULL) { printf("Column allocation failed\n"); return(1); } for (z = 0L; z < Depth; z++) { for (x = 0L; x < Width; x++) { GetColumn(mri_vol, x, z, Line); ConvertToInterpolationCoefficients(Line, Height, Pole, NbPoles, DBL_EPSILON); PutColumn(mri_vol, x, z, Line); } } free(Line); /* in-place separable process, along z */ Line = (double *)malloc((size_t)(Depth * (long)sizeof(double))); if (Line == (double *)NULL) { printf("Column allocation failed\n"); return(1); } for (y = 0L; y < Height; y++) { for (x = 0L; x < Width; x++) { GetVertical(mri_vol, x, y, Line); ConvertToInterpolationCoefficients(Line, Depth, Pole, NbPoles, DBL_EPSILON); PutVertical(mri_vol, x, y, Line); } } free(Line); return(0); } /* end SamplesToCoefficients */