FG question: retrieve points within polygon [message #89797] |
Thu, 04 December 2014 01:50  |
Helder Marchetto
Messages: 520 Registered: November 2011
|
Senior Member |
|
|
Hi,
I'm looking for an easier way to get the indices inside a polygon or ellipse created in function graphics.
So here is a basic example that states what I want to do:
;first generate the graphics
img = dist(600)
w = window(dimensions=[500,500])
im = image(img, current=w)
pl = polygon([0.25,0.75,0.75,0.25],[0.25,0.25,0.75,0.75],/norm,ta rget=im)
;make some changes to the polygon
pl.rotate, 12
;now extract the mean value of the points of the image that are inside the polygon
pl->getData, xx, yy
o = obj_new('idlanroi', xx*600d, yy*600d, /double, type=2)
mask = o->ComputeMask(dimensions=[600,600])
obj_destroy, o
pts = where(mask, cnt)
meanVal = mean(img[pts])
print, 'the mean value inside the polygon is ', meanVal
So this method works fine. It's maybe not the most obvious, but works. Now the question is... How do I get the same result for an ellipse?
Of course I could calculate the perimeter points of the ellipse and use the same method as above, but that would not really be... well ... cool.
Any better way to do this? I couldn't find any FG method to get such info.
Thanks,
Helder
|
|
|
Re: FG question: retrieve points within polygon [message #89805 is a reply to message #89797] |
Thu, 04 December 2014 05:51   |
lecacheux.alain
Messages: 325 Registered: January 2008
|
Senior Member |
|
|
On Thursday, December 4, 2014 10:50:42 AM UTC+1, Helder wrote:
> Hi,
> I'm looking for an easier way to get the indices inside a polygon or ellipse created in function graphics.
> So here is a basic example that states what I want to do:
>
> ;first generate the graphics
> img = dist(600)
> w = window(dimensions=[500,500])
> im = image(img, current=w)
> pl = polygon([0.25,0.75,0.75,0.25],[0.25,0.25,0.75,0.75],/norm,ta rget=im)
> ;make some changes to the polygon
> pl.rotate, 12
>
> ;now extract the mean value of the points of the image that are inside the polygon
>
> pl->getData, xx, yy
> o = obj_new('idlanroi', xx*600d, yy*600d, /double, type=2)
> mask = o->ComputeMask(dimensions=[600,600])
> obj_destroy, o
> pts = where(mask, cnt)
> meanVal = mean(img[pts])
> print, 'the mean value inside the polygon is ', meanVal
>
>
>
> So this method works fine. It's maybe not the most obvious, but works. Now the question is... How do I get the same result for an ellipse?
> Of course I could calculate the perimeter points of the ellipse and use the same method as above, but that would not really be... well ... cool.
>
> Any better way to do this? I couldn't find any FG method to get such info.
>
> Thanks,
> Helder
If you could plot an ellipse with FG, you know its equation from the parameters (center, axes, orientation) you have given in the call. Let it be F(x,y)=0.
Then the indices of the (x,y) points inside the ellipse are those for which F(x,y) is strictly negative.
alx.
|
|
|
Re: FG question: retrieve points within polygon [message #89809 is a reply to message #89805] |
Thu, 04 December 2014 06:32   |
Helder Marchetto
Messages: 520 Registered: November 2011
|
Senior Member |
|
|
On Thursday, December 4, 2014 2:51:28 PM UTC+1, alx wrote:
> On Thursday, December 4, 2014 10:50:42 AM UTC+1, Helder wrote:
>> Hi,
>> I'm looking for an easier way to get the indices inside a polygon or ellipse created in function graphics.
>> So here is a basic example that states what I want to do:
>>
>> ;first generate the graphics
>> img = dist(600)
>> w = window(dimensions=[500,500])
>> im = image(img, current=w)
>> pl = polygon([0.25,0.75,0.75,0.25],[0.25,0.25,0.75,0.75],/norm,ta rget=im)
>> ;make some changes to the polygon
>> pl.rotate, 12
>>
>> ;now extract the mean value of the points of the image that are inside the polygon
>>
>> pl->getData, xx, yy
>> o = obj_new('idlanroi', xx*600d, yy*600d, /double, type=2)
>> mask = o->ComputeMask(dimensions=[600,600])
>> obj_destroy, o
>> pts = where(mask, cnt)
>> meanVal = mean(img[pts])
>> print, 'the mean value inside the polygon is ', meanVal
>>
>>
>>
>> So this method works fine. It's maybe not the most obvious, but works. Now the question is... How do I get the same result for an ellipse?
>> Of course I could calculate the perimeter points of the ellipse and use the same method as above, but that would not really be... well ... cool.
>>
>> Any better way to do this? I couldn't find any FG method to get such info.
>>
>> Thanks,
>> Helder
>
> If you could plot an ellipse with FG, you know its equation from the parameters (center, axes, orientation) you have given in the call. Let it be F(x,y)=0.
> Then the indices of the (x,y) points inside the ellipse are those for which F(x,y) is strictly negative.
> alx.
Hi Alx,
I wanted to avoid doing myself the calculation, but even trying I found that it is not that possible. It seems like the ellipse() function simply generates a polygon() function. Once created, I could not retrieve the center or radius (major or minor) and cannot therefore compute using the ellipse equation. What I can do is use the undocumented getData method as I would for a polygon and then proceed as if it were a polygon.
Still, a mask method would be a nice add to the FG.
Cheers,
Helder
|
|
|
Re: FG question: retrieve points within polygon [message #89815 is a reply to message #89809] |
Thu, 04 December 2014 07:24   |
lecacheux.alain
Messages: 325 Registered: January 2008
|
Senior Member |
|
|
On Thursday, December 4, 2014 3:32:26 PM UTC+1, Helder wrote:
> On Thursday, December 4, 2014 2:51:28 PM UTC+1, alx wrote:
>> On Thursday, December 4, 2014 10:50:42 AM UTC+1, Helder wrote:
>>> Hi,
>>> I'm looking for an easier way to get the indices inside a polygon or ellipse created in function graphics.
>>> So here is a basic example that states what I want to do:
>>>
>>> ;first generate the graphics
>>> img = dist(600)
>>> w = window(dimensions=[500,500])
>>> im = image(img, current=w)
>>> pl = polygon([0.25,0.75,0.75,0.25],[0.25,0.25,0.75,0.75],/norm,ta rget=im)
>>> ;make some changes to the polygon
>>> pl.rotate, 12
>>>
>>> ;now extract the mean value of the points of the image that are inside the polygon
>>>
>>> pl->getData, xx, yy
>>> o = obj_new('idlanroi', xx*600d, yy*600d, /double, type=2)
>>> mask = o->ComputeMask(dimensions=[600,600])
>>> obj_destroy, o
>>> pts = where(mask, cnt)
>>> meanVal = mean(img[pts])
>>> print, 'the mean value inside the polygon is ', meanVal
>>>
>>>
>>>
>>> So this method works fine. It's maybe not the most obvious, but works. Now the question is... How do I get the same result for an ellipse?
>>> Of course I could calculate the perimeter points of the ellipse and use the same method as above, but that would not really be... well ... cool.
>>>
>>> Any better way to do this? I couldn't find any FG method to get such info.
>>>
>>> Thanks,
>>> Helder
>>
>> If you could plot an ellipse with FG, you know its equation from the parameters (center, axes, orientation) you have given in the call. Let it be F(x,y)=0.
>> Then the indices of the (x,y) points inside the ellipse are those for which F(x,y) is strictly negative.
>> alx.
>
> Hi Alx,
> I wanted to avoid doing myself the calculation, but even trying I found that it is not that possible. It seems like the ellipse() function simply generates a polygon() function. Once created, I could not retrieve the center or radius (major or minor) and cannot therefore compute using the ellipse equation. What I can do is use the undocumented getData method as I would for a polygon and then proceed as if it were a polygon.
>
> Still, a mask method would be a nice add to the FG.
>
> Cheers,
> Helder
Hi Helder,
If you draw the ellipse by calling the ELLIPSE function, you should know everything. If you draw it by hand, you can get the rectangle containing the ellipse by doing (after selecting it):
pos = GetWindows(/CURRENT).GetSelect().Position
then, center and axis lengthes.
alx.
|
|
|
Re: FG question: retrieve points within polygon [message #89816 is a reply to message #89815] |
Thu, 04 December 2014 07:41   |
Helder Marchetto
Messages: 520 Registered: November 2011
|
Senior Member |
|
|
On Thursday, December 4, 2014 4:24:11 PM UTC+1, alx wrote:
> On Thursday, December 4, 2014 3:32:26 PM UTC+1, Helder wrote:
>> On Thursday, December 4, 2014 2:51:28 PM UTC+1, alx wrote:
>>> On Thursday, December 4, 2014 10:50:42 AM UTC+1, Helder wrote:
>>>> Hi,
>>>> I'm looking for an easier way to get the indices inside a polygon or ellipse created in function graphics.
>>>> So here is a basic example that states what I want to do:
>>>>
>>>> ;first generate the graphics
>>>> img = dist(600)
>>>> w = window(dimensions=[500,500])
>>>> im = image(img, current=w)
>>>> pl = polygon([0.25,0.75,0.75,0.25],[0.25,0.25,0.75,0.75],/norm,ta rget=im)
>>>> ;make some changes to the polygon
>>>> pl.rotate, 12
>>>>
>>>> ;now extract the mean value of the points of the image that are inside the polygon
>>>>
>>>> pl->getData, xx, yy
>>>> o = obj_new('idlanroi', xx*600d, yy*600d, /double, type=2)
>>>> mask = o->ComputeMask(dimensions=[600,600])
>>>> obj_destroy, o
>>>> pts = where(mask, cnt)
>>>> meanVal = mean(img[pts])
>>>> print, 'the mean value inside the polygon is ', meanVal
>>>>
>>>>
>>>>
>>>> So this method works fine. It's maybe not the most obvious, but works. Now the question is... How do I get the same result for an ellipse?
>>>> Of course I could calculate the perimeter points of the ellipse and use the same method as above, but that would not really be... well ... cool.
>>>>
>>>> Any better way to do this? I couldn't find any FG method to get such info.
>>>>
>>>> Thanks,
>>>> Helder
>>>
>>> If you could plot an ellipse with FG, you know its equation from the parameters (center, axes, orientation) you have given in the call. Let it be F(x,y)=0.
>>> Then the indices of the (x,y) points inside the ellipse are those for which F(x,y) is strictly negative.
>>> alx.
>>
>> Hi Alx,
>> I wanted to avoid doing myself the calculation, but even trying I found that it is not that possible. It seems like the ellipse() function simply generates a polygon() function. Once created, I could not retrieve the center or radius (major or minor) and cannot therefore compute using the ellipse equation. What I can do is use the undocumented getData method as I would for a polygon and then proceed as if it were a polygon.
>>
>> Still, a mask method would be a nice add to the FG.
>>
>> Cheers,
>> Helder
>
> Hi Helder,
> If you draw the ellipse by calling the ELLIPSE function, you should know everything. If you draw it by hand, you can get the rectangle containing the ellipse by doing (after selecting it):
> pos = GetWindows(/CURRENT).GetSelect().Position
> then, center and axis lengthes.
> alx.
Hi Alx,
thanks.
The idea is that I have a widget window where I move and change my ellipse as I wish.
Say I start with this:
img = dist(600)
w = window(dimensions=[500,500])
im = image(img, current=w)
el = ellipse(300,300,/data, minor=100, major=150, target=im)
and then I modify the ellipse with the mouse (make it bigger, rotate, stretch,...).
The changes that will be made I don't know "a priori", so by stretching and rotating I end up with a completely different ellipse.
I can get the position (as you said) with
pos = el.position
and that gives me always the center as [(pos[0]+pos[2])/2.0,(pos[1]+pos[3])/2.0]. But I cannot retrieve the rotation or the axis and, as far as I understand, there are infinite ellipses that can fit inside the rectangle defined by the position property that have a different set of rotation/axis.
I think that I will have to stick with the polygon type solution using IDLanROI.
Thanks,
Helder
|
|
|
Re: FG question: retrieve points within polygon [message #89819 is a reply to message #89816] |
Thu, 04 December 2014 15:58   |
Jim Pendleton
Messages: 165 Registered: November 2011
|
Senior Member |
|
|
On Thursday, December 4, 2014 8:41:26 AM UTC-7, Helder wrote:
> On Thursday, December 4, 2014 4:24:11 PM UTC+1, alx wrote:
>> On Thursday, December 4, 2014 3:32:26 PM UTC+1, Helder wrote:
>>> On Thursday, December 4, 2014 2:51:28 PM UTC+1, alx wrote:
>>>> On Thursday, December 4, 2014 10:50:42 AM UTC+1, Helder wrote:
>>>> > Hi,
>>>> > I'm looking for an easier way to get the indices inside a polygon or ellipse created in function graphics.
>>>> > So here is a basic example that states what I want to do:
>>>> >
>>>> > ;first generate the graphics
>>>> > img = dist(600)
>>>> > w = window(dimensions=[500,500])
>>>> > im = image(img, current=w)
>>>> > pl = polygon([0.25,0.75,0.75,0.25],[0.25,0.25,0.75,0.75],/norm,ta rget=im)
>>>> > ;make some changes to the polygon
>>>> > pl.rotate, 12
>>>> >
>>>> > ;now extract the mean value of the points of the image that are inside the polygon
>>>> >
>>>> > pl->getData, xx, yy
>>>> > o = obj_new('idlanroi', xx*600d, yy*600d, /double, type=2)
>>>> > mask = o->ComputeMask(dimensions=[600,600])
>>>> > obj_destroy, o
>>>> > pts = where(mask, cnt)
>>>> > meanVal = mean(img[pts])
>>>> > print, 'the mean value inside the polygon is ', meanVal
>>>> >
>>>> >
>>>> >
>>>> > So this method works fine. It's maybe not the most obvious, but works. Now the question is... How do I get the same result for an ellipse?
>>>> > Of course I could calculate the perimeter points of the ellipse and use the same method as above, but that would not really be... well ... cool.
>>>> >
>>>> > Any better way to do this? I couldn't find any FG method to get such info.
>>>> >
>>>> > Thanks,
>>>> > Helder
>>>>
>>>> If you could plot an ellipse with FG, you know its equation from the parameters (center, axes, orientation) you have given in the call. Let it be F(x,y)=0.
>>>> Then the indices of the (x,y) points inside the ellipse are those for which F(x,y) is strictly negative.
>>>> alx.
>>>
>>> Hi Alx,
>>> I wanted to avoid doing myself the calculation, but even trying I found that it is not that possible. It seems like the ellipse() function simply generates a polygon() function. Once created, I could not retrieve the center or radius (major or minor) and cannot therefore compute using the ellipse equation. What I can do is use the undocumented getData method as I would for a polygon and then proceed as if it were a polygon.
>>>
>>> Still, a mask method would be a nice add to the FG.
>>>
>>> Cheers,
>>> Helder
>>
>> Hi Helder,
>> If you draw the ellipse by calling the ELLIPSE function, you should know everything. If you draw it by hand, you can get the rectangle containing the ellipse by doing (after selecting it):
>> pos = GetWindows(/CURRENT).GetSelect().Position
>> then, center and axis lengthes.
>> alx.
>
> Hi Alx,
> thanks.
> The idea is that I have a widget window where I move and change my ellipse as I wish.
> Say I start with this:
>
> img = dist(600)
> w = window(dimensions=[500,500])
> im = image(img, current=w)
> el = ellipse(300,300,/data, minor=100, major=150, target=im)
>
> and then I modify the ellipse with the mouse (make it bigger, rotate, stretch,...).
> The changes that will be made I don't know "a priori", so by stretching and rotating I end up with a completely different ellipse.
>
> I can get the position (as you said) with
>
> pos = el.position
>
> and that gives me always the center as [(pos[0]+pos[2])/2.0,(pos[1]+pos[3])/2.0]. But I cannot retrieve the rotation or the axis and, as far as I understand, there are infinite ellipses that can fit inside the rectangle defined by the position property that have a different set of rotation/axis.
>
> I think that I will have to stick with the polygon type solution using IDLanROI.
>
> Thanks,
> Helder
How adventurous do you want to be? The transformation information is stored in the container of the polygon. The coordinates of the raw data don't actually change after the polygon is created, I would guess.
Let's say you've started a new IDL session and executed the above commands then you've selected and resized or repositioned it interactively. (I'm using IDL 8.4 so YMMV.)
Which object that was created is an IDLgrPolygon?
IDL> oall = obj_valid(/cast)
IDL> print, where(obj_isa(oall, 'idlgrpolygon'))
262 550 568 586 604 621 640 657 676 1894 2089
We have a bunch. One is likely the "main" polygon and the others the "selection" items for resizing and so forth.
Which one is the "main" polygon? Let's guess the first and change its color.
IDL> oall[262]->setproperty, color = [0, 255, 0] & el.refresh
Lucky guess.
Next, let's get its container, which is by definition a model.
IDL> oall[262]->getproperty, parent = omodel
Check out the transformation matrix.
IDL> omodel->getproperty, transform = t
IDL> print, t
0.51712623 0.00000000 0.00000000 55.899910
0.00000000 1.3790130 0.00000000 -120.23054
0.00000000 0.00000000 1.0000000 0.00000000
0.00000000 0.00000000 0.00000000 1.0000000
Of course, you'll have different values here.
Let's send the ellipse back "home":
IDL> t = identity(4)
IDL> omodel->setproperty, transform = t & el.refresh
Teasing out the rotation, translation, and scale from the quaternion is an exercise left for the reader.
In function graphics there's a whole lot of cruft, er, framework, that sits over the top of the most basic graphics atoms and models and knowing how the basic, documented, objects work will go a long way to helping you get closer to what you want.
If the new graphics API doesn't expose exactly the features you want, there are ways to get and modify the data and behaviors, with the possible side effect of producing inconsistent internal states, particularly during interactive use.
Run with scissors.
Jim P.
"I work for Exelis VIS, but these are my own observations"
|
|
|
Re: FG question: retrieve points within polygon [message #89820 is a reply to message #89819] |
Fri, 05 December 2014 01:16   |
Helder Marchetto
Messages: 520 Registered: November 2011
|
Senior Member |
|
|
On Friday, December 5, 2014 12:58:48 AM UTC+1, Jim P wrote:
> On Thursday, December 4, 2014 8:41:26 AM UTC-7, Helder wrote:
>> On Thursday, December 4, 2014 4:24:11 PM UTC+1, alx wrote:
>>> On Thursday, December 4, 2014 3:32:26 PM UTC+1, Helder wrote:
>>>> On Thursday, December 4, 2014 2:51:28 PM UTC+1, alx wrote:
>>>> > On Thursday, December 4, 2014 10:50:42 AM UTC+1, Helder wrote:
>>>> > > Hi,
>>>> > > I'm looking for an easier way to get the indices inside a polygon or ellipse created in function graphics.
>>>> > > So here is a basic example that states what I want to do:
>>>> > >
>>>> > > ;first generate the graphics
>>>> > > img = dist(600)
>>>> > > w = window(dimensions=[500,500])
>>>> > > im = image(img, current=w)
>>>> > > pl = polygon([0.25,0.75,0.75,0.25],[0.25,0.25,0.75,0.75],/norm,ta rget=im)
>>>> > > ;make some changes to the polygon
>>>> > > pl.rotate, 12
>>>> > >
>>>> > > ;now extract the mean value of the points of the image that are inside the polygon
>>>> > >
>>>> > > pl->getData, xx, yy
>>>> > > o = obj_new('idlanroi', xx*600d, yy*600d, /double, type=2)
>>>> > > mask = o->ComputeMask(dimensions=[600,600])
>>>> > > obj_destroy, o
>>>> > > pts = where(mask, cnt)
>>>> > > meanVal = mean(img[pts])
>>>> > > print, 'the mean value inside the polygon is ', meanVal
>>>> > >
>>>> > >
>>>> > >
>>>> > > So this method works fine. It's maybe not the most obvious, but works. Now the question is... How do I get the same result for an ellipse?
>>>> > > Of course I could calculate the perimeter points of the ellipse and use the same method as above, but that would not really be... well ... cool.
>>>> > >
>>>> > > Any better way to do this? I couldn't find any FG method to get such info.
>>>> > >
>>>> > > Thanks,
>>>> > > Helder
>>>> >
>>>> > If you could plot an ellipse with FG, you know its equation from the parameters (center, axes, orientation) you have given in the call. Let it be F(x,y)=0.
>>>> > Then the indices of the (x,y) points inside the ellipse are those for which F(x,y) is strictly negative.
>>>> > alx.
>>>>
>>>> Hi Alx,
>>>> I wanted to avoid doing myself the calculation, but even trying I found that it is not that possible. It seems like the ellipse() function simply generates a polygon() function. Once created, I could not retrieve the center or radius (major or minor) and cannot therefore compute using the ellipse equation. What I can do is use the undocumented getData method as I would for a polygon and then proceed as if it were a polygon.
>>>>
>>>> Still, a mask method would be a nice add to the FG.
>>>>
>>>> Cheers,
>>>> Helder
>>>
>>> Hi Helder,
>>> If you draw the ellipse by calling the ELLIPSE function, you should know everything. If you draw it by hand, you can get the rectangle containing the ellipse by doing (after selecting it):
>>> pos = GetWindows(/CURRENT).GetSelect().Position
>>> then, center and axis lengthes.
>>> alx.
>>
>> Hi Alx,
>> thanks.
>> The idea is that I have a widget window where I move and change my ellipse as I wish.
>> Say I start with this:
>>
>> img = dist(600)
>> w = window(dimensions=[500,500])
>> im = image(img, current=w)
>> el = ellipse(300,300,/data, minor=100, major=150, target=im)
>>
>> and then I modify the ellipse with the mouse (make it bigger, rotate, stretch,...).
>> The changes that will be made I don't know "a priori", so by stretching and rotating I end up with a completely different ellipse.
>>
>> I can get the position (as you said) with
>>
>> pos = el.position
>>
>> and that gives me always the center as [(pos[0]+pos[2])/2.0,(pos[1]+pos[3])/2.0]. But I cannot retrieve the rotation or the axis and, as far as I understand, there are infinite ellipses that can fit inside the rectangle defined by the position property that have a different set of rotation/axis.
>>
>> I think that I will have to stick with the polygon type solution using IDLanROI.
>>
>> Thanks,
>> Helder
>
> How adventurous do you want to be? The transformation information is stored in the container of the polygon. The coordinates of the raw data don't actually change after the polygon is created, I would guess.
>
> Let's say you've started a new IDL session and executed the above commands then you've selected and resized or repositioned it interactively. (I'm using IDL 8.4 so YMMV.)
>
> Which object that was created is an IDLgrPolygon?
>
> IDL> oall = obj_valid(/cast)
> IDL> print, where(obj_isa(oall, 'idlgrpolygon'))
> 262 550 568 586 604 621 640 657 676 1894 2089
>
> We have a bunch. One is likely the "main" polygon and the others the "selection" items for resizing and so forth.
>
> Which one is the "main" polygon? Let's guess the first and change its color.
>
> IDL> oall[262]->setproperty, color = [0, 255, 0] & el.refresh
>
> Lucky guess.
>
> Next, let's get its container, which is by definition a model.
>
> IDL> oall[262]->getproperty, parent = omodel
>
> Check out the transformation matrix.
>
> IDL> omodel->getproperty, transform = t
> IDL> print, t
> 0.51712623 0.00000000 0.00000000 55.899910
> 0.00000000 1.3790130 0.00000000 -120.23054
> 0.00000000 0.00000000 1.0000000 0.00000000
> 0.00000000 0.00000000 0.00000000 1.0000000
>
> Of course, you'll have different values here.
>
> Let's send the ellipse back "home":
>
> IDL> t = identity(4)
> IDL> omodel->setproperty, transform = t & el.refresh
>
> Teasing out the rotation, translation, and scale from the quaternion is an exercise left for the reader.
>
> In function graphics there's a whole lot of cruft, er, framework, that sits over the top of the most basic graphics atoms and models and knowing how the basic, documented, objects work will go a long way to helping you get closer to what you want.
>
> If the new graphics API doesn't expose exactly the features you want, there are ways to get and modify the data and behaviors, with the possible side effect of producing inconsistent internal states, particularly during interactive use.
>
> Run with scissors.
>
> Jim P.
> "I work for Exelis VIS, but these are my own observations"
Hi Jim,
thanks for your insights into FG. To me most (=all) of what's happening behind the scenes is a mystery, therefore such demos are enlightening.
With that said, my program is somewhat complicated and it might have to deal with more instances of ellipses and things might get nasty I'm not sure that going through all this trouble would actually give me an advantage over getting the mask using the point coordinates used to draw the ellipse in the polygon object and feeding them in an IDLanROI object.
I like anyway to fiddle around with these things, therefore I tried to get your code running and got stuck pretty soon. It seems like I can't change the color of the "main" polygon.
Here is the code I've tested and I've put a break in the for loop to check the color of the ellipse.
pro testEllipse
img = dist(600)
w = window(dimensions=[500,500])
im = image(img, current=w)
el = ellipse(300,300,'r3', /data, minor=100, major=150, target=im, fill_background=0)
el->rotate, 15
el->translate, 40,60
oall = obj_valid(/cast)
polys = where(obj_isa(oall, 'idlgrpolygon'))
for i=0,n_elements(polys)-1 do begin
oall[polys[i]]->getproperty, color = c
print, 'starting color = ', c
oall[polys[i]]->setproperty, color = [0,255,0]
el.refresh
;insert break in the following line to check if the ellipse has changed color
print, 'color set'
oall[polys[i]]->setproperty, color = c
el.refresh
endfor
end
It so happens that the ellipse stays as it is. Interestingly, the colors I get from the objects I scan through are:
3 times [255,255,255]
8 times [30,144,255]
I get no red ([255,0,0]).
Since you have more insight than I do, I'll ask you the following:
What is the probability that in the near future (<1year) Exelis implements a mask for objects like Polygons and Ellipses?
I doesn't seem to me like a too complicated thing to implement if you have access (and understanding) to the lower layers of IDL FG and access to the mask method used for IDLanROI.
Thanks,
Helder
|
|
|
Re: FG question: retrieve points within polygon [message #89823 is a reply to message #89820] |
Fri, 05 December 2014 08:23  |
Jim Pendleton
Messages: 165 Registered: November 2011
|
Senior Member |
|
|
On Friday, December 5, 2014 2:16:16 AM UTC-7, Helder wrote:
> On Friday, December 5, 2014 12:58:48 AM UTC+1, Jim P wrote:
>> On Thursday, December 4, 2014 8:41:26 AM UTC-7, Helder wrote:
>>> On Thursday, December 4, 2014 4:24:11 PM UTC+1, alx wrote:
>>>> On Thursday, December 4, 2014 3:32:26 PM UTC+1, Helder wrote:
>>>> > On Thursday, December 4, 2014 2:51:28 PM UTC+1, alx wrote:
>>>> > > On Thursday, December 4, 2014 10:50:42 AM UTC+1, Helder wrote:
>>>> > > > Hi,
>>>> > > > I'm looking for an easier way to get the indices inside a polygon or ellipse created in function graphics.
>>>> > > > So here is a basic example that states what I want to do:
>>>> > > >
>>>> > > > ;first generate the graphics
>>>> > > > img = dist(600)
>>>> > > > w = window(dimensions=[500,500])
>>>> > > > im = image(img, current=w)
>>>> > > > pl = polygon([0.25,0.75,0.75,0.25],[0.25,0.25,0.75,0.75],/norm,ta rget=im)
>>>> > > > ;make some changes to the polygon
>>>> > > > pl.rotate, 12
>>>> > > >
>>>> > > > ;now extract the mean value of the points of the image that are inside the polygon
>>>> > > >
>>>> > > > pl->getData, xx, yy
>>>> > > > o = obj_new('idlanroi', xx*600d, yy*600d, /double, type=2)
>>>> > > > mask = o->ComputeMask(dimensions=[600,600])
>>>> > > > obj_destroy, o
>>>> > > > pts = where(mask, cnt)
>>>> > > > meanVal = mean(img[pts])
>>>> > > > print, 'the mean value inside the polygon is ', meanVal
>>>> > > >
>>>> > > >
>>>> > > >
>>>> > > > So this method works fine. It's maybe not the most obvious, but works. Now the question is... How do I get the same result for an ellipse?
>>>> > > > Of course I could calculate the perimeter points of the ellipse and use the same method as above, but that would not really be... well ... cool.
>>>> > > >
>>>> > > > Any better way to do this? I couldn't find any FG method to get such info.
>>>> > > >
>>>> > > > Thanks,
>>>> > > > Helder
>>>> > >
>>>> > > If you could plot an ellipse with FG, you know its equation from the parameters (center, axes, orientation) you have given in the call. Let it be F(x,y)=0.
>>>> > > Then the indices of the (x,y) points inside the ellipse are those for which F(x,y) is strictly negative.
>>>> > > alx.
>>>> >
>>>> > Hi Alx,
>>>> > I wanted to avoid doing myself the calculation, but even trying I found that it is not that possible. It seems like the ellipse() function simply generates a polygon() function. Once created, I could not retrieve the center or radius (major or minor) and cannot therefore compute using the ellipse equation. What I can do is use the undocumented getData method as I would for a polygon and then proceed as if it were a polygon.
>>>> >
>>>> > Still, a mask method would be a nice add to the FG.
>>>> >
>>>> > Cheers,
>>>> > Helder
>>>>
>>>> Hi Helder,
>>>> If you draw the ellipse by calling the ELLIPSE function, you should know everything. If you draw it by hand, you can get the rectangle containing the ellipse by doing (after selecting it):
>>>> pos = GetWindows(/CURRENT).GetSelect().Position
>>>> then, center and axis lengthes.
>>>> alx.
>>>
>>> Hi Alx,
>>> thanks.
>>> The idea is that I have a widget window where I move and change my ellipse as I wish.
>>> Say I start with this:
>>>
>>> img = dist(600)
>>> w = window(dimensions=[500,500])
>>> im = image(img, current=w)
>>> el = ellipse(300,300,/data, minor=100, major=150, target=im)
>>>
>>> and then I modify the ellipse with the mouse (make it bigger, rotate, stretch,...).
>>> The changes that will be made I don't know "a priori", so by stretching and rotating I end up with a completely different ellipse.
>>>
>>> I can get the position (as you said) with
>>>
>>> pos = el.position
>>>
>>> and that gives me always the center as [(pos[0]+pos[2])/2.0,(pos[1]+pos[3])/2.0]. But I cannot retrieve the rotation or the axis and, as far as I understand, there are infinite ellipses that can fit inside the rectangle defined by the position property that have a different set of rotation/axis.
>>>
>>> I think that I will have to stick with the polygon type solution using IDLanROI.
>>>
>>> Thanks,
>>> Helder
>>
>> How adventurous do you want to be? The transformation information is stored in the container of the polygon. The coordinates of the raw data don't actually change after the polygon is created, I would guess.
>>
>> Let's say you've started a new IDL session and executed the above commands then you've selected and resized or repositioned it interactively. (I'm using IDL 8.4 so YMMV.)
>>
>> Which object that was created is an IDLgrPolygon?
>>
>> IDL> oall = obj_valid(/cast)
>> IDL> print, where(obj_isa(oall, 'idlgrpolygon'))
>> 262 550 568 586 604 621 640 657 676 1894 2089
>>
>> We have a bunch. One is likely the "main" polygon and the others the "selection" items for resizing and so forth.
>>
>> Which one is the "main" polygon? Let's guess the first and change its color.
>>
>> IDL> oall[262]->setproperty, color = [0, 255, 0] & el.refresh
>>
>> Lucky guess.
>>
>> Next, let's get its container, which is by definition a model.
>>
>> IDL> oall[262]->getproperty, parent = omodel
>>
>> Check out the transformation matrix.
>>
>> IDL> omodel->getproperty, transform = t
>> IDL> print, t
>> 0.51712623 0.00000000 0.00000000 55.899910
>> 0.00000000 1.3790130 0.00000000 -120.23054
>> 0.00000000 0.00000000 1.0000000 0.00000000
>> 0.00000000 0.00000000 0.00000000 1.0000000
>>
>> Of course, you'll have different values here.
>>
>> Let's send the ellipse back "home":
>>
>> IDL> t = identity(4)
>> IDL> omodel->setproperty, transform = t & el.refresh
>>
>> Teasing out the rotation, translation, and scale from the quaternion is an exercise left for the reader.
>>
>> In function graphics there's a whole lot of cruft, er, framework, that sits over the top of the most basic graphics atoms and models and knowing how the basic, documented, objects work will go a long way to helping you get closer to what you want.
>>
>> If the new graphics API doesn't expose exactly the features you want, there are ways to get and modify the data and behaviors, with the possible side effect of producing inconsistent internal states, particularly during interactive use.
>>
>> Run with scissors.
>>
>> Jim P.
>> "I work for Exelis VIS, but these are my own observations"
>
> Hi Jim,
> thanks for your insights into FG. To me most (=all) of what's happening behind the scenes is a mystery, therefore such demos are enlightening.
> With that said, my program is somewhat complicated and it might have to deal with more instances of ellipses and things might get nasty I'm not sure that going through all this trouble would actually give me an advantage over getting the mask using the point coordinates used to draw the ellipse in the polygon object and feeding them in an IDLanROI object.
>
> I like anyway to fiddle around with these things, therefore I tried to get your code running and got stuck pretty soon. It seems like I can't change the color of the "main" polygon.
> Here is the code I've tested and I've put a break in the for loop to check the color of the ellipse.
>
> pro testEllipse
> img = dist(600)
> w = window(dimensions=[500,500])
> im = image(img, current=w)
> el = ellipse(300,300,'r3', /data, minor=100, major=150, target=im, fill_background=0)
> el->rotate, 15
> el->translate, 40,60
> oall = obj_valid(/cast)
> polys = where(obj_isa(oall, 'idlgrpolygon'))
> for i=0,n_elements(polys)-1 do begin
> oall[polys[i]]->getproperty, color = c
> print, 'starting color = ', c
> oall[polys[i]]->setproperty, color = [0,255,0]
> el.refresh
> ;insert break in the following line to check if the ellipse has changed color
> print, 'color set'
> oall[polys[i]]->setproperty, color = c
> el.refresh
> endfor
> end
>
> It so happens that the ellipse stays as it is. Interestingly, the colors I get from the objects I scan through are:
> 3 times [255,255,255]
> 8 times [30,144,255]
> I get no red ([255,0,0]).
>
> Since you have more insight than I do, I'll ask you the following:
>
> What is the probability that in the near future (<1year) Exelis implements a mask for objects like Polygons and Ellipses?
>
> I doesn't seem to me like a too complicated thing to implement if you have access (and understanding) to the lower layers of IDL FG and access to the mask method used for IDLanROI.
>
> Thanks,
> Helder
Ah, I see what you did there. You changed the problem on me.
The color that I was setting was the fill color on the filled IDLgrPolygon from your first example. You're attempting to change the line color. The ellipse graphic you're creating is a composite of objects. One is the filled IDLgrPolygon. Another is the IDLgrPolyline that serves as the outline. Armed with that info, you should be able to make further progress. (A shortcut is to know that for our scene the IDLgrPolygon and its associated IDLgrPolyline likely both belong to the same parent, if there are lots of polylines in a scene.)
Here's the transform of the first point, showing how the effects of the rotation and translation operations:
IDL> oall[polys[0]]->getproperty, parent = p
IDL> p->getproperty, transform = t
IDL> oall[polys[0]]->getproperty, data = data
IDL> help, data
DATA DOUBLE = Array[3, 182]
IDL> print, data[*, 0]
450.00000 300.00000 0.00000000
IDL> print, [data[*, 0], 1] # t
498.22221
418.82286
0.00000000
1.0000000
I will need to defer to the always-knowledgeable Chris T. with respect to what may or may not appear in the IDL language or graphics features in the future. My wishlist has been quite lengthy for decades, but I'm usually on the naughty-not-nice list. I got a sock full of gifts with 8.4 this year, but many years I've received lumps of coal. Running with scissors takes a toll on one's rep.
Jim P.
|
|
|