cornerstonejs / cornerstone3D

Cornerstone is a set of JavaScript libraries that can be used to build web-based medical imaging applications. It provides a framework to build radiology applications such as the OHIF Viewer.
https://cornerstonejs.org
MIT License
538 stars 278 forks source link

Image ordering is getting reversed in Stack viewport after Streaming Volume loading using WADO-URI #399

Open idemopacs opened 1 year ago

idemopacs commented 1 year ago

Image ordering is getting reversed in Stack viewport after Streaming Volume loading using WADO-URI

This is happening after PR 354 https://github.com/cornerstonejs/cornerstone3D-beta/pull/354

Please see the attached example , I have changed example 'stackToVolumeWithAnnotations' from Tools library. I am using latest version

stackToVolumeWithAnnotations.zip

idemopacs commented 1 year ago

@sedghi , is there any solution for this issue ?

sedghi commented 1 year ago

Hey, can you explain what is happening? and what is your use case? Steps to reproduce?

idemopacs commented 1 year ago

@sedghi @Ouwen

Overview : We load images in stack viewer while doing this the order of images is correctly rendered but after we create MPR in same element & switch back to stack view again the order of image is getting reveresed from original. We are using latest version of the library.

Here are step to reproduce it

Step 1: Create image ID array with WADO URI
const imageIds = wadoURICreateImageIds();

Step 2: Render the images in Satck viewport

const viewportInput = {
    viewportId,
    type: ViewportType.STACK,
    element,
    defaultOptions: {
      background: <Types.Point3>[0.4, 0, 0.4],
    },
  };

  renderingEngine.enableElement(viewportInput);  
  toolGroup.addViewport(viewportId, renderingEngineId);
  const viewport = <Types.IStackViewport>(
    renderingEngine.getViewport(viewportId)
  );
  const stack = imageIds;
  viewport.setStack(stack, 0);

   viewport.render(); 

Step 3: On clicking of button, we are loading MPR. SO for this we are switching STACK viewport to ORTHOGRAPHIC viewport

async function _convertStackToVolumeViewport(
  renderingEngine: Types.IRenderingEngine,
  viewport: Types.IStackViewport,
  toolGroup: cstTypes.IToolGroup
): Promise<void> {

  const volumeName = 'CT_VOLUME_ID';
  const volumeLoaderScheme = 'cornerstoneStreamingImageVolume';
 const volumeId = `${volumeLoaderScheme}:${volumeName}`; 
  const { id, element } = viewport;

  let imageIds = viewport.getImageIds();
  const viewportInputArray = [
    {
      viewportId: id,
      type: ViewportType.ORTHOGRAPHIC,
      element,
          defaultOptions: {
              orientation: Enums.OrientationAxis.SAGITTAL,
        background: <Types.Point3>[0.2, 0.4, 0.2],
      },
    },
  ];

  renderingEngine.setViewports(viewportInputArray);  
  toolGroup.addViewport(id, renderingEngine.id);

  const volume = await volumeLoader.createAndCacheVolume(volumeId, {
    imageIds,
  });

  volume.load();

  setVolumesForViewports(renderingEngine, [{ volumeId }], [id]);

  // Render the image
  renderingEngine.renderViewports([id]);
}

Step 4: On click of button we are switching back to STACK viewport from ORTHOGRAPHIC viewport

function _convertVolumeToStackViewport(
  renderingEngine: Types.IRenderingEngine,
  viewport: Types.IVolumeViewport,
    toolGroup: cstTypes.IToolGroup,
    imageIds,
): void {
  const { id, element } = viewport;

  // Create a stack viewport
  const viewportInput = {
    viewportId: id,
    type: ViewportType.STACK,
    element,
    defaultOptions: {
      background: <Types.Point3>[0.4, 0, 0.4],
    },
  };

  renderingEngine.enableElement(viewportInput);

  toolGroup.addViewport(id, renderingEngine.id);
  const stackViewport = <Types.IStackViewport>renderingEngine.getViewport(id);

  const actorEntry = viewport.getDefaultActor();
  const { uid: volumeId } = actorEntry;
  const volume = cache.getVolume(volumeId) as StreamingImageVolume;

  //const imageIds = volume.imageIds;

    const stack = imageIds;

  stackViewport.setStack(stack, 0);

  // Render the image
  viewport.render();
}

On switching back to stack view from MPR view we tried doing it by both ways either using image ids from volume viewport or using original imageIds variable In stack viewer the order of image rendered is reverse of original

We have also tried reversing the image id before rendering viewport const stack = imageIds.reverse();

Thanks

sedghi commented 1 year ago

This will help a lot, thanks for your explanation

idemopacs commented 1 year ago

@sedghi
Any update on this because latest version still has same issue.

sedghi commented 1 year ago

not yet

Ouwen commented 1 year ago

@idemopacs I believe the issue is that by default the volume is sorted by the patient position tag independent from imageId order. The solution would likely be to add a parameter to the volume to sort based on some orientation. Related: https://itk.org/Wiki/Proposals:Orientation

sedghi commented 1 year ago

I guess the problem is in this function convertToCornerstoneImage.

tineke01 commented 1 year ago

I ran into the same problem when I converted volume and stack and 'getCurrentImageIdIndex' returned a different value.

sedghi commented 1 year ago

so i looked into this, doesn't relate to the PR mentioned in the description of the first issue. It was always there by design. I fixed a bug for caching though here https://github.com/cornerstonejs/cornerstone3D-beta/pull/567

So basically the question is where do we set the origin for a volume and by convention that is the [0,0,0] pixel in the world space, so since we sort image ids when we want to create a volume here then if we are going back to stack we should reverse the stack since now the order has changed.

Hope this helps