-
Notifications
You must be signed in to change notification settings - Fork 532
ENH: Add Rescale interface #2599
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
Conversation
Codecov Report
@@ Coverage Diff @@
## master #2599 +/- ##
==========================================
- Coverage 67.62% 67.59% -0.03%
==========================================
Files 339 339
Lines 42787 42814 +27
Branches 5288 5288
==========================================
+ Hits 28934 28941 +7
- Misses 13171 13191 +20
Partials 682 682
Continue to review full report at Codecov.
|
nipype/interfaces/image.py
Outdated
class Rescale(SimpleInterface): | ||
"""Rescale an image | ||
|
||
Rescales the non-zero portion of ``in_file`` to match the bounds of the ' |
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.
single comma at the end of the line
ref_file = File(exists=True, mandatory=True, | ||
desc='Skull-stripped reference image') | ||
invert = traits.Bool(desc='Invert contrast of rescaled image') | ||
percentile = traits.Range(low=0., high=50., value=0., usedefault=True, |
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.
it is very unlikely the same percentile works well for both ends of the range. I would split this option or make it a tuple.
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.
Hmm. I expected that people would probably only ever want 0 or 1 (but left room for tweaking), but I can add more flexibility than this. This leads me to wonder if we want to permit different percentiles for the input and reference images. In which case we need 4 values, not 2.
WDYT? If possible, it'd be nice to allow a single knob, to keep it simple until somebody needs more refined control.
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.
WDYT?:
percentile = traits.Either(
traits.Range(low=0., high=50, value=0), # One-knob behavior
traits.Tuple(
traits.Either(None, traits.Range(low=0., high=50, value=0)),
traits.Either(None, traits.Range(low=50., high=100, value=100)),
), desc='...')
Then, if it is not a tuple, it has your one-knob mirror behavior. Otherwise you have a tuple, and you can always set one of the boundaries.
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.
My fixation for this is that T1 images typically show background pixels under the 15% and, except when there are WM hyperintensities, you probably want 98% or higher for the upper limit.
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.
So, if I'm reading this correct, we don't need to be concerned with supporting different percentiles for the input and the reference?
My fixation for this is that T1 images typically show background pixels under the 15% and, except when there are WM hyperintensities, you probably want 98% or higher for the upper limit.
This is true for skull-stripped images?
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.
Nope, but I think we should aim for this interface to work well in any situation.
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.
So, if I'm reading this correct, we don't need to be concerned with supporting different percentiles for the input and the reference?
Okay, gotcha. I'm always thinking of the input. I guess we should specify that this interface expects the reference file to be "consistent" (as in already thresholded).
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 think we should aim for this interface to work well in any situation.
I don't think this interface will work at all well in non-skull-stripped cases. Calculating the magic numbers needed won't be significantly easier or more robust than even mediocre skull stripping, if I were to make a guess.
I guess we should specify that this interface expects the reference file to be "consistent" (as in already thresholded).
I do say:
in_file = File(exists=True, mandatory=True,
desc='Skull-stripped image to rescale')
ref_file = File(exists=True, mandatory=True,
desc='Skull-stripped reference image')
And:
Rescales the non-zero portion of ``in_file`` to match the bounds of the
non-zero portion of ``ref_file``.
But I can very explicitly say in the docstring that they should be skull-stripped. And would you suggest not applying the supplied percentiles to the reference image, as well?
I guess what's your vision for what this interface should do when percentiles != (0, 100)?
@oesteban No rush, but just letting you know that I'm waiting for our discussion to resolve before making further changes. |
Sorry. We should go ahead with this, I am probably talking of a nonexistent problem. If my suggestion is an actual issue, it'll be straightforward to identify and fix. |
Upstreaming another interface from fMRIPrep. This one is based off of
fmriprep.interfaces.images.InvertT1w
. It rescales a skull-stripped image to match the rough statistics of another, which is not restricted to the case in which we applied it, so I renamed it.Differences from
InvertT1w
:invert
input)new_img_like
The original behavior is recoverable simply with
Rescale(invert=True, percentile=0.)
.