Re: CURSOR skips a few beats :-( [message #69619] |
Fri, 29 January 2010 13:33  |
cgguido
Messages: 195 Registered: August 2005
|
Senior Member |
|
|
I am glad Google is immortalizing all this: THE David Fanning just
called *me* his friend! Wot?! If only JD Smith would follow suit I
could retire happy :-)
David - It seems to me that allowing the user to measure thickness at
arbitrary points could allow for a few sources of error: Are the
starting points chosen uniformly along the lumen? are the ending
points really the closest ones? Of course, in many cases determining
where exactly the lumen/tissue (or any other) edge is, is itself a
difficult problem... My thinking was that if the user draws what he/
she is happy calling an edge (I am not a biologist - it all looks
fuzzy to me), then I can measure the shortest distance at all points,
and therefore eliminate some error. (BTW, we're looking at the
effectiveness of various tissues as a barrier to virus particles....)
David and paulv - Why do widgets act as anti-hatered shields?
Literally, all I want is for the user to choose two borderlines. I
will then spit out a list of thicknesses to a text file so the
biologists can use Excel and carry on. Most of the code that does
other "fancy" analysis (particle tracking, etc.) is used from the
command line. I could write GUIs for all this, I just don't really see
the advantages given that we are dealing with simple operations... Can
you point me to a thread that expands on the advantages of Widgets in
scientific computing? - I *am* interested. And why not go all the way
and use custom iTool interface then? (PS It is important to me that
this works with X11 forwarding over ssh...) I am not trying to bash
widgets or objects - I promise I am only trying to understand if these
approaches are worth the coding time, given the task and audience.
paulv - thanks for the link. Didn't know this stuff had a name!
pp - type=1 it is! much neater than my IF THEN WHAT? statements
By the way, the code above seems to work ok. One problem is when the
cursor exits the window and come back in, IDL looses it: you need to
re-click on the X11 window...
Sincere thanks to all of you for your help and patience.
Gianguido
|
|
|
Re: CURSOR skips a few beats :-( [message #69620 is a reply to message #69619] |
Fri, 29 January 2010 10:08   |
penteado
Messages: 866 Registered: February 2018
|
Senior Member Administrator |
|
|
On Jan 29, 3:04 pm, Gianguido Cianci <gianguido.cia...@gmail.com>
wrote:
> pp - I would not want to get the bounding polygon, but rather the path
> that joins the points. reading the docs right now. Thanks for pointing
> me in that direction :-)
I guess I was thinking of closed paths, with no crossovers, in which
case the bounding polygon is the same as the path. To get paths the
way you seem to want, use
oroi=obj_new('idlanroi',x,y,type=1)
instead. By default, an ROI is type 2 (closed polygon), but type 1
makes it a path.
Also, note that though IDLanROI is an object, it has nothing to do
with object graphics. It exists without having anything to do with any
graphics (object or direct), it is just defined from coordinates (as
in the artificial coordinates I made up). There is an object graphics
representation for ROIs (IDLgrROI), though that is a different object.
|
|
|
Re: CURSOR skips a few beats :-( [message #69621 is a reply to message #69620] |
Fri, 29 January 2010 09:58   |
Paul Van Delst[1]
Messages: 1157 Registered: April 2002
|
Senior Member |
|
|
Gianguido Cianci wrote:
> On Jan 27, 4:29 pm, David Fanning <n...@dfanning.com> wrote:
>> Well, you can do shapes easily enough just by connecting
>> the dots. For example, in AnnotateWindow you can choose
>> a pencil cursor and draw whatever shape you like (if you
>> have any drawing talent, of course). You just can't get
>> ALL the points the cursor crosses over. I don't think
>> object graphics will help in this case, either. You will
>> have learned them for nothing. :-)
>>
>
> Right, you can join the dots... so when IDL plots the line between the
> dots, it calculates which pixels need to turn white. How do I get the
> coords of all those pixels?
Maybe you can reverse engineer Brensenham's algorithm?
See: http://en.wikipedia.org/wiki/Bresenham's_line_algorithm
cheers,
paulv
p.s. BTW, David Fanning is correct - you should make this a widget program.
>
> I have come up with a three-step linear interpolation that I do
> between each pair of points and it seems to be working (with 2 probs).
> here is a snippet:
>
> pro dlines
>
> f_xsize = 300
> f_ysize = 300
>
> map = bytarr(f_xsize, f_ysize,2)*0b
>
> FOR line = 0, 1 DO BEGIN
> cursor, d1, d2, /down, /device
> device, cursor_standard = 32
> !mouse.button=0
> x1 = 0 > d1 < f_xsize-1
> y1 = 0 > d2 < f_ysize-1
> WHILE (!MOUSE.button NE 4) DO BEGIN
> plots, x1, y1, /device, ps = 3, color = fsc_color((['green',
> 'red'])[line])
> map[x1,y1, line] = 1b
> oldx = x1
> oldy = y1
> CURSOR, X1, Y1, /device,1
> x1 = 0 > x1 < f_xsize-1
> y1 = 0 > y1 < f_ysize-1
>
> dx = abs(x1-oldx)
> dy = abs(y1-oldy)
> l = sqrt((dx)^2+(dy)^2)
> IF ~keyword_set(nointerpolation) AND l GT sqrt(2) THEN BEGIN
> IF dx EQ 0 THEN BEGIN ; if I need to interpolate
> a vertical segment
> xx = indgen(dy)+min([y1, oldy]) ;new x's
> yy = round(interpol([x1, oldx], [y1, oldy], xx))
> map[yy,xx, replicate(line, n_elements(xx)) ] = 1b
> ENDIF ELSE BEGIN ; all other orientations
> xx = indgen(dx)+min([x1, oldx]) ;new x's
> yy = round(interpol([y1, oldy], [x1, oldx], xx))
> map[xx,yy, replicate(line, n_elements(xx)) ] = 1b
>
> ;;need to do this for certain diagonals
> IF dy NE 0 THEN BEGIN xx = indgen(dy)+min([y1,
> oldy]) ;new x's
> yy = round(interpol([x1, oldx], [y1, oldy], xx))
> map[yy,xx, replicate(line, n_elements(xx)) ] = 1b
> ENDIF
> ENDELSE
> ENDIF
> ENDWHILE
> w = where(map[*,*,line] EQ 1b)
> a = array_indices(map[*,*,line], w)
> device, /cursor_crosshair
> ENDFOR
>
> END
>
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
>
> Problem #1: it is not very pretty, but I could live with that I
> suppose. Though I feel there must be a better way.
>
> Problem #2: when you (slowly!) move the mouse out of the left edge of
> the window the program crashes because x1= 0>x1<f_xsize-1 sets x1 to
> -1!!! And I can't figure that one out :-(
>
>
>> P.S. Even using the pencil tool in something like Photoshop
>> you see that if you move your pencil fast you get a straight
>> line, while if you move it slowly you can get a nice even
>> bend in the line. I think this is a function of your
>> medium (a computer) and not a function of your art skills.
>>
>
> Hmm... I am not sure where you're going with the above. I hope the
> first part of this reply and the code clarify my issues...
>
>
> Thanks,
> Gianguido
|
|
|
Re: CURSOR skips a few beats :-( [message #69622 is a reply to message #69621] |
Fri, 29 January 2010 09:21   |
David Fanning
Messages: 11724 Registered: August 2001
|
Senior Member |
|
|
Gianguido Cianci writes:
> Some quick background about the project. We are taking micrographs of
> tissue samples (mostly skin). I am writing a set of IDL programs that
> would allow others in the lab to draw two curves on the picture, say
> along the lumen and along the edge of some skin layer, and then
> calculate the thickness of that part of the skin. I define thickness
> as the shortest path from each point in the lumen line to any point in
> the inner line. So far so good.
>
> The problem is that without the interpolation above, while you move
> along a straight-ish part of the tissue (you can therefore move faster
> with less error) you get a few points. On the other hand, if there is
> a part of the tissue that is convoluted (and the user instinctively
> slows down) you get more, or even every, point the mouse visits. This
> behaviour would bias the average thickness value toward the thickness
> of convoluted parts of the tissue, and that's not cool.
I can see problems with this approach. What about allowing the
user to actually measure the distance themselves with some kind
of measuring tool? (You can look to AnnotateWindow again, or to
the Catalyst example application for an example of such a tool.)
The user could click in one location, and move the cursor (the
tool now follows the user's movements) to another location and
click to record the measurement. You could take any number of
measurements, then do statistics on the measurements to get
an accurate value. This avoids a lot of problems, and gives
the user a sense of what they are *actually* doing. And, it is
easier to select individual points then it is to draw a line
on a computer.
> What do you guys think? I fear I may be reinventing a few wheels,
> maybe a whole set of wheels.
If you continue to do this with the CURSOR command, it will
be like reinventing us all the way back to the stone age. :-)
> pp - your way seems much simpler to read... I am starting to see why
> these here objects are cool... I will investigate further.
Objects are cool, although I think the IDLanROI object is
probably the wrong tool for the job here.
But, seriously, Gianguido, my friend, if you don't start
writing this program as a widget program of some kind, your
users are going to end up hating you. :-)
Cheers,
David
--
David Fanning, Ph.D.
Fanning Software Consulting, Inc.
Coyote's Guide to IDL Programming: http://www.dfanning.com/
Sepore ma de ni thui. ("Perhaps thou speakest truth.")
|
|
|
Re: CURSOR skips a few beats :-( [message #69623 is a reply to message #69622] |
Fri, 29 January 2010 09:04   |
cgguido
Messages: 195 Registered: August 2005
|
Senior Member |
|
|
On Jan 28, 7:57 pm, pp <pp.pente...@gmail.com> wrote:
> On Jan 28, 8:38 pm, Gianguido Cianci <gianguido.cia...@gmail.com>
> wrote:
>
>> Right, you can join the dots... so when IDL plots the line between the
>> dots, it calculates which pixels need to turn white. How do I get the
>> coords of all those pixels?
>
> You can do it with an ROI:
>
> ;make up some x,y pixel coordinates
> dims=[200,200]
> x=randomu(seed,10)*dims[0] & x=x[sort(x)] & x=[x,reverse(x)]
> y=(1d0+([randomu(seed,10),-randomu(seed,10)]))*dims[1]/2
> ;take look at the points
> iplot,x,y
> ;define an ROI with those vertices
> oroi=obj_new('idlanroi',x,y)
> ;get the pixels that lie on the boundary
> bound=oroi->computemask(dimensions=dims,mask_rule=0)
> ;take a look at the result
> iimage,bound
> ;get the coordinates of the boundary pixels
> w=where(bound eq 255B)
> xy_bound=array_indices(bound,w)
pp - I would not want to get the bounding polygon, but rather the path
that joins the points. reading the docs right now. Thanks for pointing
me in that direction :-)
Gianguido
|
|
|
Re: CURSOR skips a few beats :-( [message #69624 is a reply to message #69623] |
Fri, 29 January 2010 09:00   |
cgguido
Messages: 195 Registered: August 2005
|
Senior Member |
|
|
Thanks David and pp.
David - yes, I solved that rookie operator precedence mistake while
hitting myself in the forehead! :-(
Some quick background about the project. We are taking micrographs of
tissue samples (mostly skin). I am writing a set of IDL programs that
would allow others in the lab to draw two curves on the picture, say
along the lumen and along the edge of some skin layer, and then
calculate the thickness of that part of the skin. I define thickness
as the shortest path from each point in the lumen line to any point in
the inner line. So far so good.
The problem is that without the interpolation above, while you move
along a straight-ish part of the tissue (you can therefore move faster
with less error) you get a few points. On the other hand, if there is
a part of the tissue that is convoluted (and the user instinctively
slows down) you get more, or even every, point the mouse visits. This
behaviour would bias the average thickness value toward the thickness
of convoluted parts of the tissue, and that's not cool.
What do you guys think? I fear I may be reinventing a few wheels,
maybe a whole set of wheels.
pp - your way seems much simpler to read... I am starting to see why
these here objects are cool... I will investigate further.
Thanks again to both of you.
Gianguido
|
|
|
Re: CURSOR skips a few beats :-( [message #69626 is a reply to message #69624] |
Thu, 28 January 2010 17:57   |
penteado
Messages: 866 Registered: February 2018
|
Senior Member Administrator |
|
|
On Jan 28, 8:38 pm, Gianguido Cianci <gianguido.cia...@gmail.com>
wrote:
> Right, you can join the dots... so when IDL plots the line between the
> dots, it calculates which pixels need to turn white. How do I get the
> coords of all those pixels?
You can do it with an ROI:
;make up some x,y pixel coordinates
dims=[200,200]
x=randomu(seed,10)*dims[0] & x=x[sort(x)] & x=[x,reverse(x)]
y=(1d0+([randomu(seed,10),-randomu(seed,10)]))*dims[1]/2
;take look at the points
iplot,x,y
;define an ROI with those vertices
oroi=obj_new('idlanroi',x,y)
;get the pixels that lie on the boundary
bound=oroi->computemask(dimensions=dims,mask_rule=0)
;take a look at the result
iimage,bound
;get the coordinates of the boundary pixels
w=where(bound eq 255B)
xy_bound=array_indices(bound,w)
|
|
|
Re: CURSOR skips a few beats :-( [message #69628 is a reply to message #69626] |
Thu, 28 January 2010 15:35   |
David Fanning
Messages: 11724 Registered: August 2001
|
Senior Member |
|
|
Gianguido Cianci writes:
> Right, you can join the dots... so when IDL plots the line between the
> dots, it calculates which pixels need to turn white. How do I get the
> coords of all those pixels?
I'm not trying to be a smart-aleck here, but why do you
want them? (I'm trying to figure out the best way to
answer your question. Maybe the best way is to avoid
the headache of getting things you don't need!) Anyway,
what are you going to do with them when you get them?
> I have come up with a three-step linear interpolation that I do
> between each pair of points and it seems to be working (with 2 probs).
> here is a snippet:
Uh, have you given any thought to writing a widget program? :-)
> Problem #1: it is not very pretty, but I could live with that I
> suppose. Though I feel there must be a better way.
I think so, too, but I can't tell yet what it is.
> Problem #2: when you (slowly!) move the mouse out of the left edge of
> the window the program crashes because x1= 0>x1<f_xsize-1 sets x1 to
> -1!!! And I can't figure that one out :-(
Well, this is one of the most common gotchas in IDL! You
need parentheses.
x1 = 0 > x1 < (f_xsize-1)
Cheers,
David
--
David Fanning, Ph.D.
Fanning Software Consulting, Inc.
Coyote's Guide to IDL Programming: http://www.dfanning.com/
Sepore ma de ni thui. ("Perhaps thou speakest truth.")
|
|
|
Re: CURSOR skips a few beats :-( [message #69630 is a reply to message #69628] |
Thu, 28 January 2010 14:38   |
cgguido
Messages: 195 Registered: August 2005
|
Senior Member |
|
|
On Jan 27, 4:29 pm, David Fanning <n...@dfanning.com> wrote:
> Well, you can do shapes easily enough just by connecting
> the dots. For example, in AnnotateWindow you can choose
> a pencil cursor and draw whatever shape you like (if you
> have any drawing talent, of course). You just can't get
> ALL the points the cursor crosses over. I don't think
> object graphics will help in this case, either. You will
> have learned them for nothing. :-)
>
Right, you can join the dots... so when IDL plots the line between the
dots, it calculates which pixels need to turn white. How do I get the
coords of all those pixels?
I have come up with a three-step linear interpolation that I do
between each pair of points and it seems to be working (with 2 probs).
here is a snippet:
pro dlines
f_xsize = 300
f_ysize = 300
map = bytarr(f_xsize, f_ysize,2)*0b
FOR line = 0, 1 DO BEGIN
cursor, d1, d2, /down, /device
device, cursor_standard = 32
!mouse.button=0
x1 = 0 > d1 < f_xsize-1
y1 = 0 > d2 < f_ysize-1
WHILE (!MOUSE.button NE 4) DO BEGIN
plots, x1, y1, /device, ps = 3, color = fsc_color((['green',
'red'])[line])
map[x1,y1, line] = 1b
oldx = x1
oldy = y1
CURSOR, X1, Y1, /device,1
x1 = 0 > x1 < f_xsize-1
y1 = 0 > y1 < f_ysize-1
dx = abs(x1-oldx)
dy = abs(y1-oldy)
l = sqrt((dx)^2+(dy)^2)
IF ~keyword_set(nointerpolation) AND l GT sqrt(2) THEN BEGIN
IF dx EQ 0 THEN BEGIN ; if I need to interpolate
a vertical segment
xx = indgen(dy)+min([y1, oldy]) ;new x's
yy = round(interpol([x1, oldx], [y1, oldy], xx))
map[yy,xx, replicate(line, n_elements(xx)) ] = 1b
ENDIF ELSE BEGIN ; all other orientations
xx = indgen(dx)+min([x1, oldx]) ;new x's
yy = round(interpol([y1, oldy], [x1, oldx], xx))
map[xx,yy, replicate(line, n_elements(xx)) ] = 1b
;;need to do this for certain diagonals
IF dy NE 0 THEN BEGIN xx = indgen(dy)+min([y1,
oldy]) ;new x's
yy = round(interpol([x1, oldx], [y1, oldy], xx))
map[yy,xx, replicate(line, n_elements(xx)) ] = 1b
ENDIF
ENDELSE
ENDIF
ENDWHILE
w = where(map[*,*,line] EQ 1b)
a = array_indices(map[*,*,line], w)
device, /cursor_crosshair
ENDFOR
END
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Problem #1: it is not very pretty, but I could live with that I
suppose. Though I feel there must be a better way.
Problem #2: when you (slowly!) move the mouse out of the left edge of
the window the program crashes because x1= 0>x1<f_xsize-1 sets x1 to
-1!!! And I can't figure that one out :-(
> P.S. Even using the pencil tool in something like Photoshop
> you see that if you move your pencil fast you get a straight
> line, while if you move it slowly you can get a nice even
> bend in the line. I think this is a function of your
> medium (a computer) and not a function of your art skills.
>
Hmm... I am not sure where you're going with the above. I hope the
first part of this reply and the code clarify my issues...
Thanks,
Gianguido
|
|
|
Re: CURSOR skips a few beats :-( [message #69644 is a reply to message #69630] |
Wed, 27 January 2010 14:29   |
David Fanning
Messages: 11724 Registered: August 2001
|
Senior Member |
|
|
Gianguido Cianci writes:
> ok :-( At least I didn't miss an obvious /FLASH_AAHAAAH flag to
> CURSOR :-)
>
> Then: Can you do a linear interpolation of points that are in "funny"
> shapes, like say a figure-8 or some random bee-trajectory, joining
> dots with straight segments?
> Or: Is this what's going to make me learn object (abject?)
> graphics ;-) ?
Well, you can do shapes easily enough just by connecting
the dots. For example, in AnnotateWindow you can choose
a pencil cursor and draw whatever shape you like (if you
have any drawing talent, of course). You just can't get
ALL the points the cursor crosses over. I don't think
object graphics will help in this case, either. You will
have learned them for nothing. :-)
Cheers,
David
P.S. Even using the pencil tool in something like Photoshop
you see that if you move your pencil fast you get a straight
line, while if you move it slowly you can get a nice even
bend in the line. I think this is a function of your
medium (a computer) and not a function of your art skills.
--
David Fanning, Ph.D.
Fanning Software Consulting, Inc.
Coyote's Guide to IDL Programming: http://www.dfanning.com/
Sepore ma de ni thui. ("Perhaps thou speakest truth.")
|
|
|
|
|
Re: CURSOR skips a few beats :-( [message #69718 is a reply to message #69619] |
Fri, 29 January 2010 14:25  |
David Fanning
Messages: 11724 Registered: August 2001
|
Senior Member |
|
|
Gianguido Cianci writes:
> I am glad Google is immortalizing all this: THE David Fanning just
> called *me* his friend! Wot?! If only JD Smith would follow suit I
> could retire happy :-)
To get JD to notice, you have to write something that looks
like five or six programs on one line. Use a LOT of parentheses.
Now that I look at your code again, you are not too far off. ;-)
> David - It seems to me that allowing the user to measure thickness at
> arbitrary points could allow for a few sources of error: Are the
> starting points chosen uniformly along the lumen? are the ending
> points really the closest ones? Of course, in many cases determining
> where exactly the lumen/tissue (or any other) edge is, is itself a
> difficult problem... My thinking was that if the user draws what he/
> she is happy calling an edge (I am not a biologist - it all looks
> fuzzy to me), then I can measure the shortest distance at all points,
> and therefore eliminate some error. (BTW, we're looking at the
> effectiveness of various tissues as a barrier to virus particles....)
Well, I just foresee the measurements bouncing off in all kinds
of directions, so that you are never really measuring what you
think you are measuring. But I don't have any idea what your images
actually look like. So what would I know?
> David and paulv - Why do widgets act as anti-hatered shields?
I can't speak for Paul, but I can tell you it is difficult, (nay,
impossible!) to write a procedural program that acts like a user-driven
one. Users will expect functionality that you can't deliver (like
recovering from a cursor that goes out of the window).
> And why not go all the way
> and use custom iTool interface then?
Clearly, you have never tried to do this. :-)
Let's just say, iTool programming is... no, I'm not even going
to get started today. I'm just going to go get a couple of beers
and chuckle to myself.
Cheers,
Your Friend,
David
--
David Fanning, Ph.D.
Fanning Software Consulting, Inc.
Coyote's Guide to IDL Programming: http://www.dfanning.com/
Sepore ma de ni thui. ("Perhaps thou speakest truth.")
|
|
|