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

Means of Serializing out Transform + Annotations #30

Closed
cancan101 opened this issue May 7, 2015 · 11 comments
Closed

Means of Serializing out Transform + Annotations #30

cancan101 opened this issue May 7, 2015 · 11 comments

Comments

@cancan101
Copy link

For a given input image and a set of transforms and annotations applied, have some way of serializing out these transforms and annotations so that they can be re applied to the same image later.

@chafey
Copy link
Collaborator

chafey commented May 8, 2015

This is something we are discussing in our OHIF architecture meetings. Will update this issue when we have made some decisions

@swederik
Copy link
Member

swederik commented May 8, 2015

I agree this would be useful. At the moment for viewport I am using something like this (where viewportString is sent to the server and returned when the page is loaded again):

// every few seconds
var viewport = cornerstone.getViewport(element);
var viewportString = JSON.stringify(viewport);

// on page load
var savedViewport = JSON.parse(viewportString);
cornerstone.setViewport(element, savedViewport);

I could image something similar working like

var toolData = cornerstone.getAllToolStates(element);

or perhaps some function attached to the the toolStateManager(s)

@cancan101
Copy link
Author

This is an example of the data using that technique:

{"scale":4.3359375,
"translation":{"x":11.070270270270273,"y":-0.23063063063063063},
"voi":{"windowWidth":1354.671875,"windowCenter":333.0546875},
"invert":true,
"pixelReplication":false,"rotation":0,"hflip":false,"vflip":false}

Consistent with the docs here, WW/WC, invert, rotate, flip, scale and translate seem to be captured. The various annotations are not captured.

@swederik
Copy link
Member

So I think implementing this in cornerstoneTools will be a bit more complicated (because of the different types of toolStateManagers), but if you need to do this right now you can just do something like this:

// --- To serialize the tool states ---
var element = document.getElementById("dicomImage");
var allToolData = {};

// Decide which tool types you want to serialize
var toolTypes = ['length', 'angle'];

// Loop through all the tool types
for (var i = 0; i < toolTypes.length; i++) {
    // Get the tool data for this tool type
    var toolType = toolTypes[i];
    var toolData = cornerstoneTools.getToolState(element, toolType);

    if (toolData !== undefined) {
        // Put it into an object
        allToolData[toolTypes[i]] = toolData;
    }
}

var toolDataString = JSON.stringify(allToolData);

Then to put the tool data back:

// Try pasting this block into the allImageTools example: 
var element = document.getElementById("dicomImage");
var toolDataString = '{"angle":{"data":[{"visible":true,"handles":{"start":{"x":92.40628941112809,"y":109.38908238107877,"highlight":true,"active":false},"end":{"x":112.40628941112809,"y":99.64666043201174,"highlight":true,"active":false,"eactive":false},"start2":{"x":92.40628941112809,"y":109.38908238107877,"highlight":true,"active":false},"end2":{"x":112.40628941112809,"y":119.38908238107877,"highlight":true,"active":false}}}]},"length":{"data":[{"visible":true,"handles":{"start":{"x":30.63388210486889,"y":77.14351868515968,"highlight":true,"active":false},"end":{"x":57.46755322260141,"y":154.21895700205096,"highlight":true,"active":false,"eactive":false}}}]}}';

// --- To put the tool data back ---
var allToolData = JSON.parse(toolDataString);
for (var toolType in allToolData) {
    if (allToolData.hasOwnProperty(toolType)) {
        for (var i = 0; i < allToolData[toolType].data.length; i++) {
            var toolData = allToolData[toolType].data[i];
            cornerstoneTools.addToolState(element, toolType, toolData);
        }
    }
}
// Update the canvas
cornerstone.updateImage(element);

I tested this using the chrome debugger and the allImageTools example here:

https://rawgit.com/chafey/cornerstoneTools/master/examples/allImageTools/index.html

It may not be the most robust (I didn't check what happens with tool data that is empty), but it's a start and may be good enough for what you want to do.

@cancan101
Copy link
Author

Is there any way to remove a toolState once addToolState is called?
Looking over https://github.com/chafey/cornerstoneTools/wiki/DataManagement, nothing jumps out at me.

@swederik
Copy link
Member

Yes, you can use removeToolState. See:

https://github.com/chafey/cornerstoneTools/blob/9a0f143b07c808553762c7d9170507bd66b70b0f/src/stateManagement/toolStateManager.js#L38

It just splices the data out of the toolData array, so you have to tell it which piece of toolData to remove. Sooner or later a function like clearToolData will probably be added to remove all instances of one tool type (see e.g. #29), but there isn't anything like that yet.

@cancan101
Copy link
Author

Ok.
Is there some way to get var toolTypes = ['length', 'angle']; from the list of all tools in use rather than having to hard code it?

@swederik
Copy link
Member

No simple way that I can think of, but you can just make a list of all the tool types (I only used length and angle as an example). Those without toolData just won't contribute to the string output.

@swederik
Copy link
Member

Quick update: See #40 for clearing tool data.

@hubtub2
Copy link

hubtub2 commented Dec 12, 2019

The solution of swederik works well.

Howevert, if I have a stack of images (using StackStateManager) - how do I access the annotations from the images in the stack that are currently not displayed?

Or in other words: I want to serialize all annotations, not just the one from the current slice.

@dannyrb
Copy link
Member

dannyrb commented Dec 12, 2019

@hubtub2 can you please ask your question in a new issue? This issue is from 2015.

@cornerstonejs cornerstonejs locked as resolved and limited conversation to collaborators Dec 12, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants