Get coordinated of user drawn rectangle in image

mouthbag
Posts: 4
Joined: 2017-01-19
Location: Germany

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


aoa
Posts: 68
Joined: 2015-10-30
Location: United States

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


jtigor
Posts: 405
Joined: 2007-09-04
Location: United States

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.


hegedus
Posts: 335
Joined: 2009-03-21
Location: United States

Hi,

I had to solve this problem not long ago. Look at this post for the code I used using marquee.

http://www.igorexchange.com/node/8215

Andy


wings
Posts: 65
Joined: 2016-04-27
Location: China

//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


jjweimer
jjweimer's picture
Posts: 1334
Joined: 2007-08-14
Location: United States

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


mouthbag
Posts: 4
Joined: 2017-01-19
Location: Germany

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


Back to top