Dear ImageJ Experts,
What I want to do is to create a contour map, i.e. a picture (with height * width pixels) of values to which I can then apply different LUTs in order to look at my data. And what I have now are only the values of discrete positions within this picture. Actually what I want to do is more or less what is described under the following link: http://www.geomore.com/how-to-contour-a-map/ And thus the question is how to generate the contour map, i.e. calculate the values of each pixel within the picture. Is there already an algorithm under ImageJ that is already doing such a calculation? Alternatively, what kind of calculation or algorithm would you recommend me in order to calculate the values at each pixel? I thank you very much in advance for your answer and help. Best regards, Philippe -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
On Tuesday 10 Jul 2012 13:23:17 Philippe Carl wrote:
> What I want to do is to create a contour map, i.e. a picture (with height * > width pixels) of values to which I can then apply different LUTs in order to > look at my data. > And what I have now are only the values of discrete positions within this > picture. If all the pixels in the image are your values, you can use the IsoPhotContour plugins here: http://www.dentistry.bham.ac.uk/landinig/software/software.html If only some of your pixels are your values, then the method showed in the link seems quite arbitrary ("using your eye like a ruler" !?) I doubt it will be accurate or meaningful. Maybe there is some algorithm (Laplacian diffusion comes to mind, but I am not sure if that is appropriate) that can be applied to the "height" of the samples to fill in the rest of the image pixels and then find the contour lines of that new image. Cheers Gabriel -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by CARL Philippe (LBP)
Dear Wade,
I thank you very much for your message and you have very correctly indentified the problem I would like to solve. Also your picture with the blanket is indeed a very nice way to visualize things and I havent thought about the issue of the stiffness. Additionally there is another problem to solve or at least to answer which are the conditions (or values) at limits, i.e. on the border of the picture. The first algorithm I thought about is to make an iterative calculation where you attribute to a given pixel the average value of all its neighbors and reset again the known pixels to their initial values at each iteration and this until the calculation is stable. But as such a code will be working, it will be quite time consuming. Another idea was to calculate the value of a given unknown pixel with a kind of center of mass calculation. And as this calculation will be way faster, it is more difficult for the values on the border of the picture. And another way (Jérôme Mutterer gave me this idea) is to use the polynomial fit plugin (http://www.optinav.com/imagej.html) developed by Bob Dougherty which seems to be working quite well (the conditions on the limits still need to be cleared). Could you explain me a little bit better your idea with the triangles? Im quite afraid to not have understand it. My best regards, Philippe De : Wade Schuette [mailto:[hidden email]] Envoyé : mardi 10 juillet 2012 18:50 À : [hidden email] Cc : [hidden email] Objet : Re: Contour map generation under ImageJ Philippe, This is really a 2-Dimensional curve-fitting (surface fitting) problem. I don't know the ImageJ libraries and whether something exists that would work. If not, you have to run some iterations and some math. If math doesn't deter you, read on. The problem is under-defined, but probably workable. I tried using "Contour" in the SAS product JMP, but it produced an ugly result with sharp corners. I think that, conceptually, one way to tackle this is to think of it as an open field with a number of telephone poles in it of different heights, and what you want to do is drape a somewhat stiff blanket over the field, constrained by the poles. That formulation still leaves three parameters unresolved, the effective stiffness of the blanket, the stretchiness of the blanket, and the strength and direction of the force trying to make the blanket fit the tops of the poles. Or, instead of weight to get a downward force on the blanket, you could attach elastic bands to the blanket, tie the other end to the top of the poles, and try to increase the strength of those bands, which is to say lessen the discrepancy from your surface to the match points. (statistically, reduce r-squared discrepancies ). I could easily write a script to compute the up/down force on each point on the blanket, move it one time interval, recompute, etc. if just stretching were involved, as that's just iterating for each point over the neighboring 4 points as if a spring were attached, with a force proportional to stretch squared. Adding mass to the point would make it a grid of billiard-balls connected by springs, again straight-forward to solve with iterations and probably cool to watch. But I'm trying to figure out the mathematics of STIFFNESS, without which you'll end up with a very spiky landscape, instead of the smooth one you envision. You won't know the parameters of "stiffness" and "stretchiness" to use, but for what you're doing I suspect that any reasonable numbers would work, and you can explore a little and see how sensitive the result is to your choices of values. You could find a set of parameters that more or less matches the result in the web-page example you gave. Regardless, you'll end up with a complete image that you can then make contours on ( just changeValues ( z-1, z, black) for z's you want to see.), or use LUTS on, or both. I'm working on how to implement the stiffness of the 2-d blanket / splines, just for fun. A cruder way to do this is to just make a triangle from every combination of 3 points such that no other point is included inside the triangles you keep. That basically covers the surface with connected triangles. Then each triangle lies in a completely determined PLANE , that you can assign vertical values to based on the three corners. Then you can hand sketch from that, or just "SMOOTH" it and use that as your contour map. Again that may be "good enough" for whatever you need this for. Wade On Tue, Jul 10, 2012 at 5:23 AM, Philippe CARL <[hidden email]> wrote: Dear ImageJ Experts, What I want to do is to create a contour map, i.e. a picture (with height * width pixels) of values to which I can then apply different LUTs in order to look at my data. And what I have now are only the values of discrete positions within this picture. Actually what I want to do is more or less what is described under the following link: http://www.geomore.com/how-to-contour-a-map/ And thus the question is how to generate the contour map, i.e. calculate the values of each pixel within the picture. Is there already an algorithm under ImageJ that is already doing such a calculation? Alternatively, what kind of calculation or algorithm would you recommend me in order to calculate the values at each pixel? I thank you very much in advance for your answer and help. Best regards, Philippe -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html -- R. Wade Schuette, CDP, MBA, MPH 698 Monterey Ave Morro Bay CA 93442 cell: 1 (734) 635-0508 fax: 1 (734) 864-0318 [hidden email] -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by CARL Philippe (LBP)
Philippe,
I put some work from a rather hasty macro up on a weblog so I don't need to email a thousand people a meg of images. Basically, I connected the dots by lines, manually, then wrote a macro that interpolated from the end-point-values of each line where the middle contour points (5, 10,15, 20, etc.) would be, and added those to the image. Then, I thresholded that image to just show points for one contour level (say 15), connected those dots in a roughly circular order, used Edit/Selection/Fit Ellipse to change the polygon line I drew to a best-fit ellipse, and DREW that on the picture. Repeat for each contour level. As I say, the problem is under-determined by the data, but this at least gives you a pretty picture to look at that wasn't biased by nasty old human judgment. http://wadesblogtest.blogspot.com/2012/07/images-for-contour-question.html The macro is too ugly to share, but I'll be glad to tweak it to run on a data set you send me, and then I'll share it . I'm just relearning Macros in ImageJ, having bailed from the NIH-Image group a decade or so ago, when Wayne switched it to Java and I didn't have the RAM (mentally) to make that transition. Regards, Wade Wade Schuette Morro Bay, California, USA On Wed, Jul 11, 2012 at 8:07 AM, Philippe CARL <[hidden email]>wrote: > Dear Wade, > > I thank you very much for your message and you have very correctly > indentified the problem I would like to solve. > > Also your picture with the blanket is indeed a very nice way to visualize > things and I haven’t thought about the issue of the stiffness. > > Additionally there is another problem to solve or at least to answer which > are the conditions (or values) at limits, i.e. on the border of the > picture. > > The first algorithm I thought about is to make an iterative calculation > where you attribute to a given pixel the average value of all its neighbors > and reset again the known pixels to their initial values at each iteration > and this until the calculation is stable. But as such a code will be > working, it will be quite time consuming. > > Another idea was to calculate the value of a given unknown pixel with a > kind > of center of mass calculation. And as this calculation will be way faster, > it is more difficult for the values on the border of the picture. > > And another way (Jérôme Mutterer gave me this idea) is to use the > polynomial > fit plugin (http://www.optinav.com/imagej.html) developed by Bob Dougherty > which seems to be working quite well (the conditions on the limits still > need to be cleared). > > Could you explain me a little bit better your idea with the triangles? I’m > quite afraid to not have understand it. > > My best regards, > > Philippe > > > > De : Wade Schuette [mailto:[hidden email]] > Envoyé : mardi 10 juillet 2012 18:50 > À : [hidden email] > Cc : [hidden email] > Objet : Re: Contour map generation under ImageJ > > > > Philippe, > > This is really a 2-Dimensional curve-fitting (surface fitting) problem. > > I don't know the ImageJ libraries and whether something exists that > would work. If not, you have to run some iterations and some math. > If math doesn't deter you, read on. > > The problem is under-defined, but probably workable. I tried using > "Contour" > in the SAS product JMP, but it produced an ugly result with sharp corners. > > I think that, conceptually, one way to tackle this is to think of it as > an open field with a number of telephone poles in it of different heights, > and what you want to do is drape a somewhat stiff blanket over the field, > constrained by the poles. > > That formulation still leaves three parameters unresolved, the effective > stiffness of the blanket, the stretchiness of the blanket, and the > strength and direction of the force trying to make the blanket fit the tops > of the poles. > > Or, instead of weight to get a downward force on the blanket, you could > attach elastic bands to the blanket, tie the other end to the top of the > poles, and try to increase the strength of those bands, which is to say > lessen the discrepancy from your surface to the match points. > (statistically, reduce r-squared discrepancies ). > > I could easily write a script to compute the up/down force on each point on > the blanket, move it one time interval, recompute, etc. if just stretching > were involved, as that's just iterating for each point over the neighboring > 4 points as if a spring were attached, with a force proportional to > stretch squared. Adding mass to the point would make it a grid > of billiard-balls connected by springs, again straight-forward to > solve with iterations and probably cool to watch. > > But I'm trying to figure out the mathematics of STIFFNESS, without > which you'll end up with a very spiky landscape, instead of the > smooth one you envision. > > You won't know the parameters of "stiffness" and "stretchiness" to use, > but for what you're doing I suspect that any reasonable numbers would > work, and you can explore a little and see how sensitive the result is > to your choices of values. You could find a set of parameters that > more or less matches the result in the web-page example you gave. > > Regardless, you'll end up with a complete image that you can then > make contours on ( just changeValues ( z-1, z, black) for z's you > want to see.), or use LUTS on, or both. > > I'm working on how to implement the stiffness of the 2-d blanket / splines, > just for fun. > > A cruder way to do this is to just make a triangle from every combination > of 3 points such that no other point is included inside the triangles you > keep. > That basically covers the surface with connected triangles. > > Then each triangle lies in a completely determined PLANE , that > you can assign vertical values to based on the three corners. Then > you can hand sketch from that, or just "SMOOTH" it and > use that as your contour map. Again that may be "good enough" > for whatever you need this for. > > > Wade > > > > > > On Tue, Jul 10, 2012 at 5:23 AM, Philippe CARL <[hidden email]> > wrote: > > Dear ImageJ Experts, > > What I want to do is to create a contour map, i.e. a picture (with height * > width pixels) of values to which I can then apply different LUTs in order > to > look at my data. > > And what I have now are only the values of discrete positions within this > picture. > > Actually what I want to do is more or less what is described under the > following link: > > http://www.geomore.com/how-to-contour-a-map/ > > And thus the question is how to generate the contour map, i.e. calculate > the > values of each pixel within the picture. > > Is there already an algorithm under ImageJ that is already doing such a > calculation? > > Alternatively, what kind of calculation or algorithm would you recommend me > in order to calculate the values at each pixel? > > I thank you very much in advance for your answer and help. > > Best regards, > > Philippe > > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html > > > > > -- > R. Wade Schuette, CDP, MBA, MPH > 698 Monterey Ave > Morro Bay CA 93442 > cell: 1 (734) 635-0508 > fax: 1 (734) 864-0318 > [hidden email] > > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html > -- R. Wade Schuette, CDP, MBA, MPH 698 Monterey Ave Morro Bay CA 93442 cell: 1 (734) 635-0508 fax: 1 (734) 864-0318 [hidden email] -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
OK, Philippe, I believe what you REALLY need is called "biharmonic spline
interpolation". I do not know if this is implemented in ImageJ. I do know that it is implemented in MATLAB, but I don't have a copy of that. There's one discussion of the subject and one person's MATLAB code here: http://www.mathworks.com/matlabcentral/answers/17775 citing as a reference Sandwell, D. T. (1987), Biharmonic spline interpolation of GEOS-3 and SEASAT altimeter data, Geophysical Research Letters, Vol. 2, p. 139 – 142 available here: http://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0CFcQFjAA&url=http%3A%2F%2Ftopex.ucsd.edu%2Fsandwell%2Fpublications%2F021_GRL_biharmonic_1987.pdf&ei=YCv-T_joMMXeqgGi072LCQ&usg=AFQjCNG-06IIHnP0iTcIdywcSPBENJcLZg There's a (possibly different) page on the GRIDDATA procedure in MATLAB that also seems to solve this problem: Video tutorial on the subject of fitting a 2-d surface curve to an irregularly sampled set of points: http://blogs.mathworks.com/pick/2007/11/02/advanced-matlab-surface-plot-of-nonuniform-data/ Actually, go into Google and search this string: "matlab griddata" and you'll get many references to fitting irregularly sampled data and creating a uniform grid out of it, suitable for contours or plotting or whatever else you want to do next. That function (GRIDDATA) is described here: http://www.weizmann.ac.il/matlab/techdoc/ref/griddata.html Wade On Wed, Jul 11, 2012 at 1:41 PM, Wade Schuette <[hidden email]>wrote: > Philippe, > > I put some work from a rather hasty macro up on a weblog so I don't need > to email a thousand people a meg of images. Basically, I connected the > dots by lines, manually, then wrote a macro that interpolated from the > end-point-values of each line where the middle contour points (5, 10,15, > 20, etc.) would be, and added those to the image. Then, I thresholded > that image to just show points for one contour level (say 15), connected > those dots in a roughly circular order, used Edit/Selection/Fit Ellipse to > change the polygon line I drew to a best-fit ellipse, and DREW that on the > picture. Repeat for each contour level. > > As I say, the problem is under-determined by the data, but this at least > gives you a pretty picture to look at that wasn't biased by nasty old human > judgment. > > http://wadesblogtest.blogspot.com/2012/07/images-for-contour-question.html > > The macro is too ugly to share, but I'll be glad to tweak it to run on a > data set you send me, and then I'll share it . I'm just relearning Macros > in ImageJ, having bailed from the NIH-Image group a decade or so ago, when > Wayne switched it to Java and I didn't have the RAM (mentally) to make that > transition. > > > Regards, > > Wade > > Wade Schuette > Morro Bay, California, USA > > > > > > On Wed, Jul 11, 2012 at 8:07 AM, Philippe CARL <[hidden email]>wrote: > >> Dear Wade, >> >> I thank you very much for your message and you have very correctly >> indentified the problem I would like to solve. >> >> Also your picture with the blanket is indeed a very nice way to visualize >> things and I haven’t thought about the issue of the stiffness. >> >> Additionally there is another problem to solve or at least to answer which >> are the conditions (or values) at limits, i.e. on the border of the >> picture. >> >> The first algorithm I thought about is to make an iterative calculation >> where you attribute to a given pixel the average value of all its >> neighbors >> and reset again the known pixels to their initial values at each iteration >> and this until the calculation is stable. But as such a code will be >> working, it will be quite time consuming. >> >> Another idea was to calculate the value of a given unknown pixel with a >> kind >> of center of mass calculation. And as this calculation will be way faster, >> it is more difficult for the values on the border of the picture. >> >> And another way (Jérôme Mutterer gave me this idea) is to use the >> polynomial >> fit plugin (http://www.optinav.com/imagej.html) developed by Bob >> Dougherty >> which seems to be working quite well (the conditions on the limits still >> need to be cleared). >> >> Could you explain me a little bit better your idea with the triangles? I’m >> quite afraid to not have understand it. >> >> My best regards, >> >> Philippe >> >> >> >> De : Wade Schuette [mailto:[hidden email]] >> Envoyé : mardi 10 juillet 2012 18:50 >> À : [hidden email] >> Cc : [hidden email] >> Objet : Re: Contour map generation under ImageJ >> >> >> >> Philippe, >> >> This is really a 2-Dimensional curve-fitting (surface fitting) problem. >> >> I don't know the ImageJ libraries and whether something exists that >> would work. If not, you have to run some iterations and some math. >> If math doesn't deter you, read on. >> >> The problem is under-defined, but probably workable. I tried using >> "Contour" >> in the SAS product JMP, but it produced an ugly result with sharp corners. >> >> I think that, conceptually, one way to tackle this is to think of it as >> an open field with a number of telephone poles in it of different heights, >> and what you want to do is drape a somewhat stiff blanket over the field, >> constrained by the poles. >> >> That formulation still leaves three parameters unresolved, the effective >> stiffness of the blanket, the stretchiness of the blanket, and the >> strength and direction of the force trying to make the blanket fit the >> tops >> of the poles. >> >> Or, instead of weight to get a downward force on the blanket, you could >> attach elastic bands to the blanket, tie the other end to the top of the >> poles, and try to increase the strength of those bands, which is to say >> lessen the discrepancy from your surface to the match points. >> (statistically, reduce r-squared discrepancies ). >> >> I could easily write a script to compute the up/down force on each point >> on >> the blanket, move it one time interval, recompute, etc. if just >> stretching >> were involved, as that's just iterating for each point over the >> neighboring >> 4 points as if a spring were attached, with a force proportional to >> stretch squared. Adding mass to the point would make it a grid >> of billiard-balls connected by springs, again straight-forward to >> solve with iterations and probably cool to watch. >> >> But I'm trying to figure out the mathematics of STIFFNESS, without >> which you'll end up with a very spiky landscape, instead of the >> smooth one you envision. >> >> You won't know the parameters of "stiffness" and "stretchiness" to use, >> but for what you're doing I suspect that any reasonable numbers would >> work, and you can explore a little and see how sensitive the result is >> to your choices of values. You could find a set of parameters that >> more or less matches the result in the web-page example you gave. >> >> Regardless, you'll end up with a complete image that you can then >> make contours on ( just changeValues ( z-1, z, black) for z's you >> want to see.), or use LUTS on, or both. >> >> I'm working on how to implement the stiffness of the 2-d blanket / >> splines, >> just for fun. >> >> A cruder way to do this is to just make a triangle from every combination >> of 3 points such that no other point is included inside the triangles you >> keep. >> That basically covers the surface with connected triangles. >> >> Then each triangle lies in a completely determined PLANE , that >> you can assign vertical values to based on the three corners. Then >> you can hand sketch from that, or just "SMOOTH" it and >> use that as your contour map. Again that may be "good enough" >> for whatever you need this for. >> >> >> Wade >> >> >> >> >> >> On Tue, Jul 10, 2012 at 5:23 AM, Philippe CARL <[hidden email]> >> wrote: >> >> Dear ImageJ Experts, >> >> What I want to do is to create a contour map, i.e. a picture (with height >> * >> width pixels) of values to which I can then apply different LUTs in order >> to >> look at my data. >> >> And what I have now are only the values of discrete positions within this >> picture. >> >> Actually what I want to do is more or less what is described under the >> following link: >> >> http://www.geomore.com/how-to-contour-a-map/ >> >> And thus the question is how to generate the contour map, i.e. calculate >> the >> values of each pixel within the picture. >> >> Is there already an algorithm under ImageJ that is already doing such a >> calculation? >> >> Alternatively, what kind of calculation or algorithm would you recommend >> me >> in order to calculate the values at each pixel? >> >> I thank you very much in advance for your answer and help. >> >> Best regards, >> >> Philippe >> >> >> -- >> ImageJ mailing list: http://imagej.nih.gov/ij/list.html >> >> >> >> >> -- >> R. Wade Schuette, CDP, MBA, MPH >> 698 Monterey Ave >> Morro Bay CA 93442 >> cell: 1 (734) 635-0508 >> fax: 1 (734) 864-0318 >> [hidden email] >> >> >> -- >> ImageJ mailing list: http://imagej.nih.gov/ij/list.html >> > > > > -- > R. Wade Schuette, CDP, MBA, MPH > 698 Monterey Ave > Morro Bay CA 93442 > cell: 1 (734) 635-0508 > fax: 1 (734) 864-0318 > [hidden email] > -- R. Wade Schuette, CDP, MBA, MPH 698 Monterey Ave Morro Bay CA 93442 cell: 1 (734) 635-0508 fax: 1 (734) 864-0318 [hidden email] -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by CARL Philippe (LBP)
Hi Philippe,
On Tue, 10 Jul 2012, Philippe CARL wrote: > What I want to do is to create a contour map, i.e. a picture (with height * > width pixels) of values to which I can then apply different LUTs in order to > look at my data. > > And what I have now are only the values of discrete positions within this > picture. > > Actually what I want to do is more or less what is described under the > following link: > > http://www.geomore.com/how-to-contour-a-map/ > > And thus the question is how to generate the contour map, i.e. calculate the > values of each pixel within the picture. > > Is there already an algorithm under ImageJ that is already doing such a > calculation? > > Alternatively, what kind of calculation or algorithm would you recommend me > in order to calculate the values at each pixel? I gave this description a quick try and here is an alpha version of a plugin that does what you want. Note: I say it is an alpha version not because I have time to develop it further, but because the quality is not where you need it in my opinion. But it could give you a good start. One way that should work is to evolve the (spline fitted) curves to minimize their bending energy. Another would be to use b-splines instead. To play with it, launch the Fiji Script Editor (you need Fiji anyway since I used the Delaunay package) via File>Script. Paste the following source code, select Language>Java, the save with File Save and run with Run>Compile and Run. -- snipsnap -- import delaunay.DelaunayTriangulation; import delaunay.Pnt; import delaunay.Simplex; import ij.IJ; import ij.ImagePlus; import ij.gui.Overlay; import ij.gui.PointRoi; import ij.gui.PolygonRoi; import ij.gui.Roi; import ij.plugin.PlugIn; import ij.process.ImageProcessor; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; public class Contour_Map_Alpha implements PlugIn { public void run(String arg) { int width = 352; int height = 350; /* * The particles have been obtained by running this macro: * * run("URL...", "url=http://www.geomore.com/wp-content/uploads/2012/04/contouring-2.jpg"); * setAutoThreshold("Default"); * run("Set Measurements...", " center redirect=None decimal=3"); * run("Analyze Particles...", "size=10-200 circularity=0.50-1.00 show=[Overlay Outlines] display clear"); * * pasting the output into a text editor and manually adding the third column by inspecting the image */ String text = "255.878 55.957 15\n" + "175.417 96.545 40\n" + "123.675 127.575 41\n" + "71.996 90.606 12\n" + "166.429 147.925 45\n" + "105.840 212.245 35\n" + "56.742 287.025 0\n" + "196.202 206.658 32\n" + "243.238 254.097 0\n" + "249.982 158.868 38\n"; Set<MyPnt> pnts = parseData(text); ImagePlus image = IJ.createImage("Interpolated", "32-bit black", width, height, 1); ImageProcessor ip = image.getProcessor(); // Delaunay Triangulation Simplex tri = new Simplex(new MyPnt[] { new MyPnt(-10000, -10000, 0), new MyPnt(+10000, -10000, 0), new MyPnt(0, +100000, 0) }); DelaunayTriangulation dt = new DelaunayTriangulation(tri); for (MyPnt pnt : pnts) dt.delaunayPlace(pnt); Overlay overlay = new Overlay(); for (double level = 39.5; level > 0; level -= 10) { List<Roi> contour = getContourLine(dt, level); for (Roi roi : contour) overlay.add(roi); } image.setOverlay(overlay); ip.setMinAndMax(0, 255); image.setRoi(makePointRoi(pnts)); image.show(); } private static Set<MyPnt> parseData(String data) { Set<MyPnt> result = new LinkedHashSet<MyPnt>(); for (String line : data.split("\\n")) { String[] columns = line.split("[\\t ]+"); result.add(new MyPnt(Double.parseDouble(columns[0]), Double.parseDouble(columns[1]), Double.parseDouble(columns[2]))); } return result; } private static List<Roi> getContourLine(DelaunayTriangulation dt, double level) { List<Roi> result = new ArrayList<Roi>(); Set<MyEdge> done = new HashSet<MyEdge>(); Iterator iter = dt.iterator(); while (iter.hasNext()) { Simplex simplex = (Simplex)iter.next(); MyPnt[] list = getPnts(simplex); MyPnt a = null, b = null; for (int i = 0; i < list.length; i++) { int i2 = i > 0 ? i - 1 : list.length - 1; double between = isBetween(list[i2], list[i], level); if (between < 0) continue; MyEdge edge = new MyEdge(list[i2], list[i]); if (done.contains(edge)) continue; done.add(edge); List<MyPnt> polygon = new ArrayList<MyPnt>(); polygon.add(list[i2].interpolate(list[i], between)); boolean closed = true; if (!completePolygon(dt, level, simplex, polygon, edge, done)) { Collections.reverse(polygon); closed = completePolygon(dt, level, null, polygon, edge, done); } float[] x = new float[polygon.size()]; float[] y = new float[polygon.size()]; for (int j = 0; j < x.length; j++) { x[j] = (float)polygon.get(j).coord(0); y[j] = (float)polygon.get(j).coord(1); } PolygonRoi roi = new PolygonRoi(x, y, x.length, closed ? Roi.POLYGON : Roi.POLYLINE); roi.fitSpline(); result.add(roi); } } return result; } private static boolean completePolygon(DelaunayTriangulation dt, double level, Simplex simplex, List<MyPnt> polygon, MyEdge edge, Set<MyEdge> done) { outer: for (;;) { simplex = getNeighboringSimplex(dt, simplex, edge); if (simplex == null) return false; MyPnt[] list = getPnts(simplex); for (int i = 0; i < list.length; i++) { int i2 = i > 0 ? i - 1 : list.length - 1; double between = isBetween(list[i2], list[i], level); if (between < 0) continue; MyEdge newEdge = new MyEdge(list[i2], list[i]); if (edge.equals(newEdge)) continue; if (done.contains(newEdge)) return true; polygon.add(list[i2].interpolate(list[i], between)); edge = newEdge; done.add(edge); continue outer; } return false; } } private static double isBetween(MyPnt a, MyPnt b, double level) { if (a.value == b.value) return -1; if (isOutside(a) || isOutside(b)) return -1; if (a.value == level || b.value == level) level -= 1e-15; double result = (level - a.value) / (b.value - a.value); return result > 1 ? -result : result; } private static boolean isOutside(Pnt a) { return a.coord(0) < 0 || a.coord(1) < 0 || a.coord(0) >= 350 || a.coord(1) >= 350; } private static Simplex getNeighboringSimplex(DelaunayTriangulation dt, Simplex originalSimplex, MyEdge edge) { Iterator iter = dt.iterator(); while (iter.hasNext()) { Simplex simplex = (Simplex)iter.next(); if (simplex == originalSimplex) continue; if (simplex.contains(edge.a) && simplex.contains(edge.b)) return simplex; } return null; } private static MyPnt[] getPnts(Simplex simplex) { List<MyPnt> list = new ArrayList<MyPnt>(); Iterator iter = simplex.iterator(); while (iter.hasNext()) list.add((MyPnt)iter.next()); return list.toArray(new MyPnt[list.size()]); } private static class MyEdge { private MyPnt a, b; public MyEdge(MyPnt a, MyPnt b) { this.a = a; this.b = b; } @Override public boolean equals(Object other) { MyEdge o = (MyEdge)other; return (a.equals(o.a) && b.equals(o.b)) || (a.equals(o.b) && b.equals(o.a)); } @Override public int hashCode() { return a.hashCode() ^ b.hashCode(); } } private static class MyPnt extends Pnt { public double value; public MyPnt(double x, double y, double value) { super(x, y); this.value = value; } public MyPnt(double[] coords, double value) { super(coords); this.value = value; } public double distanceTo(Pnt other) { return subtract(other).magnitude(); } // t == 0 means this, t == 1 means other public MyPnt interpolate(MyPnt other, double t) { int len = dimCheck(other); double[] coords = new double[len]; for (int i = 0; i < len; i++) coords[i] = coord(i) * (1 - t) + other.coord(i) * t; return new MyPnt(coords, value * (1 - t) + other.value * t); } public String toString() { return super.toString() + "(" + value + ")"; } } private static PointRoi makePointRoi(Set<MyPnt> pnts) { int n = pnts.size(); float[] x = new float[n]; float[] y = new float[n]; int counter = 0; for (MyPnt pnt : pnts) { x[counter] = (float)pnt.coord(0); y[counter++] = (float)pnt.coord(1); } return new PointRoi(x, y, n); } } -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Dear Johannes and Wade,
I thank you very much for sharing your ideas and code. I will make a brainstorming of all this (and hope I will be able understand all your code Johannes) to get a good solution for this issue. And Johannes since you are one of the main author of Fiji (which I'm actually using) I would have a (maybe silly) question to ask you. I use the scripting window of Fiji in order to write my plugins and when you execute a plugin for the first timed within Fiji it gets correctly executed (if the code has no error of course). But if you modify then the code and hit the "Run" button the new code gets only correctly checked for errors, but on launching it is still the old code that gets executed until "Help->Refresh Menus" has been pressed. Is this a bug or can this be overcome in a way? Of course, the instruction "Help->Refresh Menus" can be simplified by defining a Shortcut on a hotkey (like for example F1), but it is still very constraining. I thank you very much fir your answer and suggestions. My best regards, Philippe -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Hi Philippe,
On Fri, 13 Jul 2012, Philippe CARL wrote: > I use the scripting window of Fiji in order to write my plugins and when you > execute a plugin for the first timed within Fiji it gets correctly executed > (if the code has no error of course). > > But if you modify then the code and hit the "Run" button the new code gets > only correctly checked for errors, but on launching it is still the old code > that gets executed until "Help->Refresh Menus" has been pressed. This did not happen for me, I developed the class exclusively in the Script Editor and never had to hit Help>Refresh Menus. Just a hunch: Is it possible that you saved the .java file into <ImageJ-Directory>/plugins/? If so, is the issue fixed by moving it (along with the corresponding .class files) out of the ImageJ directory? Ciao, Johannes P.S.: I do not want to shift this issue to the fiji-devel mailing list because it is of the greater interest of the ImageJ community. -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Hi Johannes
Just a hunch: Is it possible that you saved the .java file into <ImageJ-Directory>/plugins/? If so, is the issue fixed by moving it (along with the corresponding .class files) out of the ImageJ directory? You are completely right since not only I the plugin was saved in the <ImageJ-Directory>/plugins/ folder, but also the issue was solved by moving the whole folder with the .java file and all its libraries out of the /plugins/ folder. So I guess that a plugin under development shouldn't thus be saved in the <ImageJ-Directory>/plugins/ folder. I wasn't aware of that and I agree that this information may indeed of the greater interest of the ImageJ community. Besides that, I needed (for the plugin that I'm still working on right now) the extension of the Plot and PlotWindow classes for functionalities towards accepting ArrayList data input and allowing to display arrow plots (similar to the quiver in Matlab), logarithmic (log in x and/or y) plots, minor ticks (decimal and logarithmic), change of the label font and draw dotted lines. May these extensions be of any interest for the community, and if yes where should I upload the files? Best regards, Philippe -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Free forum by Nabble | Edit this page |