Get coordinated of user drawn rectangle in image
mouthbag
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
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
andsetmarquee
are a second option, as mentioned here http://www.igorexchange.com/node/8215March 9, 2018 at 05:45 am - Permalink
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.March 9, 2018 at 06:26 am - Permalink
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
March 9, 2018 at 06:43 am - Permalink
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
March 9, 2018 at 06:46 am - Permalink
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
March 9, 2018 at 04:38 pm - Permalink
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:
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
March 13, 2018 at 08:40 am - Permalink