Git Product home page Git Product logo

cornerstonejs / cornerstone3d Goto Github PK

View Code? Open in Web Editor NEW
449.0 19.0 241.0 203.21 MB

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.

Home Page: https://cornerstonejs.org

License: MIT License

JavaScript 19.86% TypeScript 78.37% HTML 1.52% CSS 0.22% Shell 0.03%
javascript nci-itcr cornerstone medical-imaging segmentation

cornerstone3d's People

Contributors

baokeyu123 avatar biharck avatar blackman99 avatar celian-abd avatar chafey avatar dannyrb avatar dependabot[bot] avatar galelis avatar ibrahimcsae avatar igoroctaviano avatar jamesapetts avatar jbocce avatar jlopes90 avatar jmhmd avatar kofifus avatar ladeirarodolfo avatar lscoder avatar m00n620 avatar md-prog avatar neilmacphee avatar ouwen avatar pieper avatar punzo avatar richard-viney avatar rodrigobasilio2022 avatar rogerbramon avatar sedghi avatar swederik avatar wayfarer3130 avatar woonchancho avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cornerstone3d's Issues

[Known Issue] Volume Viewport Flip

There is a known issue for fkipping in other acquisition axes.

Reason:
It calculates the flip based on the imageData metadata, which actually should be based on camera

[Known Issue] Modifier keys and Cancellation

Currently you cannot cancel an annotation while holding the modifier key (cancel works fine without modifier keys). So if you have setup a modifier key (shift + left click -> lenghTool), you are able to draw lenghtTool with shift left click but hitting Esc would not cancel its drawing

RenderingEngine.enableElement improvements

If there is an already enabled element, if we use enableElement(viewportEntry) again (drag and drop displaySet in OHIF) it will go through the whole process of disabling, resizing offscreen etc. etc. which is most of the time unnecessary.

We need to have a smarter enableElement that checks if the viewport exists, if yes, check if it is compatible (orientation, type etc.), if yes use the viewport method to like viewport.applyViewportInputOptions just to change the configuration of the viewport (which again most of the time might not be event needed).

VolumeViewport setProperties

Similar to StackViewports which can .setProperties, Volume Viewport should too

currently for stack viewports

viewport.setProperties({ voiRange: ctVoiRange });

But for volume viewports

// Get the volume actor from the viewport
const actor = viewport.getActor(volumeId);

// Set the mapping range of the actor to a range to highlight bones
actor.volumeActor
  .getProperty()
  .getRGBTransferFunction(0)
  .setMappingRange(-1500, 2500);

viewport.render();

no image loader for imageId

I use the imageId for this case,https://www.cornerstonejs.org/live-examples/stackbasic,but I got an error
image
my code:


import styles from './index.less';
import {useEffect} from 'react';
import { RenderingEngine, Enums, init as csRenderInit } from '@cornerstonejs/core';
const LabelPage = () => {
    const initHandle = async () => {
        const imageId = "wadors:https://d1qmxk7r72ysft.cloudfront.net/dicomweb/studies/1.3.6.1.4.1.14519.5.2.1.7009.2403.334240657131972136850343327463/series/1.3.6.1.4.1.14519.5.2.1.7009.2403.226151125820845824875394858561/instances/1.3.6.1.4.1.14519.5.2.1.7009.2403.811199116755887922789178901449/frames/1";
        // const imageId = "wadors:https://tools.cornerstonejs.org/examples/assets/dicom/bellona/chest_lung/1.dcm";
        const element = document.getElementById('content');
        const renderingEngineId = 'myRenderingEngine';
        const viewportId = 'CT_STACK';
        await csRenderInit();
        const renderingEngine = new RenderingEngine(renderingEngineId);
        const { ViewportType } = Enums;
        const viewportInput = {
            viewportId,
            element,
            type: ViewportType.STACK,
            defaultOptions: {
                background: [0, 0, 0]
            }
        };
        renderingEngine.enableElement(viewportInput);
        const viewport = renderingEngine.getViewport(viewportInput.viewportId);
        const stack = [imageId];
        await viewport.setStack(stack);
        viewport.render();
    };
    useEffect(() => {
        initHandle();
    }, []);
    return (
      <div id="content" className={styles.content}>
          <div className={styles.flexBox}>
              <div className={styles.flexItem}></div>
              <div className={styles.flexItem}></div>
              <div className={styles.flexItem}></div>
          </div>
      </div>
    );
};
export default LabelPage;

"@cornerstonejs/core": "^0.13.9",
"@cornerstonejs/streaming-image-volume-loader": "^0.4.9",
"@cornerstonejs/tools": "^0.20.13",
"@kitware/vtk.js": "^25.2.2",
"cornerstone-wado-image-loader": "^4.1.3",
"dcmjs": "^0.24.4",
"dicom-parser": "^1.8.13",
"gl-matrix": "^3.4.3",


Tool State manager fires removed event even though there is no annotation

The api stateManager.removeAnnotation fires removed annotation even when there is no annotation at all.

https://github.com/cornerstonejs/cornerstone3D-beta/blob/main/packages/tools/src/stateManagement/annotation/annotationState.ts#L114

Expected:

  • Removed annotation event should not be fired whenever there is NO annotation at all

Actual

  • Removed annotation even is being fired even if there is no annotation (prior deletion)

Technical inputs:
I would consider two scenarios here:

  1. Not firing event (removed) in case there is no previous annotation
  2. Also not firing event if somehow operation has failed (for both removing and adding)

[Known Issue] Target Buffer Specification for StackViewport

CSWIL has been recently equipped with an option to scale the array given the scaling parameters. It also can accept a targetBuffer to store the pixelData in the specified typedArray constructor name (Float32Array, Uint8Array etc).

Here are the problems:

  1. Memory inefficiency: Right now we are putting every thing regardless of the bitsAllocation into a Float32Array. The reason is scaling, since we are scaling PT series which will end up with float pixelData.

Potential Solution:
CSWIL should have a mechanism to compute the proper typed Array for the given pixelData, intercept, slop. It would be something like:

function getMinMaxAfterScaling(minValue, maxValue, slope, intercept, scalingParam){
  const minValueAfterScale = minValue * slope + intercept 
  const maxValueAfterScale = maxValue * slope + intercept 

  if (scalingParam){
    minValueAfterScale *= scalingParam
    maxValueAfterScale *= scalingParam
  }
}

Then we need a function to reason about the minValueAfterScale (MVAS) and maxValueAfterScale(MXVAS), something like

function getTypedArrayConstructor(MVAS, MXVAS){

  if (MVAS>0 && MXVAS<255 && isInteger(MVAS)) return Uint8Array
  If (MVAS < 0 && MVAS > -128 && MXVAS < 127 && isInteger(MVAS)) return Int8Array
  If (isFloat) return Float32Array
  ...

Notes:

  • Volume Loaders should still specify their targetBuffer since we use SharedArrayBuffer and fill it by pointers.
  • IsInteger and IsFloat should be written in a way that 1.0 be a float, and not integer (maybe we need to take into account the floatness of slope and intercept and scalingParams too?)

Error : Cannot setup 2 different CrossHairTool at the same time

Hello, I was trying to setup 2 Crosshair on different viewports but when I try to activate both at the same time I got the following error :

image

However, when I try to activate only one of them, it works perfectly.
Knowing that I have 2 rows of 3 viewports with an unique RenderingEngineID, viewportIDs and toolgroupID for each row. Both aren't linked.

You can run a simple build here : https://github.com/Pixilib/Dat_Scan_Viewer/tree/crosshairs-sync-minimal
You only need to install cornerstone's packages and to do :
-> cd datscan
-> npm start

And then you can drag and drop the files to load the viewer.

add/remove/modified events for annotations should not include viewportId and renderingEngineId

add/remove/modified events should not have viewportId and renderingEngineId as their event details. There are only one place that we depend on these Ids (at the onAnnotationModifiedListener where we trigger one last render for the viewports to update their text box since the cachedStats has been updated in a throttle).

I went ahead and removed all the unnecessary Ids but the rendering of annotations fails on the non acquisition planes. It appears
that triggerAnnotationForViewportIds is run for each viewports separately (assuming pt/ct layout, and annotating on ctAxial, it runs for ctAxial, ptAxial, fusionAxial separately), but the implemented approach was to trigger all in one, which failed.

Needs more investigation as why.

Potential reasons:

  • async throttling doesn't invalidate other viewports from not running their cachedStats and becomes an infinite loop? @JamesAPetts

Branch to look is here

replaceAll not found

Running examples give error since replaceAll is only supported in node > 15.

return str.replaceAll('\\', '/');
             ^

TypeError: str.replaceAll is not a function

@wayfarer3130 Can you please fix this for node > 12 which is the current dependency of the library?

CrossHair Tool : Cannot access 'center' before initialization

Hello, I've been trying to use the crosshair tool while following the exemple available but I could'nt rotate the views.
When I try to rotate on any axes and move the mouse this error occur :
Screenshot_1
Otherwise all of the others features such as slabThickness are working.

Maybe you got and idea for this problem.

You can see an overview of my crosshair tool :
Screenshot_2

Error „Texture.js: 1054 WebGL: INVALID_VALUE: texImage3D: width, height or depth out of range”

When I try to display a DR image (size 4048x4932) a get the error message ‘Texture.js: 1054 WebGL: INVALID_VALUE: texImage3D: width, height or depth out of range’. I guess this is due to the webgl limit: ‘MAX_3D_TEXTURE_SIZE’, which is 2048 on my system (chrome). Does this mean that it is not possible to display simple DR images with one dimension larger than 2048? Unfortunately, we have many of them. Is it necessary to use a 3D texture for plain DR images?

Cornerstone3d Server and multi-frame image

Which client and server did cornerstone 3d used in their examples? is it dicomweb-client and dicomweb-server ?
dicomweb-server has the same format of APIs for metadata and Frames. We currently face problem in saving multiframe image using following dicomWeb-client code

Code start

from dicomweb_client.api import DICOMwebClient
import pydicom
client = DICOMwebClient(url="http://0.0.0.0:5985")
filename1 = "dcmFilename.dcm"
dataset1 = pydicom.dcmread(filename1)
data=client.store_instances(datasets=[dataset1])

Code end. This one is not storing frames of multiframe image

If it is the Orthanc then is it customised? As Orthanc frame API have different format i.e.
(https://demo.orthanc-server.com/instances/{id}/frames/{frame})
But cornerstone 3d is using
https://demo.orthanc-server.com/studies/{{studyId}}/series/{{seriesId}}/instances/{{id}}/frames/{frame}

Cannot install from NPM due to conflicting peer dependencies

Maybe I'm doing something wrong, but I'm unable to install the three main packages together (core, tools, streaming-image-volume-loader) because there are peer dependency conflicts.

I'm attempting to run (with none of them currently installed or in package.json) using the latest NPM (8.7.0) and Node.js (17.9.0):

npm install --save @cornerstonejs/streaming-image-volume-loader @cornerstonejs/core @cornerstonejs/tools

Results in something like this:

npm ERR! code ERESOLVE
npm ERR! ERESOLVE could not resolve
npm ERR!
npm ERR! While resolving: [email protected]
npm ERR! Found: @cornerstonejs/[email protected]
npm ERR! node_modules/@cornerstonejs/core
npm ERR!   @cornerstonejs/core@"*" from the root project
npm ERR!   peer @cornerstonejs/core@"^0.4.3" from @cornerstonejs/[email protected]
npm ERR!   node_modules/@cornerstonejs/streaming-image-volume-loader
npm ERR!     @cornerstonejs/streaming-image-volume-loader@"*" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! @cornerstonejs/tools@"*" from the root project
npm ERR!
npm ERR! Conflicting peer dependency: @cornerstonejs/[email protected]
npm ERR! node_modules/@cornerstonejs/core
npm ERR!   peer @cornerstonejs/core@"^0.3.0" from @cornerstonejs/[email protected]
npm ERR!   node_modules/@cornerstonejs/tools
npm ERR!     @cornerstonejs/tools@"*" from the root project
npm ERR!
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
npm ERR!
npm ERR! See C:\Users\MyUser\AppData\Local\npm-cache\eresolve-report.txt for a full report.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\MyUser\AppData\Local\npm-cache\_logs\2022-04-19T15_15_55_145Z-debug-0.log

I'm not sure why, but tools and streaming both have devDependencies and peerDependencies that are incompatible with each other, and with the other libraries.

I can get core and tools to install, but not streaming-image-volume with them. Or, if I try just streaming-image-volume, I can't get 0.2.19 (latest) to install at all, but I can get 0.2.18, but then I can't get tools to install with it.

Edit: Just to note, if I use --legacy-peer-deps, I am able to install them, though having to use that flag is less than ideal (and if it is required, it should be mentioned in the documentation).

[issue] Typescript type mappings

I've noticed that cornerstoneStreamingImageVolumeLoader types are not compatible with register methods if you try to register this volume loader

  volumeLoader.registerUnknownVolumeLoader(
    cornerstoneStreamingImageVolumeLoader
  );
TS2345: Argument of type '(volumeId: string, options: { imageIds: string[]; }) => IVolumeLoader' is not assignable to parameter of type 'VolumeLoaderFn'.
   Types of parameters 'options' and 'options' are incompatible.
        Type 'Record<string, any> | undefined' is not assignable to type '{ imageIds: string[]; }'.
               Type 'undefined' is not assignable to type '{ imageIds: string[]; }'.

Even if the type is forced ( as VolumeLoaderFn) there is another error:

TS2352: Conversion of type '(volumeId: string, options: { imageIds: string[]; }) => IVolumeLoader' to type 'VolumeLoaderFn' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.   
  Types of parameters 'options' and 'options' are incompatible.
     Type 'Record<string, any> | undefined' is not comparable to type '{ imageIds: string[]; }'. 
           Property 'imageIds' is missing in type 'Record<string, any>' but required in type '{ imageIds: string[]; }'. 

This is caused by the definition of VolumeLoaderFn and cornerstoneStreamingImageVolumeLoader. The first one is defined as:

type VolumeLoaderFn = (
  volumeId: string,
  options?: Record<string, any>
)

where the second one is:

function cornerstoneStreamingImageVolumeLoader(
  volumeId: string,
  options: {
    imageIds: string[];
  }
)

Those two are not compatible with each other. First of all Record<string, any> is not compatible with named object because imageIds has to be mapped into a string like

options: {
    [imageIds as string]: string[];
  }

The second one is about optional options property. You should either force that property to be optional in both cases and check if it's not undefined inside cornerstoneStreamingImageVolumeLoader.ts or just assign the default value in the function definition

function cornerstoneStreamingImageVolumeLoader(
  volumeId: string,
  options: {
    imageIds: string[];
  } = { imageIds: [] }
)

Inappropriate intimacy between AnnotationManger and Each Annotation as far as decoration instance is concerned

Decorating the tool annotation at AnnotationManager level causes an inappropriate intimacy between both.
See here:
https://github.com/cornerstonejs/cornerstone3D-beta/blob/d07e98a5bf475210bf6385dd304d084a60bd4b10/packages/tools/src/stateManagement/annotation/FrameOfReferenceSpecificAnnotationManager.ts#L181

The most appropriate solution would be to decouple AnnotationManage from Annotations.

To fix that we could:

base/AnnotationTool be responsible decorate the annotation (annotation constructor method)

Each Tool to invoke its super method to allow this decoration.

[Known Issue] Crosshairs for multiple viewports when they are not synced

When there are multiple viewports with crosshairs and they are not using camera synchronization (petCt demo uses camera sync),
we end up with multiple pairs of reference lines, and grabbing any pair would alway grab one of them (first element).

129933859-13de025c-9d2c-4dc7-a3b2-70508dbd157a.mov

WebAssembly.Memory(): could not allocate memory

I have two graphic cards on my workstation, the one plugged with the monitor is Intel HD 530. While trying the examples Chrome crashes and FF is really slow and complains that page is slowing the browser.

Chrome version: 100.0.4896.60

CornerstoneRender: Using detect-gpu to get the GPU benchmark: {device: undefined, fps: 55, gpu: 'intel mesa intel hd graphics 530', isMobile: false, tier: 2, …}
device: undefined
fps: 55
gpu: "intel mesa intel hd graphics 530"
isMobile: false
tier: 2
type: "BENCHMARK"
[[Prototype]]: Object
12:52:54.544 init.ts:55 CornerstoneRender: using GPU rendering
12:52:54.545 dicomweb-client.es.js:1086 retrieve metadata of series 1.3.6.1.4.1.14519.5.2.1.7009.2403.226151125820845824875394858561
12:52:54.823 dicomweb-client.es.js:1086 retrieve metadata of series 1.3.6.1.4.1.14519.5.2.1.7009.2403.879445243400782656317561081015
12:52:57.905 RenderingEngine.ts:103 [Violation] 'requestAnimationFrame' handler took 1818ms
12:52:59.093 index.worker.min.worker.js:1 Uncaught RangeError: WebAssembly.Memory(): could not allocate memory
    at o (index.worker.min.worker.js:1:81364)
    at I (index.worker.min.worker.js:1:154829)
    at ke (index.worker.min.worker.js:1:168400)
    at Object.initialize (index.worker.min.worker.js:1:169326)
    at index.worker.min.worker.js:1:153529
    at Array.forEach (<anonymous>)
    at index.worker.min.worker.js:1:153503
    at self.onmessage (index.worker.min.worker.js:1:153665)

is it supposed to fallback to CPU?

image

Examples break when using streaming-wadors

I ran into an issue while doing the examples and trying to use steaming-wadors

in all the Volume examples, imageIds are created and cached with the createImageIdsAndCacheMetaData helper function and 'VOLUME' (upper case string) for type.
https://github.com/cornerstonejs/cornerstone3D-beta/blob/659888db44ab70d562f7f52872c822feb5c1db03/packages/core/examples/multiVolumeAPI/index.ts#L214

After closer inspection of the helper function you, which prefix is determined here

https://github.com/cornerstonejs/cornerstone3D-beta/blob/main/utils/demo/helpers/createImageIdsAndCacheMetaData.js#L51

but VOLUME constant is
const VOLUME = 'volume';

When I fix the constant to 'VOLUME' the streaming loader fails to initialize with the following exception... "Error: cornerstoneWADOImageLoader requires a copy of Cornerstone to work properly."
image

Image appears zoomed and cropped

Any idea what might be causing the image to be cropped? I've seen similar issues in the older version, but a lot of the API has changed, and I am unsure how to approach it. I've tried changing the camera options but it doesn't appear to do anything for the stack version.

The image currently looks like this:
image

It should look like this:
image

This is a stack view. I've added the zoom and pan tool, but it seems like the image is still cropped.
Changing the properties or camera through setCamera and setProperties doesn't appear to do anything. I tried directly setting sHeight and sWidth, but that also doesn't appear to help.

Possibly Software Versions:

    "@cornerstonejs/calculate-suv": "1.0.2",
    "@cornerstonejs/core": "0.8.1",
    "@cornerstonejs/streaming-image-volume-loader": "0.2.24",
    "@cornerstonejs/tools": "0.15.4",
    "@kitware/vtk.js": "24.0.0",
    "react": "17.0.2",
    "vite": "2.7.2"

These are the current viewport settings:
image

These are the metadata associated with the image using a custom metadataprovider with cornerstonewebimageloader
(not a real patient below)

accessionNumber: 7974669
acquisitionDate: 20150519
acquisitionNumber: 25
acquisitionTime: "082223"
additionalPatientHistory: ""
angleOfFirstView: 0
biopsyPosition: 0
biopsyRefLocation: 0
biopsyTLocation: 0
bitsAllocated: 16
bitsStored: 16
cellNumberAtTheta: 389.75
cellSpacing: 1.0239
centerACoordOfPlaneImage: 47.5999985
centerRCoordOfPlaneImage: 2.5999999
centerSCoordOfPlaneImage: -135.75
columns: 512
contentDate: 20150519
contentTime: "082225"
convolutionKernel: "STANDARD"
correctedAfterglowTerms: 0
dasAdInput: 0
dasCalMode: 0
dasFpaGain: 0
dasOutputSource: 0
dasTriggerSource: 0
dataCollectionDiameter: 500
degreeOfRotation: 362.926819
degreesOfAzimuth: 87
deltaStartTime: 0
dependantOnNumberOfViewsProcessed: 2
distanceSourceToDetector: 949.075012
distanceSourceToPatient: 541
durationOfXrayOn: 1
exposure: 37
exposureTime: 1000
filterType: "BODY FILTER"
firstScanRas: "S"
focalSpots: 1.2
frameOfReferenceUid: "1.3.6.1.4.1.5962.99.1.2260725868.1504138972.1445369770092.7.0"
fullFidelity: "CT_LIGHTSPEED"
gantryDetectorTilt: 0
gantryPeriod: 1
generatorPower: 36000
highBit: 15
horizontalFrameOfReference: 640.039978
imageActualDate: 1432023674
imageFromWhichPrescribed: 2
imageOrientationPatient: (6) [1, '0.000000', '0.000000', '0.000000', 1, '0.000000']
imagePositionPatient: (3) [-131.1, -176.1, -135.75]
imageType: (3) ['ORIGINAL', 'PRIMARY', 'AXIAL']
instanceCreationDate: 20150519
instanceCreationTime: "082225"
instanceNumber: 200
institutionName: "Stanford"
kvp: 120
lastScanRas: "I"
manufacturer: "GE MEDICAL SYSTEMS"
manufacturerModelName: "Discovery ST"
maxOverrangesInAView: 0
midScanFlag: 1
midScanTime: 56.425903
modality: "CT"
nameOfPhysiciansReadingStudy: ""
noViewsRefChannelsBlocked: 0
normalACoord: -0
normalRCoord: 0
normalSCoord: 1
numberOfCellsInDetector: 912
numberOfOverranges: -1
numberOfTriggers: 992
operatorsName: "JL"
patientAge: "068Y"
patientBirthDate: 19470328
patientId: 8907068
patientName: "Kim^SphericalMets"
patientPosition: "HFS"
patientSex: "F"
patientWeight: 70
performedProcedureStepDescription: "Radiation Oncology CT"
performedProcedureStepId: "PPS ID  21429"
performedProcedureStepStartDate: 20150519
performedProcedureStepStartTime: "081652"
photometricInterpretation: "MONOCHROME2"
pixelData: null
pixelPaddingValue: -2000
pixelRepresentation: 1
pixelSpacing: (2) [0.501953, 0.501953]
planeType: 2
positionReferenceIndicator: "OM"
privateCreator: "GEMS_HELIOS_01"
privateScanOptions: 2
productId: "Discovery ST"
protocolName: "2.3 STEREO BRAIN"
raCoordOfTargetReconCentre: (2) [2.6, 47.599998]
reconPostProcessingFlag: 1
reconstructionDiameter: 257
referenceChannels: 0
referencedImageSequence: [{…}]
referencedPatientSequence: [{…}]
referencedStudySequence: [{…}]
referringPhysicianName: ""
requestAttributesSequence: [{…}]
rescaleIntercept: -1024
rescaleSlope: 1
rescaleType: "HU"
rotationDirection: "CW"
rows: 512
samplesPerPixel: 1
scanFovType: 16
scanOptions: "AXIAL MODE"
scanPitchRatio: ""
scoutType: 0
segmentNumber: 0
seriesContrast: 0
seriesDate: 20150519
seriesDescription: "STEREO BRAIN"
seriesFromWhichPrescribed: 1
seriesInstanceUid: "1.3.6.1.4.1.5962.99.1.2260725868.1504138972.1445369770092.6.0"
seriesNumber: 2
seriesTime: "082114"
sliceLocation: -135.75
sliceThickness: 1.25
smartScanOnOffFlag: 0
softwareVersions: "CyberKnife Information System 2.6.0.8"
sopClassUid: "1.2.840.10008.5.1.4.1.1.2"
sopInstanceUid: "1.3.6.1.4.1.5962.99.1.2260725868.1504138972.1445369770092.189.0"
startScanToXrayOnDelay: 0
startTimeSecsInFirstAxial: 1432023687.773211
stationName: "stct"
studyDate: 20150519
studyDescription: "Radiation Oncology CT"
studyId: 21429
studyInstanceUid: "1.3.6.1.4.1.5962.99.1.2260725868.1504138972.1445369770092.2.0"
studyTime: "081652"
suiteId: "STCT"
tableEndLocation: 0
tableHeight: 176
tableSpeed: 0
tableStartLocation: 0
totalSegmentsRequested: 0
triggerFrequency: 984
triggerOnPosition: 147.926682
uniqueImageIdentifier: null
unknownTagData: ""
viewCompressionFactor: 1
vmaClip: 0
vmaMamp: 0
vmaMod: 0
windowCenter: 40
windowValue: 400
windowWidth: 400
xRayTubeCurrent: 300
xrayChain: 99

[Known Issue] CrosshairsTool pointer gap

The empty space between the crosshairs lines is a fixed length currently, which makes it look huge for smaller images (canvases too I guess). Crosshairs middle gap should be configurable and be relative to canvas size.

image

Target Buffer Uint16 support?

I noticed that when loading the image we provide a target buffer of either Float32 or Uint8. In cornerstonejs I believe there was support for Uint16 type. Larger medical image volumes (tomo) can be quite large when decompressed (200 slices of 2000x3000 uint16 pixels). This would translate to about 2.4GB if the native Uint16 is used, but would double to 4.8GB using Float32.

I was curious if there were any challenges in supporting uint16 with the underlying vtk engine.

colorLUT and fillAlpha problem

The color i got is not linear, fillAlphe 0.99/1 changed a lot.I think i got the wrong color.I wonder if it's my fault.
When i use setToolGroupSpecificConfig like this
image
I got the color like this.
@sedghi The colorLut[1] is transparent. The colorLUT[2]/[3] are completely opaque.FillAlphe has been changed to 1.
The segmentation from left to right use colorIndex 1,2,3.
image

it seems that colorLUT[1] behave differently。
When i change the colorLUTArray.
image
The color has changed like this
image
@sedghi
When i change the colorLut[1] to [77,228,121,255],it seems that colorLUT[1] is transparent.
image

Cornerstone3D and Vite

I have been attempting to utilize Cornerstone3D in a Svelte web app which uses Vite. Unfortunately, when I try to import @cornerstonejs/core into the app, the build fails.

image

image

Note: If I import things from @cornerstonejs/core/dist/umd/index everything compiles and works fine, but I cannot utilize the TS types.

Reproduction steps:

  1. Generate new Svelte app using Vite (npm create vite@latest)
  2. npm install
  3. npm install @cornerstonejs/core (etc...)
  4. npm run dev
  5. Above error is thrown

I've created a repo with nothing but a fresh Svelte app and Cornerstone3d to demonstrate the problem:
https://github.com/ty-ler/cornerstone3d-svelte-vite-repro

[Vite] Uncaught TypeError: RequestPoolManager is not a constructor at imageRetrievalPoolManager.ts:11:35

Unfortunately, that's the only piece of information that I get. Using a debugger, I have linked it to simply importing @cornerstonejs/core.

image

My current setup is as follows:

  • Windows 10
  • Vite: 2.7.2
  • React: 17.0.2
  • Typescript: 4.4.4
  • Node: 16.13.2

Cornerstone-Related Library Versions:

- @cornerstonejs/calculate-suv: 1.0.2
- @cornerstonejs/core: 0.7.0
- @cornerstonejs/streaming-image-volume-loader: 0.2.24
- @cornerstonejs/tools: 0.10.1
- @kitware/vtk.js 24.0.0
- detect-gpu 4.0.20
- gl-matrix 3.4.3

Notable Actions:
Similar to #80 , I had issues with peer dependencies and used --force when installing @cornerstonejs/tools and @cornerstonejs/streaming-image-volume-loader.

This may be related: #64

Need example of using CornerstoneWebImageLoader in Cornerstone3D

The CornerstoneWebImageLoader's example is using the old cornerstone-core.

I've tried to render PNG with the following code in @cornerstonejs/core and it is not working:

const imageId = 'http://localhost:5555/my-test-dcm.png';
const imageIds = [imageId];

const renderingEngineId = 'myRenderingEngine';
const renderingEngine = new RenderingEngine(renderingEngineId);

const viewportId = 'CT_STACK';
const viewportInput = {
  viewportId,
  element: cornerstoneEl,
  type: ViewportType.STACK,
  defaultOptions: {
    background: [0, 0, 0],
  },
};

renderingEngine.enableElement(viewportInput);
if (toolGroup) {
  toolGroup.addViewport(viewportId, renderingEngineId);
}

const viewport = renderingEngine.getViewport(viewportInput.viewportId);
viewport.setStack(imageIds, 0);

viewport.render();

Screenshot 2022-05-29 at 2 16 00

Packaged source

Will you release packaged source file? That would be great. Thanks.

Build error with WebPack 5

Hi there,

we just wanted to warn that Cornerstone3D has a build issue with Webpack 5 due to the detect-gpu library

The issue is raised here : pmndrs/detect-gpu#89

For those working with react 18 with create-react-app will have this issue.

I put this here because once detect-gpu will be fixed it will need to upgrade cornerstone 3d dependencies

Salim & Celian

PT unit is always shown as SUV even when the value is not in SUV (because meta data is missing)

Currently the annotations (elliptical, rectangle, probe, maybe others) show SUV as the unit of all PT images (see .e.g. https://github.com/cornerstonejs/cornerstone3D-beta/blob/main/packages/tools/src/tools/annotation/RectangleROITool.ts#L851-L854).

However, not all PT images have the required metadata to convert values to SUV.

https://v3-demo.ohif.org/viewer?StudyInstanceUIDs=1.3.6.1.4.1.25403.345050719074.3824.20170125113417.1
Screenshot 2022-08-04 at 09 54 51
If you inspect the log, you can find:

Error: CorrectedImage must contain "ATTN" and "DECY": NORM,DTIM,RADL,DECY
    at calculateSUVScalingFactors

Error: PatientWeight value is missing. It is not possible to calculate the SUV factors

So in these cases the unit should not be SUV.

Ideally, even if all metadata is present to calculate SUV, the user should be able to select the unit (e.g. if an image is in units Bq/ml, that might be what the user actually wants so see).

PS: Thank you for this great library!

CornerStone3D-beta library can't render X-Ray images(CR, DX, XO, e.g,)

We have application based on CornerStone3D-beta library. The application can work properly with CT, PT images.
The applications can't display images For X-Ray images(CR, DX, XO,)
The question is following: Can CornerStone3D-beta library render and display X-Ray Images ?

If answer is positive can you give us the link of working code to display X-Ray images(CR, DX, XO) CornerStone3D- library.

Thanks in advance

Streaming of Volume Data using React returns TypeError when it calls 'makeVolumeMetadata' file

I am trying to create a React component which will render a Volume using some imageIds. Those imageId's come from a server where I have around 360 '.dcm' files uploaded. Normally when I send a request to the imageId URL, I get back the '.dcm' file with no problem.

To make sure I can load the files I've also tried loadImage from imageLoader with the schema of dicomweb on the URL's.
For that, I used the following line:
imageLoader.loadAndCacheImage(`dicomweb:${MY_URL}.dcm`)
This returns an Image object with ImageId, color and such.

The Error

The problem I'm encountering occurs when I try to create a volume using volumeLoader.createAndCacheVolume. I get the following error (VolumeViewport.js is the component I've written):

Uncaught (in promise) TypeError: _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.get(...) is undefined
    node_modules bundle.js:13023
    sortImageIdsAndGetSpacing sortImageIdsAndGetSpacing.ts:37
    cornerstoneStreamingImageVolumeLoader cornerstoneStreamingImageVolumeLoader.ts:67
    loadVolumeFromVolumeLoader volumeLoader.ts:99
    createAndCacheVolume volumeLoader.ts:183
    render VolumeViewport.js:53
    VolumeViewport VolumeViewport.js:91
    React 8
    workLoop scheduler.development.js:266
    flushWork scheduler.development.js:239
    performWorkUntilDeadline scheduler.development.js:533
    js scheduler.development.js:571
    js scheduler.development.js:633
    factory react refresh:6
    Webpack 24
sortImageIdsAndGetSpacing.ts:38

Here is the source code

The error occurs within the render function while creating volumes, but I wanted to include the whole code in case of someone wanting to see the whole code.

import { useEffect, useRef, useState } from "react";
import { RenderingEngine, Enums, CONSTANTS, setVolumesForViewports } from '@cornerstonejs/core';
import { init as csCoreInit } from '@cornerstonejs/core';
import { imageLoader, volumeLoader } from '@cornerstonejs/core'
import initVolumeLoader from "./initVolumeLoader";
import initWadoImageLoader from './initWadoImageLoader'

const { ViewportType } = Enums;
const { ORIENTATION } = CONSTANTS

const VolumeViewport = () => {
    const viewportRef1 = useRef(null)
    const viewportRef2 = useRef(null)
    const TOTAL_FILE_COUNT = 360
    
    const initCornerstone = async() => {
        initWadoImageLoader()
        initVolumeLoader()
        await csCoreInit()
    }
    
    const render = async() => {
        await initCornerstone()
        
        const renderingEngineId = 'myRenderingEngine'
        const renderingEngine = new RenderingEngine(renderingEngineId)

        let imageIds = []
        for (let count = 1; count <= TOTAL_FILE_COUNT; count++) {
            const paddedCount = String(count).padStart(5, '0')
            imageIds.push(`streaming-wadors:${MY_URL}`)
        }

        const volumeId = 'cornerStreamingImageVolume: myVolume';
        const volume = await volumeLoader.createAndCacheVolume(volumeId, { imageIds: imageIds })

        const viewportId1 = 'CT_AXIAL';
        const viewportId2 = 'CT_SAGITTAL';

        const viewportInput = [
            {
                viewportId: viewportId1,
                element: viewportRef1.current,
                type: ViewportType.ORTHOGRAPHIC,
                defaultOptions: {
                orientation: ORIENTATION.AXIAL,
                },
            },
            {
                viewportId: viewportId2,
                element: viewportRef2.current,
                type: ViewportType.ORTHOGRAPHIC,
                defaultOptions: {
                orientation: ORIENTATION.SAGITTAL,
                },
            },
        ];

        renderingEngine.setViewports(viewportInput);

        await volume.load()
        setVolumesForViewports(
            renderingEngine,
            [{ volumeId }],
            [viewportId1, viewportId2]
        )
        
        renderingEngine.renderViewports([viewportId1, viewportId2])
    }

    useEffect(() => {
        if (viewportRef1.current && viewportRef2.current) {
            render()
        }
    }, [viewportRef1])


    return (
        <>
            <div ref={viewportRef1} style={{width: '500px', height: '500px'}}>

            </div>
            <div ref={viewportRef2} style={{width: '500px', height: '500px'}}>

            </div>
        </>

    );
}
 
export default VolumeViewport;

VolumeViewport Orientation when ImageOrientation metadata is unusual

TLDR:
How to set proper orientation for a VolumeViewport when ImageOrientationPatient metadata doesn't match the provided constant orientations?
---

Hi,
I'm having issues with finding out the proper Orientation values to set, when I'm rendering a volume with ImageOrientation metadata values different than the usual Axial/Sagital/Coronal values.

I believe that the ImageOrientation values map to orientations like this:

    coronalImageOrientationPattern = [1, 0, 0, 0, 0, -1];
    // sliceNormal: <Point3>[0, 1, 0],
    // viewUp: <Point3>[0, 0, 1],

    sagittalImageOrientationPattern = [0, 1, 0, 0, 0, -1];
    // sliceNormal: <Point3>[1, 0, 0],
    // viewUp: <Point3>[0, 0, 1],

    axialImageOrientationPattern = [1, 0, 0, 0, 1, 0];
    // sliceNormal: <Point3>[0, 0, -1],
    // viewUp: <Point3>[0, -1, 0],

But when the ImageOrientation value is different(like below), the standard orientations don't result in the expected Axial/Coronal/Sagital views.
[0.85005025920695,-0.5267015823236,2.1648092e-8,0.00883004239504,0.01425087456269,-0.9998594615872].

I think cornerstone doesn't have any instructions about what to do in such case.

So I attempted to create a custom orientation based on the ImageOrientation, I found out that the sliceNormal part is created by crossing the ImageOrientation like this: sliceNormal = cross(imageOrientation.slice(0, 3), imageOrientation.slice(3, 6)) , though I'm not sure if it's correct. And for the ViewUp part I have no idea how I should set it properly...
When using the calculated SliceNormal and some viewUp from the constant orientations, the view seems like it's correct, except for the camera. It's often positioned wrongly. For example, for these views to be correct, we'd need to: flip the camera horizontally / move the camera to the back of the image instead of the front etc. Cornerstone doesn't give us functionalites like that tho, and even if it did, it'd be hard to dynamically decide what camera operations need to be done to make the specific view correct.

So my question is, how to set the orientation for volumes with custom ImageOrientationPatient metadata?

Volume rendered with Orientation Coronal
coronal

Volume rendered with Orientation Axial
axial

Volume rendered with custom orientation - sliceNormal = cross(imageOrientation.slice(0, 3), viewUp = [0, 0, 1]
(in this case the problem is left=right)
sliceCalcView001

Used DICOM files - series-000001.zip

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.