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] scaled PT image with lut defined on metadata return wrong Volume VOI #1806

Open
ghetolay opened this issue Feb 4, 2025 · 11 comments
Open
Assignees

Comments

@ghetolay
Copy link

ghetolay commented Feb 4, 2025

Describe the Bug

I'm not sure at 100% that this is a bug as I'm not sure about the standard for this.
But I got a PT serie where images were scaled AND a windowWidth and a WindowCenter were defined. Except those values are defined for raw pixel not scaled ones.

This result in a VOI/Lut totally wrong, because pixels are scaled and VOI values are based on raw pixels value.

Steps to Reproduce

Load a PT image with scaling and VOI defined on metadata.

The current behavior

Wrong VOI is returned

The expected behavior

I'm not so sure about what should be done.
It seems to me that in the function below we should check if volume is scaled first and return according VOI no matter what.

async function setDefaultVolumeVOI(
  volumeActor: VolumeActor,
  imageVolume: IImageVolume
): Promise<void> {
  let voi = getVOIFromMetadata(imageVolume);

  if (!voi && imageVolume.imageIds.length) {
    voi = await getVOIFromMiddleSliceMinMax(imageVolume);
    voi = handlePreScaledVolume(imageVolume, voi);                 <==== // do this as the first thing in the function
  }

But maybe correct behavior is to scale the metadata VOI somehow or even something else I don't know.

OS

Windows 11

Node version

v22.11.0

Browser

any

@sedghi
Copy link
Member

sedghi commented Feb 4, 2025

Do you have a data anonymized to share? Screenshots showing what is wrong?

@ghetolay
Copy link
Author

ghetolay commented Feb 4, 2025

Here is the images, I can't really get a screenshot but anyway it's just all black.
As you can see on the images Window Center and Window Width are way above 2000 since the image is scaled pixel values are very small (somewhere in the range of [0, 10] mostly). So such an applied lut renders everything to black.

pet_with_windowing.zip

Copy link
Member

sedghi commented Feb 4, 2025

OHIF handles it correctly https://viewer-dev.ohif.org/localbasic hmmm

Copy link
Member

sedghi commented Feb 4, 2025

Also looks good here too https://www.cornerstonejs.org/live-examples/local.html

@ghetolay
Copy link
Author

ghetolay commented Feb 4, 2025

I'm not familiar with OHIF, I'm unable to set a volume got it.
And second link is just displaying 1 image.

I checked cornerstone examples but didn't find a volume example where you can drop your own images.

@ghetolay
Copy link
Author

ghetolay commented Feb 4, 2025

seems like OHIf is not scaling the volume, probe shows me raw values instead of SUV

@sedghi
Copy link
Member

sedghi commented Feb 4, 2025

i guess it is not corrected PT then. Which software shows SUV for it?

@ghetolay
Copy link
Author

ghetolay commented Feb 5, 2025

I don't know which one are being used, but I would say any standard (non-web) ones.
But you can see on metadata that it is a corrected PT

Image

@ghetolay
Copy link
Author

ghetolay commented Feb 5, 2025

Found out weasis is rendering it correctly with scaled values

@sedghi
Copy link
Member

sedghi commented Feb 5, 2025

We use this library , so seems like the lib thinks the required metadata is not provided, or we have limited support for suv of this type

@ghetolay
Copy link
Author

ghetolay commented Feb 5, 2025

I don't know why OHIF is not showing the scaled volume and I think we're diverging from original issue.

Issue is about setDefaultVolumeVOI() and how it choose what to return.
In a scenario where imageVolume is scaled (doesn't matter why or how) AND imageVolume has VOI metadata, the decision is to return the VOI from metadata.
I think this is wrong because VOI specified on metadata are based on raw pixel values and not scaled one. But you may think this is correct behavior and close this.

Also now that I took another pick into the code :

if (!voi && imageVolume.imageIds.length) {
    voi = await getVOIFromMiddleSliceMinMax(imageVolume);
    voi = handlePreScaledVolume(imageVolume, voi);
  }

handlePreScaledVolume() will discard the voi computed from getVOIFromMiddleSliceMinMax() on scaled volume.
Then it seems like we should do handlePreScaledVolume() first and fallback to getVOIFromMiddleSliceMinMax().
Avoiding going into the trouble of computing a voi from minmax just to discard it right after.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants