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] #1617

Open
xiaoxiao5 opened this issue Nov 26, 2024 · 2 comments
Open

[Bug] #1617

xiaoxiao5 opened this issue Nov 26, 2024 · 2 comments

Comments

@xiaoxiao5
Copy link

Describe the Bug

1732611369922.mp4

Selection status error

Steps to Reproduce

image
Click on the button imageID1 setActiveSegmentIndex (id, 1) into effect activeSegmentOutlineWidthDelta state at this time, Click imageID10 button again setActiveSegmentIndex (id, 10) activeSegmentOutlineWidthDelta is invalid at this time

The current behavior

The current page has a variety of colors, switch setActiveSegmentIndex effective, but after turning the page, the error (this time only the value of 1 is effective, other values are invalid), after turning the page setActiveSegmentIndex set to the current page SegmentIndex set invalid

The expected behavior

SetActiveSegmentIndex is set to 1, at this point 1 outlineWidth equals outlineWidth + activeSegmentOutlineWidthDelta, setActiveSegmentIndex set to 10, At this time of 10 outlineWidth equals outlineWidth + activeSegmentOutlineWidthDelta,

OS

window 11

Node version

19.0.0

Browser

chrome 131.0.6778.86

Copy link
Member

sedghi commented Dec 2, 2024

can you paste the code? or better the example you are trying?

@xiaoxiao5
Copy link
Author

你能粘贴代码吗?或者更好的是你正在尝试的例子?
import type { Types } from '@cornerstonejs/core';
import {
RenderingEngine,
Enums,
setVolumesForViewports,
volumeLoader,
imageLoader,
} from '@cornerstonejs/core';
import * as cornerstone from '@cornerstonejs/core';
import {
initDemo,
createImageIdsAndCacheMetaData,
setTitleAndDescription,
addSliderToToolbar,
addButtonToToolbar,
} from '../../../../utils/demo/helpers';
import { fillVolumeLabelmapWithMockData, fillStackSegmentationWithMockData } from '../../../../utils/test/testUtils';
import * as cornerstoneTools from '@cornerstonejs/tools';

// This is for debugging purposes
console.warn(
'Click on index.ts to open source code for this example --------->'
);

const {
ToolGroupManager,
Enums: csToolsEnums,
segmentation,
StackScrollTool,
} = cornerstoneTools;
const { MouseBindings, KeyboardBindings } = csToolsEnums;

const { ViewportType } = Enums;

// Define a unique id for the volume
const volumeName = 'CT_VOLUME_ID'; // Id of the volume less loader prefix
const volumeLoaderScheme = 'cornerstoneStreamingImageVolume'; // Loader id which defines which volume loader to use
const volumeId = ${volumeLoaderScheme}:${volumeName}; // VolumeId with loader id + volume id
const segmentationId1 = 'SEGMENTATION_ID_1';
const toolGroupId = 'MY_ TOOL_GROUP_ID';
const renderingEngineId = 'myRenderingEngine';
const viewportId = 'CT_AXIAL_STACK';
let viewport, InitImageIds, segmentationImageIds;

// ======== Set up page ======== //
setTitleAndDescription(
'Labelmap Segment specific Configuration',
'Here we demonstrate how to change the segment specific segmentation configuration'
);

const size = '500px';
const content = document.getElementById('content');
const element = document.createElement('div');

element.style.width = size;
element.style.height = size;

content.appendChild(element);
// ============================= //

let segment1FillAlpha = 0.9;
let segment2FillAlpha = 0.9;

addSliderToToolbar({
title: 'fill alpha for Segment 1',
range: [0, 100],
defaultValue: 90,
onSelectedValueChange: (value) => {
segment1FillAlpha = Number(value) / 100;

segmentation.config.style.setStyle(
  {
    segmentationId: segmentationId1,
    type: csToolsEnums.SegmentationRepresentations.Labelmap,
    segmentIndex: 1,
  },
  {
    // outlineWidth: 10,
    fillAlpha: segment1FillAlpha,
    // renderFill: false
  }
);

},
});

addSliderToToolbar({
title: 'fill alpha for Segment 2',
range: [0, 100],
defaultValue: 90,
onSelectedValueChange: (value) => {
segment2FillAlpha = Number(value) / 100;

segmentation.config.style.setStyle(
  {
    segmentationId: segmentationId1,
    type: csToolsEnums.SegmentationRepresentations.Labelmap,
    segmentIndex: 2,
  },
  {
    // outlineWidth: 1,
    fillAlpha: segment2FillAlpha,
    // renderFill: true
  }
);

},
});
addButtonToToolbar({
title: 'imageId-1',
onClick: async () => {
// segmentation.segmentIndex.setActiveSegmentIndex(segmentationId1, 1)
const { jumpToSlice } = cornerstone.utilities;
jumpToSlice(element, {
imageIndex: 1,
});
const { metaData, cache } = cornerstone;
const { rows, columns } = metaData.get('imagePlaneModule', InitImageIds[1]);
const dimensions = [columns, rows, InitImageIds.length];

const center = [dimensions[0] / 2, dimensions[1] / 2, dimensions[2] / 2];
let centerOffset = [0, 0, 0],
  innerValue = 1, outerValue = 2;

center[0] += centerOffset[0];
center[1] += centerOffset[1];
center[2] += centerOffset[2];

const outerRadius = 64;
const innerRadius = 32;
let voxelIndex = 0;
let z = 1;
const image = segmentationImageIds[z];
// console.log(image, segmentationImageIds[z])
const voxelManager =
  image.voxelManager ||
  cornerstone.utilities.VoxelManager.createScalarVolumeVoxelManager({
    dimensions: [columns, rows, 1],
    scalarData: image.voxelManager.getCompleteScalarDataArray(),
  });
for (let y = 0; y < dimensions[1]; y++) {
  for (let x = 0; x < dimensions[0]; x++) {
    const distanceFromCenter = Math.sqrt(
      (x - center[0]) * (x - center[0]) +
      (y - center[1]) * (y - center[1]) +
      (z - center[2]) * (z - center[2])
    );
    if (distanceFromCenter < innerRadius) {
      voxelManager.setAtIndex(voxelIndex, innerValue);
    } else if (distanceFromCenter < outerRadius) {
      voxelManager.setAtIndex(voxelIndex, outerValue);
    }
    voxelIndex++;
  }
}

},
});
addButtonToToolbar({
title: 'imageId-10',
onClick: async () => {
segmentation.segmentIndex.setActiveSegmentIndex(segmentationId1, 10)
const { jumpToSlice } = cornerstone.utilities;
jumpToSlice(element, {
imageIndex: 10,
});
const { metaData, cache } = cornerstone;
const { rows, columns } = metaData.get('imagePlaneModule', InitImageIds[10]);
const dimensions = [columns, rows, InitImageIds.length];

const center = [dimensions[0] / 2, dimensions[1] / 2, dimensions[2] / 2];
let centerOffset = [0, 0, 0],
  innerValue = 10;

center[0] += centerOffset[0];
center[1] += centerOffset[1];
center[2] += centerOffset[2];

const innerRadius = 64;
let voxelIndex = 0;
let z = 10;
const image = segmentationImageIds[z];
// console.log(image, segmentationImageIds[z])
const voxelManager =
  image.voxelManager ||
  cornerstone.utilities.VoxelManager.createScalarVolumeVoxelManager({
    dimensions: [columns, rows, 1],
    scalarData: image.voxelManager.getCompleteScalarDataArray(),
  });
for (let y = 0; y < dimensions[1]; y++) {
  for (let x = 0; x < dimensions[0]; x++) {
    const distanceFromCenter = Math.sqrt(
      (x - center[0]) * (x - center[0]) +
      (y - center[1]) * (y - center[1]) +
      (z - center[2]) * (z - center[2])
    );
    if (distanceFromCenter < innerRadius) {
      voxelManager.setAtIndex(voxelIndex, innerValue);
    }
    voxelIndex++;
  }
}

},
});
// ============================= //

async function addSegmentationsToState(imageIds) {
// Create a segmentation of the same resolution as the source data
// const segmentationVolume1 =
// await volumeLoader.createAndCacheDerivedLabelmapVolume(volumeId, {
// volumeId: segmentationId1,
// });

// // Add the segmentations to state
// segmentation.addSegmentations([
// {
// segmentationId: segmentationId1,
// representation: {
// // The type of segmentation
// type: csToolsEnums.SegmentationRepresentations.Labelmap,
// // The actual segmentation data, in the case of labelmap this is a
// // reference to the source volume of the segmentation.
// data: {
// volumeId: segmentationId1,
// },
// },
// },
// ]);

// // Add some data to the segmentations
// fillVolumeLabelmapWithMockData({
// volumeId: segmentationVolume1.volumeId,
// cornerstone,
// });

segmentationImageIds = await imageLoader.createAndCacheDerivedLabelmapImages(imageIds, {
getDerivedImageId: (id) => segmentation_${id},
});
segmentation.addSegmentations([
{
segmentationId: segmentationId1,
representation: {
type: csToolsEnums.SegmentationRepresentations.Labelmap,
data: {
imageIds: segmentationImageIds.map((it) => it.imageId),
},
},
}
]);
// fillStackSegmentationWithMockData({
// imageIds,
// segmentationImageIds,
// cornerstone
// })
segmentation.config.style.setStyle(
{
segmentationId: segmentationId1,
type: csToolsEnums.SegmentationRepresentations.Labelmap,
},
{
activeSegmentOutlineWidthDelta: 5,
// outlineWidth: 1,
}
);
}

/**

  • Runs the demo
    */
    async function run() {
    // Init Cornerstone and related libraries
    await initDemo();
    cornerstoneTools.addTool(StackScrollTool);

// Add tools to Cornerstone3D

// Define tool groups to add the segmentation display tool to
const toolGroup = ToolGroupManager.createToolGroup(toolGroupId);
toolGroup.addTool(StackScrollTool.toolName);
toolGroup.setToolActive(StackScrollTool.toolName, {
bindings: [
{
mouseButton: MouseBindings.Wheel,
},
{
mouseButton: MouseBindings.Primary,
},
],
});

// Get Cornerstone imageIds for the source data and fetch metadata into RAM
const imageIds = await createImageIdsAndCacheMetaData({
StudyInstanceUID:
'1.3.6.1.4.1.14519.5.2.1.7009.2403.334240657131972136850343327463',
SeriesInstanceUID:
'1.3.6.1.4.1.14519.5.2.1.7009.2403.226151125820845824875394858561',
wadoRsRoot: 'https://d3t6nz73ql33tx.cloudfront.net/dicomweb',
});

// const smallVolumeImageIds = [imageIds[0], imageIds[1]];
const smallVolumeImageIds = [...imageIds.slice(0, 20)];
InitImageIds = smallVolumeImageIds;

// Define a volume in memory
// const volume = await volumeLoader.createAndCacheVolume(volumeId, {
// imageIds: smallVolumeImageIds,
// });

// Add some segmentations based on the source data volume
await addSegmentationsToState(smallVolumeImageIds);

// Instantiate a rendering engine
const renderingEngine = new RenderingEngine(renderingEngineId);

// Create the viewports
const viewportInput = {
viewportId,
// type: ViewportType.ORTHOGRAPHIC,
type: ViewportType.STACK,
element,
// defaultOptions: {
// orientation: Enums.OrientationAxis.AXIAL,
// background: <Types.Point3>[0.2, 0, 0.2],
// },
};

toolGroup.addViewport(viewportId, renderingEngineId);

// renderingEngine.enableElement(viewportInput);
renderingEngine.setViewports([viewportInput]);
viewport = renderingEngine.getViewport(viewportId);
await viewport.setStack(smallVolumeImageIds, 0);

// Set the volume to load
// volume.load();

// Set volumes on the viewports
// await setVolumesForViewports(renderingEngine, [{ volumeId }], [viewportId]);

// Add the segmentation representations to the viewport
await segmentation.addSegmentationRepresentations(viewportId, [
{
segmentationId: segmentationId1,
type: csToolsEnums.SegmentationRepresentations.Labelmap,
},
]);

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

run();

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

No branches or pull requests

2 participants