sbonaretti/pyKNEEr

Further processing of thickness maps

Closed this issue · 6 comments

Hi Serena,
I've been using pyKNEEr to create cartilage thickness maps for the subjects in one of our studies. However, I can't figure out how to get the maps back into a file format that can be overlaid with the original structural scans, which is necessary for the analysis I intend to do further. There doesn't seem to be any way described in the documentation to take these "point clouds" and translate them to, for example, a 2D NIFTI or other common file type. If I can figure out how to get the thickness maps to display, for example, in ITK-SNAP, I can probably figure out how to implement the rest of the pipeline that I have in mind. If you have any suggestions for how to do something like this, I'd greatly appreciate if you can share them with me.
Thank you!
Abby

Hi Abby,

Thanks for using pyKNEEr!

That's right, right now there are no 3D thickness map images, and this is indeed a feature to add - thanks for recommending it!
To create 3D thickness map images, the first idea that comes up to my mind is:

  • For each voxel:
    • Consider all the thickness lines passing through the voxel (* - see explanation below)
    • Average them
    • Create a color map with average thicknesses.
  • Thicknesses are calculated as the euclidean distance between each point of the bone surface and the closest point of the articular surface. With the current implementation several lines can pass trough a voxel, and thus their thickness can be averaged.

Please, let me know whether this is clear and what you think about it.
Serena

Hi Serena,

Thank you for your response!

After looking at this with a couple of colleagues, I think the main thing we're unclear on is this: are the points in the pointcloud of each surface located in original image space (as defined by the Nifti header), or are they in "unrolled" space?

If we understand correctly, you do an "unrolling" of the cartilage before drawing these thickness lines, and the pointclouds describing the articular and chondral surfaces are in an "unrolled" space. If that's the case, then the colormap calculated as you described would also be in the "unrolled" space. However, we would need our colormap to be in the "real" image space as defined by the Nifti header of the original structural image. It's still not clear to us how to solve that problem. (Could we, for example, "reroll" the thickness map back into regular space? Is the transformation saved somewhere?) In any case, in general we're a bit confused about the unrolling business, so it would be really helpful if you can address that particular point!

Thanks again,
Abby

Hi Abby,

The coordinates of the points are in the 3D original image space. Points of the articular side of the cartilage are in the file *_artiCart.txt and the points of the subchondral side are in the file *_boneCart.txt (both files are in the folder morphology). Points are extracted from sagittal slices and the third coordinate is the slice position. Thicknesses are calculated in 3D. I do the "enrolling" only for visualization.
Does this make sense? I have two very hectic weeks in front of me, but then I will be able to look into this more carefully. Would that work for you?

Thanks for your patience,
Serena

Hi again Serena,
Yes, this does make sense!
I think what I'm going to try to do is this: I can create a matrix in Matlab that has the same dimensions as the original image space, and "fill it in" using the coordinates from the cartilage surface text files. We have code that can create "fake" dicoms from Matlab matrices, copying the header information from the original. So, I can create a dicom that has these surfaces --basically as a 3D mask whose pixel values are equal to their thicknesses. Then I can overlay this dicom with the structural image in ITK-SNAP.
I would welcome your input as to the quality of this plan :)
Thanks!
Abby

Hi Abby,
My hectic period is over - thanks for your patience!
I am not sure I understand the final output of your pipeline ("a 3D mask whose pixel values are equal to their thicknesses"). Are you going to assign thickness values only to the voxels at the edge of the cartilage or also to the inner voxels?
Also, have you considered writing your code in python? We could add your contribution to the current development and you would be added as one of pyKNEEr's contributors.
Serena