Skip to content
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

BUG: fixes to improve handling of single frame SEG #89

Merged
merged 2 commits into from
Oct 15, 2016

Conversation

fedorov
Copy link
Member

@fedorov fedorov commented Sep 16, 2016

No description provided.

@fedorov
Copy link
Member Author

fedorov commented Sep 16, 2016

Note for the discussion: this should be improved further. Spacing should be calculated for consecutive frames of the individual segment. Right now, all frames are considered indiscriminately. Question is whether it should be computed at all, considering we do not have any information about whether the 2 frames are adjacent or not, so perhaps we should always rely on the declared spacing, and not even try to compute it?

To be discussed with @QIICR/dcmqi

@fedorov
Copy link
Member Author

fedorov commented Sep 16, 2016

so perhaps we should always rely on the declared spacing, and not even try to compute it?

I should have used have no choice but instead of should. At least I don't see any choice. Assumption of consecutive frames that is valid for scalar volumes does not apply to segmentations.

@pieper
Copy link
Member

pieper commented Sep 16, 2016

I think the Slice Thickness should be a mandatory requirement for a valid
segmentation object and Image Position should be mandatory for each frame.
That way everything is well defined and there is no need for the concept of
Slice Spacing. If I recall the standard correctly I realize this isn't the
way it is in the standard but we could still generate warnings from dcmqi
if there is any chance for ambiguity.

It's really just not right to leave this to chance when we are talking
about a segmentation boundary that could be used as a resection or therapy
delivery zone boundary.

On Fri, Sep 16, 2016 at 2:50 PM, Andrey Fedorov notifications@github.com
wrote:

Note for the discussion: this should be improved further. Spacing should
be calculated for consecutive frames of the individual segment. Right now,
all frames are considered indiscriminately. Question is whether it should
be computed at all, considering we do not have any information about
whether the 2 frames are adjacent or not, so perhaps we should always rely
on the declared spacing, and not even try to compute it?

To be discussed with @QIICR/dcmqi
https://github.com/orgs/QIICR/teams/dcmqi


You are receiving this because you are on a team that was mentioned.
Reply to this email directly, view it on GitHub
#89 (comment), or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAHsfZvv4HkDjHFO66fCnj4dMD4984G8ks5qquUIgaJpZM4J_PIV
.

@fedorov
Copy link
Member Author

fedorov commented Sep 16, 2016

@pieper for the context, here is the code that handles parsing the "declared" spacing. SliceThickness is 1C for SEG, but only after this CP, and so one can have an "imperfectly" valid SEG object that will not have this information...

Here is the code that makes the decision which spacing to use - declared or computed: https://github.com/QIICR/dcmqi/blob/master/libsrc/ImageSEGConverter.cpp#L442-L468

What I am saying is that we just cannot compute spacing from the slice positions, and thus we should remove any use of computed spacing. If SEG doesn't have SliceThickness or SpacingBetweenSlices, we should probably fail with the error that there is no sufficient information to reconstruct the volume. I don't see any way around this, but wanted to confirm with the group.

@dclunie
Copy link
Member

dclunie commented Sep 17, 2016

I guess there are at least four scenarios, assuming parallel
slices:

  1. regularly spaced slices in single traversal of 3D volume
  2. regularly spaced slices in multiple traversals of 3D volume (3+D)
  3. a single slice
  4. multiple slices not regularly spaced (e.g., sparsely sampled)

For 1 and 2, spacing should be computed from the (always
present) Image Position (Patient); if Spacing Between Slices
is present it will be in the Shared functional groups (or
in the Per-Frame and the same value for all frames, though
it is not supposed to be there when it has the same value).

But since Spacing Between Slices is Type 3 (optional) why
even look at it (except perhaps to warn if it is inconsistent
with what is computed from Image Position (Patient)?

Spacing Between Slices is a convenience attribute, useful for
example, for the purpose of signaling that all slices are equally
spaced (if it occurs in the Shared functional group sequence),
but it cannot always be trusted, based on past experience.

Slice Thickness, if present, is irrelevant. It should never
be used in cases 1 and 2 (volumes) as a substitute for the
spacing between slices (computed or explicitly encoded), since
its only bearing on the geometry of adjacent slices is to
indicate if there is overlap or are gaps present (or in the
case of superimposition on images in the same frame of reference,
such as those from which the SEG was derived, to indicate the
coverage of the SEG, i.e., the thickness that was segmented).

The comment in the code at:

https://github.com/QIICR/dcmqi/blob/master/include/ConverterBase.h#L226

describes this ... and (appropriately) does not use thickness.

For 3, a single frame, since Spacing Between Slices is Type 3
(optional), it would be reasonable to omit it when writing and
other senders may do so, but in our case it may be useful if you
need to determine the extent of a single frame as a 3D volume,
I suppose; alternatively, the spatial extent of a single frame
slice is possibly its thickness, or perhaps it is the interval
of the source set but only one slice was segmented (i.e., you
could consult the source set). See also:

http://dclunie.blogspot.com.au/2013/10/how-thick-am-i-sad-story-of-lonely-slice.html

For the single frame case, CP1426 is important to us for Pixel
Spacing, Image Position (Patient) and Image Orientation (Patient),
but its effect on Slice Thickness is not really relevant if we are
going to ignore it on receipt anyway.

Note that there is no reason to treat Slice Thickness differently
on writing single frames, since even single slices have thickness
(just not spacing).

On 9/16/16 3:14 PM, Andrey Fedorov wrote:

What I am saying is that we just cannot compute spacing from
the slice positions, and thus we should remove any use of computed
spacing.

I assume that you mean that you cannot compute spacing when there
is only a single slice, which is true (unless you consult the
referenced source images that may have spacing).

If SEG doesn't have SliceThickness or SpacingBetweenSlices, we should
probably fail with the error that there is no sufficient information
to reconstruct the volume

I assume that you are saying this only for single frame slices, which
is reasonable, since for non-sparsely regularly sampled multiple frames
you should always compute the spacing, right?

In:

https://github.com/QIICR/dcmqi/blob/master/libsrc/ImageSEGConverter.cpp#L442-L468

you call computeVolumeExtent, but I couldn't find where this was
defined or see what it actually does.

Case 4, multiple slices that are not regularly spaced, are an
interesting challenge. If one assumes that they represent
a sparse sample of a regularly sample volume, e.g., empty slices
were omitted, then perhaps Spacing Between Slices could be
present, and the positions of all those slices that were present
would fall on multiples of that spacing value, and one could
create a volume that way and fill in a bunch of empty slices
perhaps. But if Spacing Between Slices was absent, or if the
positions did not fall on multiples of the spacing value, then
it would be hard to know what the slices represented, in terms
of sampling pattern, if it matters.

Obviously, there are other reasons a set of slices could have
irregular intervals.

All this begs the question of what you are using the "spacing" "for"
anyway ... isn't where the slices are located what matters, not
how they happen to be spaced? Or does the recipient need the
slices to be equally spaced to constitute a regularly sampled
"volume" for some later step in the pipeline, and you want to
exclude data sets that are not such a "volume" for some reason?

As for the standard ...

The requirements for the SEG IOD were intended to allow for all
of the spatial information to be absent if the segmented images
were not in some 3D coordinate system, e.g., a chest x-ray rather
than a chest CT, in which case the relationship to the segmented
images is explicitly specified with a UID reference rather than
a shared coordinate system. They are probably unnecessarily complex
and potentially inconsistent, between the tabulated conditions and
the prose of A.51.5.1 at the functional group level:

http://dicom.nema.org/medical/dicom/current/output/chtml/part03/sect_A.51.5.html

and the conditions within the macro when it has been included:

http://dicom.nema.org/medical/dicom/current/output/chtml/part03/sect_C.7.6.16.2.html#sect_C.7.6.16.2.1

In our case, since we are always sending Frame of Reference UID
(only dealing with cross-sectional images), the position, orientation,
and measures macros are required per A.51.5.1 and should always be
expected in received SEG instances (and if absent the SEG should be
rejected).

David

On 9/16/16 3:14 PM, Andrey Fedorov wrote:

@pieper for the context, here is the code that handles parsing the "declared" spacing. SliceThickness is 1C for SEG, but only after this CP, and so one can have an "imperfectly" valid SEG object that will not have this information...

Here is the code that makes the decision which spacing to use - declared or computed: https://github.com/QIICR/dcmqi/blob/master/libsrc/ImageSEGConverter.cpp#L442-L468

What I am saying is that we just cannot compute spacing from the slice positions, and thus we should remove any use of computed spacing. If SEG doesn't have SliceThickness or SpacingBetweenSlices, we should probably fail with the error that there is no sufficient information to reconstruct the volume. I don't see any way around this, but wanted to confirm with the group.

On 9/16/16 2:59 PM, Steve Pieper wrote:
I think the Slice Thickness should be a mandatory requirement for a valid
segmentation object and Image Position should be mandatory for each frame.
That way everything is well defined and there is no need for the concept of
Slice Spacing. If I recall the standard correctly I realize this isn't the
way it is in the standard but we could still generate warnings from dcmqi
if there is any chance for ambiguity.

It's really just not right to leave this to chance when we are talking
about a segmentation boundary that could be used as a resection or therapy
delivery zone boundary.

On Fri, Sep 16, 2016 at 2:50 PM, Andrey Fedorov notifications@github.com
wrote:

Note for the discussion: this should be improved further. Spacing should
be calculated for consecutive frames of the individual segment. Right now,
all frames are considered indiscriminately. Question is whether it should
be computed at all, considering we do not have any information about
whether the 2 frames are adjacent or not, so perhaps we should always rely
on the declared spacing, and not even try to compute it?

On 9/16/16 2:52 PM, Andrey Fedorov wrote:>

so perhaps we should always rely on the declared spacing, and not even try to compute it?

I should have used have no choice but instead of should. At least I don't see any choice. Assumption of consecutive frames that is valid for scalar volumes does not apply to segmentations.

@fedorov
Copy link
Member Author

fedorov commented Sep 17, 2016

@dclunie the discussion is motivated my the scenarios 3 and 4 from your list.

While receiving SEG, in absence of the direct correspondence between SEG frames and segmented modality frames (when they are available), we cannot decide which of the scenarios we deal with in the general case, and that is why I raised the concern that we cannot calculate slice thickness, in the general case.

If you have SEG frames regularly sampled, how can you assure that, for example, it is not every other frame of the original modality that has been segmented? (in the general case, of course)

To your question

All this begs the question of what you are using the "spacing" "for"
anyway ... isn't where the slices are located what matters, not
how they happen to be spaced?

In the Slicer world, everything is a volume, even if it is a single slice. We always deal with volume reconstructions.

In the quantitative imaging use case, if we have a segmentation and we don't know slice spacing - how can we, for example, compute ROI volume?

@pieper
Copy link
Member

pieper commented Sep 17, 2016

For me the overriding consideration is: a unambiguous definition of the
segmentation value at any point in space (and time).

If the parameter to dcmqi aren't enough to create an unambiguous SEG then
it should generate an error. If the user insists on creating something
ambiguous then we could provide a flag like --force.

On Sat, Sep 17, 2016 at 7:26 AM, Andrey Fedorov notifications@github.com
wrote:

@dclunie https://github.com/dclunie the discussion is motivated my the
scenarios 3 and 4 from your list.

While receiving SEG, in absence of the direct correspondence between SEG
frames and segmented modality frames (when they are available), we cannot
decide which of the scenarios we deal with in the general case, and that is
why I raised the concern that we cannot calculate slice thickness, in the
general case.

If you have SEG frames regularly sampled, how can you assure that, for
example, it is not every other frame of the original modality that has been
segmented? (in the general case, of course)

To your question

All this begs the question of what you are using the "spacing" "for"
anyway ... isn't where the slices are located what matters, not
how they happen to be spaced?

In the Slicer world, everything is a volume, even if it is a single slice.
We always deal with volume reconstructions.

In the quantitative imaging use case, if we have a segmentation and we
don't know slice spacing - how can we, for example, compute ROI volume?


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#89 (comment), or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAHsfck4i4X_Z-hBe90vSc9kjBRPQAbQks5qq85jgaJpZM4J_PIV
.

@dclunie
Copy link
Member

dclunie commented Sep 18, 2016

So I guess that for each scenario we need to define:

(a) what the right thing to encode is

(b) what Slicer will do with such a SEG object when received

(c) how the user (caller) of dcmqi will assure that it is encoded
that way

This thread is mostly about (c), right (if I understand what Steve
is emphasizing), but is certainly predicated on first defining (a)?

If we assume that Spacing Between Slices is always to be sent in
the Shared functional group (even if a single slice), then one
could say that:

  • for cases 1 and 2 (3D and 3+D regularly sampled)
    it can be computed, and if supplied by the user and different, is
    an error
  • for case 3 (single slice) it must be supplied by the caller since
    it cannot be computed (and failing to supply it is an error)
  • for case 4 (multiple slices but irregular spacing) it is going to
    be encoded as shared, there is the possibility that it might be "wrong",
    unless you want to provide a means of supplying it on a per-frame basis

As for Slice Thickness, it is required, and cannot be computed
(unless you are willing to make the assumption that it should be
set to the value of computed Spacing Between Slices if not
overridden), and can be supplied by the user if intended to be
encoded in the Shared functional group (unless you also want
to provide that on a per-frame basis too).

Andrey raised the question of regular, but sparse sampling
relative to the original, e.g., every other slice of the
original segmented, in which case it would appear as case
1 or 2 when computing the Spacing Between Slices, and these
would be encoded correctly, but it would be incorrect to
assume that Slice Thickness was equal to computed Spacing
Between Slices (i.e., there is always a gap). But, as
discussed, Slice Thickness could be overridden in such
cases by the user of dcmqi.

Note that in this variant (sparser sampling that the original),
the volume of an ROI that spans multiple adjacent segmented
frames is still the volume based on spacing (not thickness),
since one "interpolates" across the encoded segmented frames,
right?

The "happy" path (>90% of use cases I suspect) is a single 3D
volume regularly sampled with the same spacing as the original
segmented images, and with thickness equal to spacing, is it
not?

David

On 9/17/16 10:18 AM, Steve Pieper wrote:

For me the overriding consideration is: a unambiguous definition of the
segmentation value at any point in space (and time).

If the parameter to dcmqi aren't enough to create an unambiguous SEG then
it should generate an error. If the user insists on creating something
ambiguous then we could provide a flag like --force.

On Sat, Sep 17, 2016 at 7:26 AM, Andrey Fedorov notifications@github.com
wrote:

@dclunie https://github.com/dclunie the discussion is motivated my the
scenarios 3 and 4 from your list.

While receiving SEG, in absence of the direct correspondence between SEG
frames and segmented modality frames (when they are available), we cannot
decide which of the scenarios we deal with in the general case, and that is
why I raised the concern that we cannot calculate slice thickness, in the
general case.

If you have SEG frames regularly sampled, how can you assure that, for
example, it is not every other frame of the original modality that has been
segmented? (in the general case, of course)

To your question

All this begs the question of what you are using the "spacing" "for"
anyway ... isn't where the slices are located what matters, not
how they happen to be spaced?

In the Slicer world, everything is a volume, even if it is a single slice.
We always deal with volume reconstructions.

In the quantitative imaging use case, if we have a segmentation and we
don't know slice spacing - how can we, for example, compute ROI volume?

@fedorov
Copy link
Member Author

fedorov commented Sep 19, 2016

Let's discuss at the next hangout when you are back David.

@fedorov
Copy link
Member Author

fedorov commented Oct 14, 2016

Consensus was reached that in the cases where neither SliceThickness, nor SpacingBetweenSlices are available, the conversion of the SEG into a volume should fail.

As discussed in QIICR#89, in the general case, we cannot rely on the slice thickness
computed from the positions of the individual frames, since frames may not be
contiguous. When source image references are available, and the source images
are also available, additional checks could be possible, but not in dcmqi.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants