Hello together,
I wrote a more or less complex plugin in python for Fiji, which helps me to analyse every pixel of an image (row by row) in combination with some ROI calculation. The iteration I use is: for j in range(x): IJ.showProgress(j, x) sumpix_sap = 0 for i in range(y): sap_row = 0 for roi in RoiManager.getInstance().getRoisAsArray(): if roi.contains(j, i): pix_sap = rt.getValue("Sapflow per Pixel", sap_row) sumpix_sap = sumpix_sap + pix_sap break else: sap_row = sap_row + 1 table.incrementCounter() table.addValue("Sapflow sum", sumpix_sap * 1000000) IJ.showProgress(1) For a test picture (620x90 pixel, 197 ROIs) it needs some seconds to calculate my result values. For another test picture (592x301, 1172 ROIs) it needs around 6 minutes. Unfortunatly I need to analyse pictures with 6000x1000+ pixel and 100000+ ROIs. I tried it but stopped it after around 30 minutes with the progress bar not moving once. Is this a problem with python iterations or did I something wrong with my code, which slows down the progress unnecessarily? I would appreciate any hint/help. Thank you very much in advance. Andreas -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
I posted a similar script to the mailing list a while ago for help with an unrelated problem and received the following tip from Wayne Rasband.
Even at their best Jython iterations are slow. I eventually moved to using a combination of masks, the image calculator and getStatistics. I only had one ROI for each image so such a solution may not be as useful for your situation. > Change the script to use a mask instead of roi.contains() and it will run ~6 times faster. Here is an example Python script that uses a mask to calculate the pixel count and mean pixel value of a non-rectangular selection. > > imp = IJ.getImage() > roi = imp.getRoi() > mask = roi.getMask() > ip = imp.getProcessor() > r = roi.getBounds() > total = sum = 0 > for y in range(r.height): > for x in range(r.width): > if mask.get(x,y)!=0: > total += 1 > sum += ip.getf(r.x+x,r.y+y); > print "count=", total > print "mean=", sum/total Jonathan Street [hidden email] On Oct 22, 2013, at 8:06 AM, Andreas Rzepecki <[hidden email]> wrote: > Hello together, > > I wrote a more or less complex plugin in python for Fiji, which helps me to analyse every pixel of an image (row by row) in combination with some ROI calculation. The iteration I use is: > > for j in range(x): > IJ.showProgress(j, x) > sumpix_sap = 0 > for i in range(y): > sap_row = 0 > for roi in RoiManager.getInstance().getRoisAsArray(): > if roi.contains(j, i): > pix_sap = rt.getValue("Sapflow per Pixel", sap_row) > sumpix_sap = sumpix_sap + pix_sap > break > else: > sap_row = sap_row + 1 > table.incrementCounter() > table.addValue("Sapflow sum", sumpix_sap * 1000000) > IJ.showProgress(1) > > > For a test picture (620x90 pixel, 197 ROIs) it needs some seconds to calculate my result values. > > For another test picture (592x301, 1172 ROIs) it needs around 6 minutes. > > Unfortunatly I need to analyse pictures with 6000x1000+ pixel and 100000+ ROIs. I tried it but stopped it after around 30 minutes with the progress bar not moving once. > > Is this a problem with python iterations or did I something wrong with my code, which slows down the progress unnecessarily? > > I would appreciate any hint/help. Thank you very much in advance. > > Andreas > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Dear Mr. Street,
thank you very much for the mask-hint. I tried to change my code to avoid roi.contains() and instead use mask.get: for j in range(x): IJ.showProgress(j, x) sumpix_sap = 0 for i in range(y): sap_row = 0 for roi in RoiManager.getInstance().getRoisAsArray(): mask = roi.getMask() if mask.get(j, i)!= 0: pix_sap = rt.getValue("Sapflow per Pixel", sap_row) sumpix_sap = sumpix_sap + pix_sap else: sap_row = sap_row + 1 table.incrementCounter() table.addValue("Sapflow sum", sumpix_sap * 1000000) IJ.showProgress(1) table.show("IASF-Results") This unfortunately leads to the following Java-error: Traceback (most recent call last): File "<iostream>", line 44, in <module> at ij.process.ByteProcessor.get(ByteProcessor.java:262) at sun.reflect.GeneratedMethodAccessor21.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) java.lang.ArrayIndexOutOfBoundsException: java.lang.ArrayIndexOutOfBoundsException: 30 So I'm at this point not sure if I have completely misunderstood the mask command. Best regards Andreas Rzepecki -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by Andreas Rzepecki
Hi Andreas,
unfortunately I don't understand what your plugin should do, but anyhow: The rt.getValue command is nothing that I'd put into an in the inner loop; it needs to lookup the column index from the String. It would be much faster using an array than the ResultsTable; write your data to the ResultsTable at the very end. One more point: If the rois are much smaller than the image size, it would be much faster stepping through the rois in the outer loop, and using the bounding rectangle (getBounds()) of each roi for the x and y coordinates, so the inner loop would be just over the pixels within the bounding rectangle. You may need some additional arrays to store intermediate results. --- Concerning roi.getMask(): First note that it is null for rectangular Rois; you will get an exception if you have a rectangular roi and don't check for this. Also, the mask is only for pixels within the getBounds() rectangle. So it contains getBounds().width * getBounds().height pixels. If you can explain what your macro should do, maybe there is some trick to make it faster... Michael ________________________________________________________________ On Oct 22, 2013, at 14:06, Andreas Rzepecki wrote: > Hello together, > > I wrote a more or less complex plugin in python for Fiji, which helps me to analyse every pixel of an image (row by row) in combination with some ROI calculation. The iteration I use is: > > for j in range(x): > IJ.showProgress(j, x) > sumpix_sap = 0 > for i in range(y): > sap_row = 0 > for roi in RoiManager.getInstance().getRoisAsArray(): > if roi.contains(j, i): > pix_sap = rt.getValue("Sapflow per Pixel", sap_row) > sumpix_sap = sumpix_sap + pix_sap > break > else: > sap_row = sap_row + 1 > table.incrementCounter() > table.addValue("Sapflow sum", sumpix_sap * 1000000) > IJ.showProgress(1) > > > For a test picture (620x90 pixel, 197 ROIs) it needs some seconds to calculate my result values. > > For another test picture (592x301, 1172 ROIs) it needs around 6 minutes. > > Unfortunatly I need to analyse pictures with 6000x1000+ pixel and 100000+ ROIs. I tried it but stopped it after around 30 minutes with the progress bar not moving once. > > Is this a problem with python iterations or did I something wrong with my code, which slows down the progress unnecessarily? > > I would appreciate any hint/help. Thank you very much in advance. > > Andreas > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by Andreas Rzepecki
This is another issue I've encountered and previously received help with from people on the fiji IRC channel.
The issue is that converting a ROI into a mask does not operate on the entire image but on the bounding box for the ROI. If you have a 100by100 image with a circular ROI centered at 10,10 with a radius of 5 the mask will be only 10by10 (the size of the bounding box) so when you reach column or row 11 you'll get the out of bounds error. I suggest instead of iterating over each pixel in the outer loops first iterate over each ROI. I don't know what your images look like but in my case this reduced the number of pixels I was checking by about 30%. For each ROI iterate over the pixels with r = roi.getBounds() for y in range(r.height): for x in range(r.width): if mask.get(x,y) != 0: # Process Here x and y will not match the location of the pixel in the original image so we need to offset them using r.x and r.y Jonathan Street [hidden email]<mailto:[hidden email]> On Oct 22, 2013, at 12:00 PM, Andreas Rzepecki <[hidden email]<mailto:[hidden email]>> wrote: Dear Mr. Street, thank you very much for the mask-hint. I tried to change my code to avoid roi.contains() and instead use mask.get: for j in range(x): IJ.showProgress(j, x) sumpix_sap = 0 for i in range(y): sap_row = 0 for roi in RoiManager.getInstance().getRoisAsArray(): mask = roi.getMask() if mask.get(j, i)!= 0: pix_sap = rt.getValue("Sapflow per Pixel", sap_row) sumpix_sap = sumpix_sap + pix_sap else: sap_row = sap_row + 1 table.incrementCounter() table.addValue("Sapflow sum", sumpix_sap * 1000000) IJ.showProgress(1) table.show("IASF-Results") This unfortunately leads to the following Java-error: Traceback (most recent call last): File "<iostream>", line 44, in <module> at ij.process.ByteProcessor.get(ByteProcessor.java:262) at sun.reflect.GeneratedMethodAccessor21.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) java.lang.ArrayIndexOutOfBoundsException: java.lang.ArrayIndexOutOfBoundsException: 30 So I'm at this point not sure if I have completely misunderstood the mask command. Best regards Andreas Rzepecki -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by Street, Jonathan (NIH/NIDDK) [F]
Hi Michael,
thanks for your answer, after reading it several times I changed the rt.getValue command. The new iterating part of the plugin is now: for j in range(x): IJ.showProgress(j, x) sumpix_sap = 0 for i in range(y): sap_row = 0 for roi in RoiManager.getInstance().getRoisAsArray(): if roi.contains(j, i): f = roi.getFeretValues() ip.setRoi(roi) stats = ImageStatistics.getStatistics(ip, Measurements.AREA, None) pix_sap = ((math.pi/4) * (1/(nu*L)) * math.pow(f[0], 3) * math.pow(f[2], 3) / (math.pow(f[0], 2) + math.pow(f[2], 2))*p)/stats.pixelCount sumpix_sap = sumpix_sap + pix_sap break table.incrementCounter() table.addValue("Sapflow sum", sumpix_sap * 1000000) IJ.showProgress(1) table.show("IASF-Results") but it still needs too much time, so here is what I want to do with this code: 1. Iterating through every pixel of the picture (row by row) 2. If the pixel is inside a certain ROI calculate a value for this pixel determined by the ROI and divided by the amount of pixel of this ROI (= pix_sap; nu ,L, p are constant)) 3. Calculating the sum of pix_sap per pixel row 4. Print the sum of pix_sap per pixel row Maybe using a function for the calculation will speed up the plugin, but in my oppinion the main problem seems to be that I potentially have to iterate through every pixel * ROI. Thanking you in advance. Andreas -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
On Tuesday 22 Oct 2013 21:14:46 Andreas Rzepecki wrote:
> thanks for your answer, after reading it several times I changed the > rt.getValue command. The new iterating part of the plugin is now: [...] > but it still needs too much time, so here is what I want to do with this > code: > 1. Iterating through every pixel of the picture (row by row) > 2. If the pixel is inside a certain ROI calculate a value for this pixel > determined by the ROI and divided by the amount of pixel of this ROI (= > pix_sap; nu ,L, p are constant)) > 3. Calculating the sum of pix_sap per > pixel row > 4. Print the sum of pix_sap per pixel row > > Maybe using a function for the calculation will speed up the plugin, but in > my oppinion the main problem seems to be that I potentially have to iterate > through every pixel * ROI. That approach is very inefficient. Since for all the ROIs their area can be known beforehand I would rather iterate on the ROIs, not the pixels. I.e. for each pixel in a particular ROI, the area of the ROI is the same. You know which pixel is in which ROI if you label the regions in grey value 1..n in a 16bit image and use that value to index the ROI area (let's say stored in an array). You seem to want to label a pixel according to a ROI value and the area (which would be the same for all the pixels in that ROI) so for any pixel in the ROI the result would be - according to your description - the same, but maybe I misunderstood something. Hope that my comment is useful. Cheers Gabriel -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by Andreas Rzepecki
On Oct 22, 2013, at 22:14, Andreas Rzepecki wrote:
> so here is what I want to do with this code: > > 1. Iterating through every pixel of the picture (row by row) > 2. If the pixel is inside a certain ROI calculate a value for this pixel determined by the ROI and divided by the amount of pixel of this ROI (= pix_sap; nu ,L, p are constant)) > 3. Calculating the sum of pix_sap per pixel row > 4. Print the sum of pix_sap per pixel row Hi Andreas, as Gabriel wrote already, it is much better to have a loop over the rois. If I understand your problem correctly, what about something like the following approach: Create an empty float (32 bit) image. For each roi { determine the value that depends on the roi and divide by roi area, this gives you 'pix_sap' select the roi in the float image Process>Math>Add add 'pix_sap' to the float image (it will be restricted to the roi) } Take the float image and resize it to width=1, height=original size, 'Average when downsizing" and Interpolation=none. This gives you the average of each row. Then multiply the values by the previous width, so you have the sum. Have a line selection from (0,0) to (0, height-1) and use array = getProfile (macro) or pp = new ProfilePlot(imp); array = pp.getProfile(); (scripting). This is your array of the sums of 'pix_sap' over each row. As it does not use any loop over pixels, an implementation in the imageJ macro language with BatchMode will be about as fast as any other implementation. Hope this helps, Michael -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by Andreas Rzepecki
Thx for the help so far. I try to lable the ROIs with a grey color (1-65536 in a 16bit picture) first, which will most probably speed up my procedure.
Therefore I tried this code: import math from ij import IJ from ij.gui import GenericDialog imp = IJ.getImage() ip = imp.getProcessor().convertToFloat() imp = IJ.getImage() ip = imp.getProcessor().convertToFloat() grey_value = 1 IJ.run("Set Measurements...", "area centroid perimeter shape feret's area_fraction redirect=None decimal=6") IJ.run("Set Scale...") IJ.run("Analyze Particles...") IJ.run("16-bit") for roi in RoiManager.getInstance().getRoisAsArray(): roi.setFillColor(grey_value) grey_value = grey_value + 1 imp.show() This leads to: TypeError: setFillColor(): 1st arg can't be coerced to java.awt.Color Unfortunatly it looks like setFillColor() needs the color determing value in another form? Would it be possible to use 32bit picture too, because I maybe need more then 65536 lable classes? Best regards Andreas -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Hi Andreas,
> I try to lable the ROIs with a grey color (1-65536 in a 16bit picture) If you use Fiji and add the LOCI update site [1], the Plugins > LOCI > Roi Map plugin will do this for you. If you have 255 or fewer ROIs it creates an 8-bit labeling with discontinuous LUT (similar to Glasbey [2]). If you have more than 255 ROIs it creates a 16-bit labeling with grayscale LUT. Source at: https://github.com/uw-loci/misc-plugins/blob/master/src/main/java/loci/plugins/RoiMap.java Regards, Curtis [1] http://fiji.sc/Update_Sites [2] http://fiji.sc/Glasbey On Wed, Oct 23, 2013 at 6:32 AM, Andreas Rzepecki <[hidden email]>wrote: > Thx for the help so far. I try to lable the ROIs with a grey color > (1-65536 in a 16bit picture) first, which will most probably speed up my > procedure. > > Therefore I tried this code: > > import math > from ij import IJ > from ij.gui import GenericDialog > imp = IJ.getImage() > ip = imp.getProcessor().convertToFloat() > > imp = IJ.getImage() > ip = imp.getProcessor().convertToFloat() > grey_value = 1 > > IJ.run("Set Measurements...", "area centroid perimeter shape feret's > area_fraction redirect=None decimal=6") > IJ.run("Set Scale...") > IJ.run("Analyze Particles...") > IJ.run("16-bit") > > for roi in RoiManager.getInstance().getRoisAsArray(): > roi.setFillColor(grey_value) > grey_value = grey_value + 1 > > imp.show() > > > This leads to: > > TypeError: setFillColor(): 1st arg can't be coerced to java.awt.Color > > Unfortunatly it looks like setFillColor() needs the color determing value > in another form? Would it be possible to use 32bit picture too, because I > maybe need more then 65536 lable classes? > > Best regards > > Andreas > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html > -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
> I try to lable the ROIs with a grey color (1-65536 in a 16bit picture)
Just a follow up. I just noted that you do not need to label the cells at the start. You know where cell n is because it has coordinate XStart YStart in row n of the results table. So you could do your computation without labelling anything and then paint that cell at the end (flood filling with the result values you want at XStart YStart. Cheers Gabriel -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by Michael Schmid
On Oct 23, 2013, at 5:04 AM, Michael Schmid wrote:
> On Oct 22, 2013, at 22:14, Andreas Rzepecki wrote: > >> so here is what I want to do with this code: >> >> 1. Iterating through every pixel of the picture (row by row) >> 2. If the pixel is inside a certain ROI calculate a value for this pixel determined by the ROI and divided by the amount of pixel of this ROI (= pix_sap; nu ,L, p are constant)) >> 3. Calculating the sum of pix_sap per pixel row >> 4. Print the sum of pix_sap per pixel row > > Hi Andreas, > > as Gabriel wrote already, it is much better to have a loop over the rois. > If I understand your problem correctly, what about something like the following approach: > > Create an empty float (32 bit) image. > For each roi { > determine the value that depends on the roi and divide by roi area, this gives you 'pix_sap' > select the roi in the float image > Process>Math>Add add 'pix_sap' to the float image (it will be restricted to the roi) > } > Take the float image and resize it to width=1, height=original size, 'Average when downsizing" and Interpolation=none. This gives you the average of each row. Then multiply the values by the previous width, so you have the sum. > Have a line selection from (0,0) to (0, height-1) and use > array = getProfile (macro) or > pp = new ProfilePlot(imp); array = pp.getProfile(); (scripting). > This is your array of the sums of 'pix_sap' over each row. > > As it does not use any loop over pixels, an implementation in the imageJ macro language with BatchMode will be about as fast as any other implementation. imp = IJ.getImage() imp32 = imp.duplicate() IJ.run(imp32, "Analyze Particles...", "show=[Overlay Outlines] clear") overlay = imp32.getOverlay() IJ.run(imp32, "32-bit", "") ip = imp32.getProcessor() for i in range(overlay.size()): roi = overlay.get(i) ip.setRoi(roi) stats = ip.getStatistics() ip.setValue(float(ip.getWidth())/stats.pixelCount) ip.fill(roi) ip.resetRoi() ip.setInterpolationMethod(ImageProcessor.NONE) ip = ip.resize(1, ip.getHeight(), True) plot = Plot("Values", "X", "Y", None, ip.getPixels()) plot.show() Here is a JavaScript version of the Python script: imp = IJ.getImage() imp32 = imp.duplicate() IJ.run(imp32, "Analyze Particles...", "show=[Overlay Outlines] clear") overlay = imp32.getOverlay() IJ.run(imp32, "32-bit", "") ip = imp32.getProcessor() for i in range(overlay.size()): roi = overlay.get(i) ip.setRoi(roi) stats = ip.getStatistics() ip.setValue(float(ip.getWidth())/stats.pixelCount) ip.fill(roi) ip.resetRoi() ip.setInterpolationMethod(ImageProcessor.NONE) ip = ip.resize(1, ip.getHeight(), True) plot = Plot("Values", "X", "Y", None, ip.getPixels()) plot.show() A sample image is attached, courtesy of Andreas Rzepecki. It is a picture of the transition zone of two tree rings of Douglas-fir (left side: early wood, right side: late wood). -wayne [cid:[hidden email]] -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html Pseudotsuga_menziesii.png (33K) Download Attachment |
Yesterday's message was missing the JavaScript version of the Python example. Instead, the message had two copies of the Python script. Below is an enhanced version of the JavaScript, along with some notes about it.
1. This version of the script downloads the test image from the ImageJ website. 2. The test image contains metadata (a description of the image) added using the macro editor's Edit>Copy to Image Info command. The metadata is displayed when you check "Show metadata" in the dialog box. 3. The test image was saved using File>Save As>ZIP, which reduced its size by a factor of 18 by using lossless compression. 4. The IJ.error("Macro canceled") statement aborts the script without displaying a message. 5. The script uses an overlay instead of the ROI Manager. In many cases, overlays are faster, simpler and easier to use. 6. It uses the setValue() method instead of setColor() because setColor() only works with integer values in ImageJ 1.48e and earlier. 7. It uses the fill(roi) method instead of add() because add(), like most ImageProcessor methods, only works with rectangular ROIs. The getStatistics() method does work with non-rectangular ROIs. 8. The dummy first argument of the Plot() constructor ("") is needed because JavaScript displays an error message if it is missing. Here is the script: path = "http://imagej.nih.gov/ij/images/Pseudotsuga_menziesii.zip" gd = new GenericDialog("Options") gd.addCheckbox("Show source image", false) gd.addCheckbox("Show metadata", false) gd.addCheckbox("Show 32-bit image", false) gd.showDialog() if (gd.wasCanceled()) IJ.error("Macro canceled") showSourceImage = gd.getNextBoolean() showSourceImageMetadata = gd.getNextBoolean() show32bitImage = gd.getNextBoolean() imp = IJ.openImage(path) imp32 = imp.duplicate() IJ.run(imp32, "Analyze Particles...", "show=[Overlay Outlines] clear") overlay = imp32.getOverlay() IJ.run(imp32, "32-bit", "") ip = imp32.getProcessor() for (i=0; i<overlay.size(); i++) { roi = overlay.get(i) ip.setRoi(roi) stats = ip.getStatistics() ip.setValue(ip.width/stats.pixelCount) ip.fill(roi) } ip.resetRoi() ip.setInterpolationMethod(ImageProcessor.NONE) ip = ip.resize(1, ip.height, true) plot = new Plot("", "Row Averages", "X", "Y", null, ip.getPixels()) plot.show() if (showSourceImage) imp.show() if (show32bitImage) { imp32.setOverlay(null) IJ.run(imp32, "Enhance Contrast...", "saturated=0.4") imp32.show() } if (showSourceImageMetadata) IJ.showMessage(imp.getTitle(), imp.getProperty("Info")); -wayne On Oct 26, 2013, at 9:19 PM, Rasband, Wayne (NIH/NIMH) [E] wrote: > On Oct 23, 2013, at 5:04 AM, Michael Schmid wrote: > >> On Oct 22, 2013, at 22:14, Andreas Rzepecki wrote: >> >>> so here is what I want to do with this code: >>> >>> 1. Iterating through every pixel of the picture (row by row) >>> 2. If the pixel is inside a certain ROI calculate a value for this pixel determined by the ROI and divided by the amount of pixel of this ROI (= pix_sap; nu ,L, p are constant)) >>> 3. Calculating the sum of pix_sap per pixel row >>> 4. Print the sum of pix_sap per pixel row >> >> Hi Andreas, >> >> as Gabriel wrote already, it is much better to have a loop over the rois. >> If I understand your problem correctly, what about something like the following approach: >> >> Create an empty float (32 bit) image. >> For each roi { >> determine the value that depends on the roi and divide by roi area, this gives you 'pix_sap' >> select the roi in the float image >> Process>Math>Add add 'pix_sap' to the float image (it will be restricted to the roi) >> } >> Take the float image and resize it to width=1, height=original size, 'Average when downsizing" and Interpolation=none. This gives you the average of each row. Then multiply the values by the previous width, so you have the sum. >> Have a line selection from (0,0) to (0, height-1) and use >> array = getProfile (macro) or >> pp = new ProfilePlot(imp); array = pp.getProfile(); (scripting). >> This is your array of the sums of 'pix_sap' over each row. >> >> As it does not use any loop over pixels, an implementation in the imageJ macro language with BatchMode will be about as fast as any other implementation. > > Here is a Python script that iterates over the ROIs, which are created by the particle analyzer. In a float image, each ROI is filled with a value that is inversely proportional to the ROI area. The float image is then resized to a width of 1 to get the average for each row. > > imp = IJ.getImage() > imp32 = imp.duplicate() > IJ.run(imp32, "Analyze Particles...", "show=[Overlay Outlines] clear") > overlay = imp32.getOverlay() > IJ.run(imp32, "32-bit", "") > ip = imp32.getProcessor() > for i in range(overlay.size()): > roi = overlay.get(i) > ip.setRoi(roi) > stats = ip.getStatistics() > ip.setValue(float(ip.getWidth())/stats.pixelCount) > ip.fill(roi) > ip.resetRoi() > ip.setInterpolationMethod(ImageProcessor.NONE) > ip = ip.resize(1, ip.getHeight(), True) > plot = Plot("Values", "X", "Y", None, ip.getPixels()) > plot.show() > > Here is a JavaScript version of the Python script: > > imp = IJ.getImage() > imp32 = imp.duplicate() > IJ.run(imp32, "Analyze Particles...", "show=[Overlay Outlines] clear") > overlay = imp32.getOverlay() > IJ.run(imp32, "32-bit", "") > ip = imp32.getProcessor() > for i in range(overlay.size()): > roi = overlay.get(i) > ip.setRoi(roi) > stats = ip.getStatistics() > ip.setValue(float(ip.getWidth())/stats.pixelCount) > ip.fill(roi) > ip.resetRoi() > ip.setInterpolationMethod(ImageProcessor.NONE) > ip = ip.resize(1, ip.getHeight(), True) > plot = Plot("Values", "X", "Y", None, ip.getPixels()) > plot.show() > > A sample image is attached, courtesy of Andreas Rzepecki. It is a picture of the transition zone of two tree rings of Douglas-fir (left side: early wood, right side: late wood). > > -wayne -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Free forum by Nabble | Edit this page |