-
Notifications
You must be signed in to change notification settings - Fork 27
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
Compatibility with Cornerstone3D #48
Comments
(I do plan to try to test and figure this out on my own. I'm posting this to ask for some guidance to be added to the docs to help others out during the transition) |
I'm currently trying to make this project work with cornerstone3D but there are functions which changed with corenerstone3D (as loadAndCacheImage for example). I don't know if the both are compatible. |
i load nifti files for Cornerstone3D, but it not works. are you have some examples? |
Thank you for the clarification! That helps a lot. I'll build on |
@acegank there's an example right in the repo. But like I said, and like @simonalo confirmed, these NIfTI examples need to work against |
Hello, I managed to make I post the relevant portions of my code, if it can help somenone. It's not minimal, as I wanted to display 3 orientations (x,y,z) of the same image. And I had to tweak a few things (events, metadata), and I'm not quite sure if there are side effects...
{
"name": "cornerstone3d-tests",
"packageManager": "yarn@3.3.1",
"version": "0.0.0",
"description": "",
"private": true,
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"watch": "webpack --watch",
"start": "webpack serve --open",
"build": "webpack"
},
"devDependencies": {
"css-loader": "^6.7.3",
"style-loader": "^3.3.1",
"webpack": "^5.75.0",
"webpack-cli": "^5.0.1",
"webpack-dev-server": "^4.11.1"
},
"dependencies": {
"@cornerstonejs/core": "^0.25.1",
"@cornerstonejs/nifti-image-loader": "^1.0.9",
"@cornerstonejs/tools": "^0.35.0",
"@kitware/vtk.js": "^26.0.0",
"d3-array": "^3.2.1",
"d3-interpolate": "^3.0.1",
"gl-matrix": "^3.4.3"
}
}
import * as cornerstone from '@cornerstonejs/core';
import * as cornerstoneNIFTIImageLoader from '@cornerstonejs/nifti-image-loader';
const { ViewportType } = cornerstone.Enums;
function createElement( size = '400px') {
let element = document.createElement('div');
element.style.width = size;
element.style.height = size;
element.style.border = '1px solid red';
element.style.margin = '10px';
// Disable default context menu
element.oncontextmenu = (e) => e.preventDefault();
return element;
}
/**
* Hardcoded metadata provider for NIFTI images, as they don't exist in the old cornerstone module
* @param type The type of metadata to retrieve
* @param imageId The imageId of the image to retrieve metadata for. Must start with 'nifti:'
* @returns {Object} The metadata object
*/
function additionalMetaDataProvider(type, imageId) {
const colonIndex = imageId.indexOf(':');
const scheme = imageId.substring(0, colonIndex);
if (scheme !== 'nifti') return;
if (type === 'generalSeriesModule') {
return {
modality: 'Unknown',
};
}
}
/**
* Uses the NIFTI image loader to fetch metadata of a NIFTI, cache it in cornerstone,
* and return a list of imageIds for the frames.
*
* @returns {string[]} An array of imageIds for instances in the study.
*/
async function createImageIdsAndCacheMetaData(imageId) {
const colonIndex = imageId.indexOf(':');
const scheme = imageId.substring(0, colonIndex);
if (scheme !== 'nifti') {
console.warn('createImageIdsAndCacheMetaData: imageId must have scheme "nifti". imageId: ', imageId);
return;
}
// Load the image (it will be stored in the cache, and the metadata also)
const imageIdObject = cornerstoneNIFTIImageLoader.nifti.ImageId.fromURL(imageId);
const image = await cornerstone.imageLoader.loadAndCacheImage(imageIdObject.url);
// Get the number of frames from the metadata the image loader provides
const numberOfFrames = cornerstone.metaData.get('multiFrame', image.imageId).numberOfFrames;
const imageIds = Array.from(Array(numberOfFrames),
(_, i) => `nifti:${imageIdObject.filePath}#${imageIdObject.slice.dimension}-${i},t-0`)
console.log('imageIds', imageIds);
return imageIds;
}
async function run() {
// Create elements to render into
const content = document.getElementById('content');
content.style.display = 'flex';
content.style.flexDirection = 'row';
const element1 = createElement();
content.appendChild(element1);
const element2 = createElement();
content.appendChild(element2);
const element3 = createElement();
content.appendChild(element3);
// Initialize cornerstone and tools
await cornerstone.init();
// Create a rendering engine
const renderingEngineId = 'myRenderingEngine';
const renderingEngine = new cornerstone.RenderingEngine(renderingEngineId);
// Create the viewports (of type STACK)
const viewportInputArray = [
{
viewportId: 'X_VIEWPORT',
type: ViewportType.STACK,
element: element1,
},
{
viewportId: 'Y_VIEWPORT',
type: ViewportType.STACK,
element: element2,
},
{
viewportId: 'Z_VIEWPORT',
type: ViewportType.STACK,
element: element3,
}
];
renderingEngine.setViewports(viewportInputArray);
const viewportX = renderingEngine.getViewport('X_VIEWPORT');
const viewportY = renderingEngine.getViewport('Y_VIEWPORT');
const viewportZ = renderingEngine.getViewport('Z_VIEWPORT');
// Register the nifti image loader
cornerstoneNIFTIImageLoader.external.cornerstone = cornerstone;
// NOTE: This is a hack to get around the fact that the nifti image loader
// uses the old cornerstone module, and we need to provide it with the
// new cornerstone module (events = eventTarget).
cornerstoneNIFTIImageLoader.external.cornerstone.events = cornerstone.eventTarget;
// cornerstoneNIFTIImageLoader.nifti.streamingMode = true;
// Register an additional metadata provider for Nifti images (for the generalSeriesModule, not provided by the package)
cornerstone.metaData.addProvider(
(type, imageId) => additionalMetaDataProvider(type, imageId),
1000 // Priority of the NIFTI metadata provider is 10000, so this one is called after
);
// Example of a Nifti image, from the web.
// The number after # is the frame index
// const imageUrl = 'https://raw.githubusercontent.com/muschellij2/Neurohacking_data/master/BRAINIX/NIfTI/Output_3D_File.nii.gz#10'
// Will load a local image
const imageUrl = `data/mni152_2009_256.nii.gz`;
// Load the image and assign it to the viewport, for each orientation
const imageIdsZ = await createImageIdsAndCacheMetaData(`nifti:${imageUrl}#z`);
viewportZ.setStack(imageIdsZ, Math.floor(imageIdsZ.length / 2));
viewportZ.render();
const imageIdsY = await createImageIdsAndCacheMetaData(`nifti:${imageUrl}#y`);
viewportY.setStack(imageIdsY, Math.floor(imageIdsY.length / 2));
viewportY.render();
const imageIdsX = await createImageIdsAndCacheMetaData(`nifti:${imageUrl}#x`);
viewportX.setStack(imageIdsX, Math.floor(imageIdsX.length / 2));
viewportX.render();
}
run(); |
@scandel |
Is this something planned to be tackled soon? |
@scandel Kind regards |
Yes you can load NIFTI images in cornerstone3D in volume using @cornerstonejs/nifti-volume-loader. |
I want to use this but I don't know how I am supposed to right now. Can you clarify if this is/isn't compatible with the new Cornerstone3D?
package.json
doesn't list it as a dependency (peer or otherwise) so I'm not sure what version of Cornerstone I'm supposed to be using.According to https://www.cornerstonejs.org/, Cornerstone3D, or
@cornerstonejs/core
, is the new "beta" version of Cornerstone:and according to cornerstonejs/cornerstone3D#118 (comment), the legacy Cornerstone,
cornerstone-core
, is no longer being maintained at all.The two projects have separate versioning schemes. The legacy one is at 2.6.1, the beta is at 0.16.7. So they really are separate projects.
The reason I'm confused is:
this repo is installable as
@cornerstonejs/nifiti-image-loader
, in the same@cornerstonejs
group, as if it's a peer of@cornerstonejs/core
, and that copy has the most recent 1.0.7 releasebut it's also installable as the older name
cornerstone-nifiti-image-loader
, but that copy hasn't been updated since 1.0.0, so that copy is probably deadbut the actual examples that show me how to use this in practice have vendored a copy of the legacy code, and haven't touched it in 5 years
cornerstone-nifti-image-loader/examples/cornerstone.js
Line 1 in b14ae74
So, how do I use this? If I
npm i @cornerstone/core
will this work correctly with it?The text was updated successfully, but these errors were encountered: