Get coordinated of user drawn rectangle in image

Dear all,

I have a seemingly simple problem, however I could not find a solution in the Igor documentation.

I have an image that is displayed vie NewImage. The user has to draw a rectangular ROI in the image. This can be easily done by utilizing the standard ROI-Panel. What I need is a way to get the coordinates of the user drawn rectangle. Either in pixels or some other arbitrary scaling.

Is there a way to get the rectangle coordinates inside the image?

Best regards,
Todor
One way would be to use ImageGenerateROIMask. I believe it creates a 2D wave with pixels in the ROI set to one value and pixels outside set to another. When I have used it, I recall at first failing to read the second paragraph in its help file, which mentions that the ROI has to be drawn in the drawing layer 'progFront'. A way to set an image window to that drawing layer is to run: setdrawlayer progFront

If you're only interested in rectangular ROIs, it looks like getmarquee and setmarquee are a second option, as mentioned here http://www.igorexchange.com/node/8215



Consider using the marquee for the ROI. It's a simple matter to get the coordinates for the marquee corners.

Take a look at GetMarquee in the help browser and click on the "Open Marquee Demo" link at the bottom. This provides a nice intro to how the marquee may simplify your application.
//Only one rentangle considered... you may modify this code to fit your specific need
function  GetRoiCoord()
    string sw=winname(0,1)
    string simg=stringfromlist(0,imagenamelist("",";"))
    ImageGenerateROIMask $simg
    wave w=M_ROIMask
    variable l,t,r,b
    variable nx=dimsize(w,0)
    variable ny=dimsize(w,1)
    variable x0=dimoffset(w,0)
    variable dx=dimdelta(w,0)
    variable y0=dimoffset(w,1)
    variable dy=dimdelta(w,1)
    variable i,j,flag=0
   
    //this algorithm seems not so good,but works...
    for(i=0;i<nx;i+=1)
        for(j=0;j<ny;j+=1)
            if(w[i][j]==1)
                l=x0+dx*i
                t=y0+dy*j
                flag=1
                break
            endif
        endfor
        if(flag==1)
            break
        endif
    endfor
    flag=0
    for(i=nx-1;i>=0;i-=1)
        for(j=ny-1;j>=0;j-=1)
            if(w[i][j]==1)
                r=x0+dx*i
                b=y0+dy*j
                flag=1
                break
            endif
        endfor
        if(flag==1)
            break
        endif
    endfor
    print l,t,r,b  //left,top,right,bottom
end
I use a structure and a Get function call. Modifications of this approach might be of use.

// structure to collect marquee coordinates
Structure MarqueeCoordinates
    variable ispresent
    variable left
    variable right
    variable top
    variable bottom
EndStructure

// fill the structure
Function GetMCCoordinates(mc)
    Struct MarqueeCoordinates &mc
   
    GetMarquee/W=imgT_display/Z left,top
    mc.ispresent = v_flag
    mc.left = v_left
    mc.right = v_right
    mc.top = v_top
    mc.bottom = v_bottom

    return 0
end

    if (iBckg.MRoI != 1)
        // get marquee from image graph
        STRUCT MarqueeCoordinates mc
        GetMCCoordinates(mc)
        if (!mc.ispresent)
            DoAlert/T="Show I Slice" 0, "No Marquee region is present. Set one and try again."
            return -1
        endif
    endif


--
J. J. Weimer
Chemistry / Chemical & Materials Engineering, UAH
Thank you for your replies. There were some very helpful ideals.

During the last few days my objective changed. I want the user to be able to select multiple rectangular ROIs and extract the position of their top left corner as well as height and width.

Here is the code which works for me:

Function MC_EndROI()

    SVAR MC_captureFrameImage  //Name of graph displaying the image of interest.

    Variable aCount, bCount           //Arbitrary counter variables

        //End user selection of ROI
    setdrawenv/W=$MC_captureFrameImage gstop
    hidetools/W=$MC_captureFrameImage
    drawaction/W=$MC_captureFrameImage/L=progfront getgroup=MC_ROISelection, extractoutline

        //Create pointers to W_PolyX and W_PolyY containing the polygon points of the user selected ROI.
        //Important assumption: the ROI is rectangular
    Wave W_PolyX
    Wave W_PolyY
   
        //Add a NaN to end of W_PolyX and W_PolyY to simplify later for-loop
    Redimension/N=(DimSize(W_PolyX,0)+1) W_PolyX
    Redimension/N=(DimSize(W_PolyY,0)+1) W_PolyY   
    W_PolyX[DimSize(W_PolyX,0)-1]=NaN
    W_PolyY[DimSize(W_PolyY,0)-1]=NaN
   
    Variable buffer, bufferSize, bufferPixel
        //Buffer wave for storing coordinates upper-left and lower-right corner of rectangle   
    Make/O/N=(2,2) bufferRectEdges
   
    bCount=0
   
    for(aCount=0;aCount<DimSize(W_PolyX,0);aCount+=1)
       
                //NaN separates polygons from each other
        if(numtype(W_PolyX[aCount])==2)
                //Initialite bufferRectEdges
            bufferRectEdges=0
           
                        //Upper-left corner x-coordinate
            bufferRectEdges[0][0]=W_PolyX[aCount-5]
                        //Upper-left corner y-coordinate
            bufferRectEdges[0][1]=W_PolyY[aCount-5]
                        //Lower-right corner x-coordinate
            bufferRectEdges[1][0]=W_PolyX[aCount-3]
                        //Lower-right corner y-coordinate
            bufferRectEdges[1][1]=W_PolyY[aCount-3]
                  endif

    endfor

Variable top, left, width, height

top=min(bufferRectEdges[0][0],bufferRectEdges[0][1])
left=min(bufferRectEdges[0][1],bufferRectEdges[1][1])
width=abs(bufferRectEdges[0][0]-bufferRectEdges[1][0])
height=abs(bufferRectEdges[0][1]-bufferRectEdges[1][1])

End


There might be some syntax errors, scince I truncated the code a litte. There are a few extra steps and precautions needed in my application.

Best regards,
mouthbag