Scalar range not updating for live stream volume

I am live streaming a volume over OpenIGTLink into Slicer (latest preview) using the SlicerOpenIGTLink (latest) extension. I’m noticing that the scalar range for the volume node is not updating for new image data. The below image is what the volumes module displays after the first frame is received. Then when the second frame is received it does not update. Maybe this is an issue with code in the SlicerOpenIGTLink extension? This is a very very low frame rate live stream from a camera device. For example it would be a 5 second exposure and then a 10 second exposure capture where the scalar max for the second would be approximately double the first.

image

My Current Workaround:
I can force update it with a hacky workaround by doing:

volume_array = slicer.util.arrayFromVolume(live_stream_node)
slicer.util.updateVolumeFromArray(live_stream_node, volume_array)

After update:
image

cc: @lassoan @Sunderlandkyl

Updating the scalar range is an expensive operation, so it should be only performed when the Volume Information section is visible (volumes module is active and information section is not collapsed). But if it is visible then it should be updated.

@Sunderlandkyl could you have a look? VTK caches scalar range, so maybe a Modified() call is missed at some level, and that’s why VTK does not recompute the value it but returns the last one.

1 Like

What I’m looking to do is set the Lower threshold based on some percentage of the current max scalar value in the image. So even if the Volumes modules was not visible I would want to do something like the following.

_, max_value = live_stream_node.GetImageData().GetScalarRange()
min_value = max_value * 0.04
live_stream_node.GetDisplayNode().SetThreshold(min_value, max_value)

However this is not working as GetScalarRange is still returning the range of the image data from the first frame instead of the image data of the current frame. The threshold range is limited to the scalar range, so when I attempt to set the upper threshold for the second frame which is higher than the first frame, the max threshold gets rejected as the value is outside the range.

This confirms that the issue is that the scalar array is not marked as modified.

Some additional information from debugging:
What also seems to update the scalar range is if the image dimensions change. So if my 1024x1024 live stream image becomes a 512x512 image it will force the scalar range to be updated.

This commit in OpenIGTLinkIO should cause the scalar range to update: ENH: Mark received image data scalars as modified · IGSIO/OpenIGTLinkIO@32feaaa · GitHub

1 Like