Login  Register

Re: Python iteration through Pixel/ROI to slow ... ?

Posted by Rasband, Wayne (NIH/NIMH) [E] on Oct 27, 2013; 1:19am
URL: http://imagej.273.s1.nabble.com/Python-iteration-through-Pixel-ROI-to-slow-tp5005274p5005335.html

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

[cid:[hidden email]]




--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html

Pseudotsuga_menziesii.png (33K) Download Attachment