-
Notifications
You must be signed in to change notification settings - Fork 95
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[ENH] ITK IO to be LPS-aware #257
Conversation
@rijobro perhaps you could add this PR to the Image Geometry project for bookkeeping? |
@ashgillman could you rebase this on master resolving the conflict that appears after I squash-merged #248? |
i.e., use Disc. Dens. LPS coords for direction.
…rrectly. Still not fixed..
NB: Currently only reads orientation as unknown. If DICOM, field can possibly be available
Done |
There are some methods here that return image pointers. Should these be changes to be shared pointers? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
overall looks good, but I haven't checked the detail.
Regarding convert_ITK_to_STIR
and read_file_itk
returning bare pointers, it's not nice, but I don't mind too much as they are internal static functions. If we both to change them, they should return unique_ptr
(might be somewhat trickier than you think as we need to preserve backwards compatibility with non-C++11 compilers)
src/IO/ITKImageInputFileFormat.cxx
Outdated
for ( it.GoToBegin(); !it.IsAtEnd(); ++it, ++stir_iter) { | ||
itk::Point<double,3U> itk_coord; | ||
|
||
itk_coord[0] = -double(it.Get()[0]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why the minus signs here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rijobro I assume this can go now, I'll remove it. Best you double check on your data.
src/IO/ITKImageInputFileFormat.cxx
Outdated
switch (exam_info_sptr->patient_position.get_position()) { | ||
case PatientPosition::unknown_position: | ||
// If unknown, assume HFS | ||
// TODO: warning? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes please.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, best when we set patient_position to unknown I think
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure. would be then when reading. I guess here.
I have no idea if ITK reads patient position for other file formats (non-DICOM). would be great if they did...
src/IO/ITKImageInputFileFormat.cxx
Outdated
const BasicCoordinate<3,int> &min_indices, | ||
bool is_displacement_field) | ||
ITK_coordinates_to_STIR(const itk::ImageBase<3>::PointType &itk_coord, | ||
const STIRImageType stir_image, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reference to STIRImageType
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const STIRImageType& stir_image
? Sure, but curious why?
Does that prevent copying the whole image data?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes. (potentially) big objects should always be passed by (preferably const
) reference. Note for stuff like int
, float
etc. Really should add this to our developers-guide...
Since rebasing I am getting a numerical exception. Has anyone seen this before? Div by 0?
Update: nevermind, having more luck with debugger |
Issue was that itk_image->Clone() returned an empty image with none of the same data nor metadata as itk_image. I opted to allow conversion to modify itk_image, since it is not used elsewhere. Alternatively, this seems to be the way to duplicate an image - rather verbose in classic ITK style. https://itk.org/Wiki/ITK/Examples/SimpleOperations/ImageDuplicator |
As far as I'm concerned, this can be merged. ok? Regarding DICOM, I've posted a question to the ITK Community list |
The ITK list is now replaced by a forum. My question is here. The answer points to the section of the manual on DICOM IO. The relevant bit is at the end. @ashgillman, want to do that before merging, or later? |
Before probably makes sense, I'll have a look into it. |
Hmm, no current code is not correct. Writing is correct it seems, but if I read a NIfTI then write out again it is reversed in the SI and AP directions The below images are the phantom acquisitions at UCL mMR acquired with @bathomas. The first is the vendor reconstruction converted to .nii with |
Where's the error?If I do a STIR reconstruction on raw data, and save the output to .nii, the reconstruction appear correctly oriented w.r.t. vendor reconstructions, so the write seems to be working and the error I guess must be in the reader. Is the reorienter working?Here I print the Orientation and Origin before and after the reorienter.
This is the expected behaviour. Notice though that the axes flipping is the SI and AP directions, the same as I am getting an issue with. Does manually messing with the reorienter help?When I manually change the reorienter for HFS from RAS to RPI, the resulting image out has shifted its origin (an expected consequence), but the axes directions are still incorrect. The reorienter works on the meta data, what about voxel data?So maybe the reorienter isn't actually re-ordering the voxel data. Or maybe the iterator is smart in some way and iterates not in stored order? So I added this snippet to check the iterator data is actually changing:
which returns
So the reorienter is changing the voxel data... Test the testcheck that if I craft the reorienter to do nothing that no voxels change (reorient to LAS, the same as this particular input):
So...I must admit I am stumped... |
@rijobro, sounds good to me. People might get fed-up seeing the warning, but we have so many repetitive warnings in STIR already that one more isn't going to hurt :-; |
@ashgillman, turns out I can make changes directly in your branch. So I did that to add the warning. I'll do it via PR in the future, but this one seemed like a tiny change. |
Alright, I was also able to reduce some of the explicit templating, however it seems many are still required when the output type is assigned to a pointer, as the output type can't be determined. Edit: Sorry, missed some more comments made, pushing changes now. |
7e8a8e9
to
6b74596
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2 super-tiny suggestions.
Awaiting testing by @rijobro.
documentation/release_3.1.htm
Outdated
@@ -161,7 +162,8 @@ <h3>Changed functionality</h3> | |||
</li> | |||
<li> | |||
The orientation of images read/written via ITK has changed. It should now be correct if the patient | |||
was in HFS position. This is currently not checked (and for many file formats, never can be checked). | |||
was in HFS position for NIfTI (this can't be verified due to lack of metadata in the format), or if |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I find this a bit awkward to read. I suggest
was in HFS position. Unfortunately, for most file formats (such as NifTI) this can't be verified due to lack of metadata in the format. If the files are in DICOM format, as long as the file contains the correct metadata, other patient positions are supported (currently HFS, FFS, HFP or FFP).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes was a bit muddled in my head as I tried to get the words out. Much better
Co-Authored-By: ashgillman <ashley.gillman@my.jcu.edu.au>
Sorry, should have added the skip ci tag. |
Tested by performing non-rigid transformation of nifti image with nifti displacement field. Result was the same as before. Any other tests needed? |
Did a small PR. By default, you were setting |
to me, setting the defaults doesn't make a lot of sense. do we need them? Anyway, whatever works really. I'm eager to press the "squash and merge" button! |
I meant to say that the default wasn't being overridden, which means that the displacement image was being treated as if it was a deformation. Looks good to me now! (once Ash accepts my PR) |
[FIX] default to displacement not deformation
Ah I see, I hadn't gone high enough with the I think the default makes sense where @rijobro left it (I have previously removed the others), since you don't want to have to choose it for single images. I also kept the default in But I'm not sure you really care! Point is I also am happy now :) |
13d6ebb
to
ab735eb
Compare
done? |
Yep |
Solution for #242
Depends #248
Still one TODO - reading orientation from DICOM. But works for now with NIfTI by assuming HFS (actually it calls it unknown, this is just treated like HFS in #248).