Viewers: How to draw rect on image/slice at correct position

Created on 19 Apr 2019  路  10Comments  路  Source: OHIF/Viewers

Hi,

I'd like to

  1. Click link to navigate and go to a slice by calling switchToImageByIndex(imageIndex)
  2. Draw a rectangle on display image(slice)

1.
I've done

2.
I can draw by below code but the position of rectangle is incorrect.
At first time series display, I click "View slice", the rect position is incorrect.
If I click any button (on header menu), the position of rectangle is moved to new one that as my expected. Please find the attach.

What is my wrong? How can I draw at correct position as my expected one?

I think I need convert the coordinate system but no way. Please help me.

Template.XXX.events({
    'click ul li a'(event) {
       ...
       const $element = $('.imageViewerViewport'); 
       $element.on('cornerstoneimagerendered', onImageRendered); 

    }
})
const onImageRendered = (event, eventData) => {
    const detectedSopInstanceUId = Session.get("detectedSopInstanceUId");

    const instance = aiUtils.getViewportInstanceInfo();
    const currentSopInstanceUid = instance.sopInstanceUid;
    // Checl sopId
    if (currentSopInstanceUid == detectedSopInstanceUId) {

        // Call mark 
        drawRect();
    }
}

function drawRect() {
    ....
    const canvas = activeViewport.querySelector('canvas');
    const context = canvas.getContext('2d');

    context.beginPath();

    // Mark rectangle
    context.strokeStyle = 'red';
    context.lineWidth = 2;
    context.rect(Number(currentPosition.x) - area/4, Number(currentPosition.y) - area/4, area/2, area/2);
    // Draw
    context.stroke(); 
}

image

Awaiting Reproduction Community

Most helpful comment

@liuchen1393193701, please stop leaving short, unhelpful comments across many issues. If you need assistance, please:

  • Create a new GitHub issue in the appropriate repository
  • Describe what you have already tried and your results
  • If relevant, include a minimal reproduction or example

At that point, if you are not receiving the answers you need to resolve your issue, you may want to consider paid support from an expert.

Best of luck ^_^

As a heads up, I have removed some of the less helpful comments.

All 10 comments

Hmm.. I'm not 100% sure why you're seeing an initially incorrect placement. It looks like the code snippet you've included is incomplete. Either way, if you're trying to display an annotation, and you want it to be correctly positioned, you'll likely want to work with the underlying cornerstone.js and cornerstoneTools.js APIs instead of drawing directly on the canvas yourself.

Those libraries take into account viewport scaling, translation, etc. As well as a host of other factors that might be prohibitive to account for in a one-off custom annotation.

Cornerstone already supports rectangle annotations, and the OHIF Viewer has this tool added:

image

You would likely want to "restore state" for the rectangle roi tool using the stateManagement exposed by cornerstone-tools: https://github.com/cornerstonejs/cornerstoneTools/blob/master/src/index.js#L142-L149

Hi @dannyrb,

Yes, you're right! I've done by calling cornerstoneTools.addToolState(element, 'rectangleRoi', measurementData) . Thank you so much!

I have a trouble.
When series display, I click "view slice" slices will scroll to my slice (eg, slice index 40) automatically and draw rectangleRoi on. How can I wait until my slice display and then draw the rect?

I'm using cornerstoneTools.scrollToIndex(element, newImageIdIndex) to scroll to my index slice.

Now when I click "View slice" scroll to my slice without rect and then click "View slice" once again the rect will be drew.

@iam0620, cornerstone emits an event each time a new image is rendered. You can listen for the event, and add the rect when the ID matches the one you expect?

For a list of events, check out the cornerstone repository.

Also, most tooldata is specific to an image ID. Cornerstone tools should conditionally render the annotation when the corresponding image is displayed.

Thanks @dannyrb

I changed my above drawRect() to as below and the rect is drew correctly when click "View slice".
I draw the rect in onImageRendered = (event, eventData){} event and only when currentSopInstanceUid == detectedSopInstanceUId (scroll image sop instance = expected sop instance)

However, The zoom, pan tool don't work on the current slice/image (that the rectangleRoi is drew) . The view state always returns to the initial state (state when scrolling to and drawing rect firstly) after doing zoom/pan action.
(I think due to cornerstoneTools.addToolState(element, 'rectangleRoi', measurementData) )

Could I need to check if zoom/pan event, don't do rectangleRoi?

function drawRect() {
    const activeViewport = Viewerbase.viewportUtils.getActiveViewportElement();

    if (!activeViewport) {
        // No selected main viewer
        return;
    }

    const canvas = activeViewport.querySelector('canvas');
    const context = canvas.getContext('2d');


    const enabledElement = Viewerbase.viewportUtils.getEnabledElement(activeViewport);   
    var element = enabledElement.element;

    cornerstone.enable(element);    

    // x: 357.841, y: 95.88900000000001
    var start = {x:Number(currentPosition.x) - area/4, y:Number(currentPosition.y) - area/4};
    // end = {x: 135, y: 135}
    var end = {x:(start.x + area/2), y:(start.y + area/2)};

    // Rect data
    const measurementData = {
                                visible: true,
                                active: true,
                                invalidated: true,
                                handles: {
                                    start: {
                                        x: start.x,
                                        y: start.y,
                                        highlight: true,
                                        active: false
                                    },
                                    end: {
                                        x: end.x,
                                        y: end.y,
                                        highlight: true,
                                        active: true
                                    },
                                    textBox: {
                                        active: false,
                                        hasMoved: false,
                                        movesIndependently: false,
                                        drawnIndependently: true,
                                        allowedOutsideImage: true,
                                        hasBoundingBox: true
                                    }
                                }
                            }

    // Clear and re-draw
    cornerstoneTools.clearToolState(element, 'rectangleRoi');                        
    cornerstoneTools.addToolState(element, 'rectangleRoi', measurementData)    
}

If the element is already enabled and showing an image, you likely don't need to call this:

cornerstone.enable(element); -- That may be triggering your viewport issue?

Can you step through your code and identify which line of code is causing your issue? Assuming the zoom/pan tools are active, they should continue to work even after a state change. Do you see any exceptions in your console?

Hi @dannyrb

No any exceptions in my console.

When zooming or panning, onImageRendered = (event, eventData){} event trigger looply and of course it call cornerstone.enable(element) and draw rectangleROI . It is causing my issues.

I dived deeply investigation but I can not find how to check an element is already enable to don't call cornerstone.enable(element) again as well as how to check exptected image is displaying?.

When "View slice" clicked, I get into debug mode at onImageRendered = (event, eventData){} event, imageId value is my expected image but actually imageId doesn't display/scroll to yet (current displaying image isn't my expected)

I would be appreciated if you could help!

How to realize the area of closed graphics with mouse moving painting

@liuchen1393193701, please stop leaving short, unhelpful comments across many issues. If you need assistance, please:

  • Create a new GitHub issue in the appropriate repository
  • Describe what you have already tried and your results
  • If relevant, include a minimal reproduction or example

At that point, if you are not receiving the answers you need to resolve your issue, you may want to consider paid support from an expert.

Best of luck ^_^

As a heads up, I have removed some of the less helpful comments.

@Iam0620, sorry for the delay. It's getting a bit hard to follow which parts you are doing yourself, and which parts are being handled by cornerstone tools. If I'm going to help further, I would appreciate:

  • A fork of this repo with only your changes applied
  • What your current result is, versus your expected result

The hope is that what you're asking should only require adding toolstate to the rectangle tool. So I'm not sure where the disconnect is. Any additional context you can provide to help would be :fire:

Hi @dannyrb

I've just solved my issues.

I check sopInstanceUid is my expected SopId and current element has no toolData, made rectangleRoi.

toolData = cornerstoneTools.getToolState(element, 'rectangleRoi');

Thank you for your support.

Was this page helpful?
0 / 5 - 0 ratings