Abstract
This paper describes the Insight Toolkit (ITK) Spherical Wavelet object: itkSWaveletSource. This ITK object is an implementation of a paper by Schr¨oder and W. Sweldens, “Spherical Wavelets: Effi- ciently Representing Functions on the Sphere” [8], with pseudo-code given in their paper entitled “Spherical wavelets: Texture processing” [7]. In these papers, Swelden et. al. show how to do decompose a scalar signal defined on a spherical mesh into spherical wavelet coefficients (analysis step, also called forward transform), and vice-versa (synthesis step, also called inverse transform). We have implemented the spherical wavelet transform in ITK entitled itkSWaveletSource object, which will take the scalar function defined on a spherical mesh as input and apply spherical wavelet analysis and synthesis on it. In this paper, we describe our code and provide the user with enough details to reproduce the results which we present in this paper. This filter has a variety of applications including shape representation and shape analysis of brain surfaces, which was the initial motivation for this work. This paper is accompanied with the source code, input data, parameters and output data that the authors used for validating the spherical wavelet transform described in this paper.
Keywords
Source Code and Data
Reviews
Luis Ibanez
Tuesday 11 September 2007
Summary:
This paper contributes a filter that generates a Wavelet decomposition of a function defined on the unit sphere, and a filter that recompose a function from a set of wavelet coefficients
Open Science:
This paper seems to be a great example of Open Science.
The material needed for replicating the work seems to be provided by the athors.
However, compilation problems and run time error made a bit harder to verify whether the material provided was complete or not.
After the compilation error were dealt with, it was possible to use the material easily and to verify the results presented by the authors.
Reproducibility:
I was able to compile the code without mayor problem.
Only had to fix three warning due to lack of explicit casting from double to int and unsigned long:
The changes were made in the following lines:
itkSWaveletSource.txx:308: unsigned long nOfVerts = static_cast( 10.0 * pow(4, i ) + 2 ); // for icosahedron.
itkSWaveletSource.txx:309: unsigned long nOfNewVerts = static_cast( 10.0 * pow(4,i+1) + 2 ); // for icosahedron.
itkSWaveletSource.txx:841: int resolution = static_cast( 1 + floor(log((nOriVerts-2)/10)/log(4)) );
I was surprised to find that four of the five tests were commented out in the CMakeLists.txt file.
The only enabled test crashes at run time with the following message:
testing task 5:
step 1.1 we have a scalar function defined on the vertexes of the finest mesh. Here we just use the z-coordinates as the function.
step 1.2 Do a wavelet transform of the function and we get wavelet coefficients.
step 1.3 Do a wavelet inverse transform from the coefficients to reconstruct the original function.
step 1.4 Compare the original functin with the reconstructed function to show the fedelity of the transform.
terminate called after throwing an instance of 'std::bad_alloc'
what(): St9bad_alloc
zsh: abort ./itkSWaveletTest5
When enabling the other tests, they failed to compile.
IJ-Spherical_Wavelet_ITK_Filter.1/itkSWaveletTest/itkSWaveletTest.cxx:146: error: expected unqualified-id before ‘else’
IJ-Spherical_Wavelet_ITK_Filter.1/itkSWaveletTest/itkSWaveletTest.cxx:150: error: expected declaration before ‘}’ token
IJ-Spherical_Wavelet_ITK_Filter.1/itkSWaveletTest/itkSWaveletSource.txx: In member function ‘void itk::SWaveletSource::SetWaveletCoefficientAtScale(int, int, double) [with TOutputMesh = itk::Mesh >]’:
The error seemed to arise from a copy/paste mistake.
After fixing it, the code compiled fine.
---
It was pretty easy to reproduce the results of Figure 2, following the clear instructions on page 6 of the paper.
The visualization of each one of the different sphere resolutions matched the images in Figure 2.
--
The paper fails to mention that the code of section 2.3 is available in the test
itkSWaveletTest2.cxx
This test prints out the reconstruction error for the level of resolution provided by the in the command line.
The errors reported are indeed in the range of 10^-6, as the paper indicates:
Resolution Error
1 ==> 1.11022e-16
2 ==> 2.18535e-19
3 ==> 2.22045e-16
4 ==> 1.11022e-16
5 ==> 3.33067e-16
6 ==> 3.33067e-16
---
In section 2.4 It should probably state that the corresponding source code is in the example
itkSWaveletTest.cxx
That being, said,
by running this example I got the following files:
reconstructedFnKWVisuChanged.txt
reconstructedFnKWVisu.txt
reconstructedFn.txt
ScalingFnKWVisu.txt
but couldn't load them in KWMeshVisu because this appication expects files with extension .meta
or .vtk. Simply renaming the files to change the extension didn't allowed me to load the files.
It would have been useful to have simple instructions on how to load the files in KWMeshVisu.
I had to add to the code the following line:
mySphereMeshSource->WriteMeshToMetaFile("Mesh.meta",n);
To save the Mesh itself into a file, and then be able to use KWMeshVisu.
From KWMeshVisu I loaded the "Mesh.meta" file as a mesh, and then loaded the files as 1D scalar properties
reconstructedFnKWVisuChanged.txt
reconstructedFnKWVisu.txt
reconstructedFn.txt
ScalingFnKWVisu.txt
WaveletFnKWVisu.txt
The paper fails to mention that the mesh files are along with the source code in a meta directory.
The CMakeLists.txt file could have been formated for making the different figures a test by using the ADD_TEST command. In that way these different usage details could have been provided explicitly.
----
In section 3, the authors refer to a "filteringShape.cxx" file that is not included with the contribution.
Use of Open Source Software:
- The authors used the Insight Toolkit (ITK),
- The Visualization Toolkit (VTK)
- and suggested the use of a previous IJ paper (KWVisu) for visualizing the mesh results: http://insight-journal.org/dspace/handle/1926/220
Open Source Contributions:
The authors provide their source code, and the paper provide examples on how to use it.
Unfortunately only one of the examples is enabled for compilation.
Code Quality:
[If the authors provided their source code: Was the code easy to read? Did they use a modern coding style? Did they rely on non-portable mechanism? Was it suitable for multiple-platforms?]
Applicability to other problems:
[Do you find that the authors methods can be applied to other image analysis problems? Suggest other disciplines or even other specific projects that could take advantage of this work]
Suggestions for future work:
[Suggest to authors future directions for improving their methods, or other domains from which they could learn technique that could help them advance in their research.]
Requests for additional information from authors:
[Did you find that information was missing from the paper? Maybe parameters for running the tests? Maybe some images were missing? Would you like to get more details on how the diagrams, or plots were generated?]
Additional Comments:
[This is a free-form field]
Alexandre Gouaillard
Thursday 26 July 2007
Summary:
This paper is an implementation of the original spherical wavelet paper by Swelden. The main goal is to be able to do analysis of (genus 0 = parameterizable on the sphere) shapes. It is becoming a standard approach when coupled with the spherical parameterization for brain surface analysis for example.
Hypothesis:
Evidence:
Open Science:
The paper is clear and explain with sufficient detail the implementation. The implementation seems to be as close as possible to the paper.
Reproducibility:
I downloaded the code, and comfigure it with for the following configuration:
cmake 2.4.6, Win32 on top of win64 (XP) MSVC++ 2005 (32bits).
I needed to apply the following minor changes for the code to compile:
itkSWaveletSource.txx:308,309
< unsigned long nOfVerts = 10pow(4,i) + 2; // for icosahedron.
< unsigned long nOfNewVerts = 10pow(4,i+1) + 2; // for icosahedron.
---
> unsigned long nOfVerts = 10pow(4.0,(int)i) + 2; // for icosahedron.
> unsigned long nOfNewVerts = 10pow(4.0,(int)i+1) + 2; // for icosahedron.
itkSWaveletSource.txx:841
< int resolution = 1 + floor(log((nOriVerts-2)/10)/log(4));
---
> int resolution = 1 + floor(log((nOriVerts-2.0)/10.0)/log(4.0));
Thedefault example did not work. It seems to exhaust the memory trying to read a file:
itkSWaveletTest5.cxx:60 getScalarFn("x10.txt", oriF);
itkSWaveletTest5.cxx:99 scalarFn.push_back(a);
[...]
Unhandled exception at 0x7d4e2366 in itkSWaveletTest5.exe: Microsoft C++ exception: std::bad_alloc at memory location 0x0139fb6c..
It came from my building in a separate tree. The example assumes that you are running it at the sme level as the files. Moreover, the getScalarFn that reads from disk does not check if the file was found and is open before it tries to read from it.
Here are the corresponding fixes:
:60,61:
getScalarFn("../x10.txt", oriF);
mySphereMeshSource->SetScalarFunctionWithSphere( "../para10.meta", oriF);
:92,105:
void getScalarFn(char* scalarFileName, std::vector< double >& scalarFn)
{
std::ifstream f(scalarFileName);
if( f.fail( ) )
{
// print an error here
exit( EXIT_FAILURE );
}
double a;
while(!f.eof())
{
f>>a;
scalarFn.push_back(a);
}
Use of Open Source Software:
The filter is written on top of ITK.
Open Source Contributions:
The paper is clear and explain with sufficient detail the implementation.
Code Quality:
As for the design, I love the work on the wavelet coefficients. Being able to access both the mesh and the corresponding wavelet at any level of decomposition is a great idea. It open the way to a lot of applications (compression, watermarking, any filtering, ...).
The code is not yet up to ITK standard: there seems to be a lot of commented out code. the debug and warning macro are not used (cerr is used instead) and it seems to have be written using arrays first. Some parts have been rewritten using stl (vector) but some parts still used arrays. Testing it through the web interface of KWStyle could help the authors enhance the style greatly (http://66.194.253.24/KWStyle/).
The types are hard coded, and ,as the author themselves admit, templating it depending on the mesh traits or on other arithmetic types would be great.
The code is written on top of itk::Mesh and thus must deal with a lot of shortcomings. The authors reimplement a pointToCell array and assume orientability, orientation consistency as well as 2-manifoldness. I'm pretty sure the code would break if you use as input a sphere of which one triangle or more would be flipped inside-out. It would also be nice to check if the mesh is triangular first. I would recommand, if the author had the time, to rewrite it on top of an itkQuadEdgeMesh. One itkMeshToMeshFilter enforcing the orientation would still be need though.
It would be nice to have the subdivision part separated from the wavelet feature. We could think of a general 1 to 4 subdivision filter (abstract, topology only) with a set of functions implementing the geometrical behavior (new point function of old point + mask). That open the way to subdivision filters in ITK, as well as predictive filtering for wavelet compression, lazy wavelets and so on.
Applicability to other problems:
There is the direct problem the authors are addressing: (brain surface) shape analysis, but having access to the wavelet and to the inverse transform, you can think about almost any kind of filtering in wavelet space including:
- denoising (wavelet coefficient thresholding)
- compression,
- watermarking,
- optimization of active surface algorithms,
You can see those two pages for ideas:
http://www.creatis.insa-lyon.fr/~agouaillard/Research.htm
http://www.creatis.insa-lyon.fr/~valette/publis.htm
Suggestions for future work:
- write a test suite to enforce the expected behavior, it would help reviewers make some experiments with the code and even add fonctionalities.
- template over meshtraits / arithmetic types.
- rewrite on top of of QEMesh (much easier to code, much easier to maintain, faster)
- separate subdivision from wavelet
- would pluggable wavelet functions be too hard to code (I sincerely have no idea) ?
Requests for additional information from authors:
I loved the paper.
Additional Comments:
i'd like to help the authors fix the problems, and even implement some of my recommendations.
