Sigma Filter sloooooow...

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Sigma Filter sloooooow...

lechristophe
The sigma filter is a "gentle smooth" filter found in Tony Collins' MBF
ImageJ.

It's the best filter for processing confocal stacks before projection,
but it's really really slow compared to the improved version of the
ImageJ base filters (that are now a lot faster since 1.38u, thanks to
Michael Schmid). I process a lot of stacks and I find myself waiting
several minutes for each stack.

Why is it so slow ? Is there a way to tweak it like the
Gaussian/Mean/Median filters, in order to get multiprocessor support and
to speed it ?

The source of the filter can be found here if you want to take a look at
the code :
https://www.bio.espci.fr/upload/files/Sigma_Filter.java

Thank you for your help and your support !

Christophe Leterrier
Reply | Threaded
Open this post in threaded view
|

Re: Sigma Filter sloooooow...

Michael Schmid
Hi Christophe,

unfortunately the sigma filter code is not very short, so it
is difficult for me to understand what exactly the filter does.
I have no access to the 1983 article by J.S. Lee describing
the filter.

Anyhow, there are a few hints that I can give:

Calculating the mean and sigma can be fast in ImageJ because
these values are derived from sums over the pixel values and
their squares.
When moving from one pixel to the next, one can subtract the
values that are not in the sum any more and add those that are
new. This was the main trick for speeding up "mean" and
"variance".

This trick won't work with a procedure that needs to examine
all the single pixel values, and the sigma filter contains such
a loop.

Nevertheless, you might do a few tricks to speed up the code
significantly:

- Convert it from a Plugin to a PlugInFilter (necessary for the
   following steps). You can also convert it to an
   ExtendedPlugInFilter, this will give you a the possibility
   to add preview. For an example, see
   http://imagejdocu.tudor.lu/Members/schmid/High_pass.java/view

- Specify the PARALLELIZE_STACKS flag for running stack slices
   in parallel on multiprocessor machines.

- You might use the CONVERT_TO_FLOAT flag of an
   (Extended)PlugInFilter.  Then, the run(ip) method of your
   filter will be always called with a FloatProcessor (3 times
   for an RGB image, once for each color channel).
   This has the advantage that you can access the pixel values
   directly from the pixels array of the FloatProcessor, without
   the getPixelValue and putPixelValue methods. I guess that you
   can gain a factor between 3 and 10 by this.
   Another advantage is that RGB images won't be converted to
   grayscale as in the current code.
   The downside: The pixel values will be uncalibrated, in
   contrast to getPixelValue, which gives calibrated pixel
   values for 8-bit and 16-bit grayscale.  As I understand the
   Sigma Filter, it won't matter whether you run it on calibrated
   or uncalibrated data.

- Finally, you could salvage the code for copying the image data
   into a shorter cache array from the RankFilters.java in the
   ImageJ source code. Since the cache array will remain in the
   CPU cache, this will give you some speed gain again.
   [Using a cache would also work if you need the calibrated values
   obtained by getPixelValues since that method has to be called
   only once per pixel to read the data into the cache, not
   dozens of times.]
   For details, see comment "data handling" in RankFilters.java.
   Other advantages of using a cache:
   -- The data written into the output image do not modify the
      input any more. This is not properly done in the current
      Sigma Filter: when accessing the neighborhood of a pixel,
      the previously modified pixels are read. Thus, the filter
      is not strictly isotropic.
   -- Easier handling of edge pixels: The cache can be slightly
      larger than the input image and its values corresponding
      to out-of-image pixels can be set to the edge pixel.
      Then, when reading the cache, there are no
      "if-pixel-outside-image" conditionals that would make the
      code complicated and slow.

It might be that the easiest way would be taking the
RankFilters.java source
   http://rsb.info.nih.gov/ij/source/ij/plugin/filter/RankFilters.java
There, delete the min/max/median code (except for the loop
accessing the pixels one-by-one) and add the functionality
required.  Having a circle with radius r instead of a square
neighborhood won't hurt. For a square, you might simply change
all occurrences of lineRadius[...] to radius (whereby radius is
1 for a 3x3 neighborhood, 2 for 5x5, and so on).

Hope this helps,

Michael
________________________________________________________________

On 18 Oct 2007, at 19:11, Christophe Leterrier wrote:

> The sigma filter is a "gentle smooth" filter found in Tony Collins'  
> MBF ImageJ.
>
> It's the best filter for processing confocal stacks before  
> projection, but it's really really slow compared to the improved  
> version of the ImageJ base filters (that are now a lot faster since  
> 1.38u, thanks to Michael Schmid). I process a lot of stacks and I  
> find myself waiting several minutes for each stack.
>
> Why is it so slow ? Is there a way to tweak it like the Gaussian/
> Mean/Median filters, in order to get multiprocessor support and to  
> speed it ?
>
> The source of the filter can be found here if you want to take a  
> look at the code :
> https://www.bio.espci.fr/upload/files/Sigma_Filter.java
>
> Thank you for your help and your support !
>
> Christophe Leterrier
Reply | Threaded
Open this post in threaded view
|

Re: Sigma Filter sloooooow...

lechristophe
Dear Michael,

Thank you very much for your detailed reply. The plugin was written by
Tony Collins. Concerning the definition of the Sigma filter, I found
this definition on the web :

http://www.geogr.ku.dk/CHIPS/Manual/f187.htm

So the parameters are the kernel (window size, default 3x3), the sigma
value (default 2), and the minimum number of pixels P (default 1).
My understanding is that the filter can be modified ("Lee's modified"
option in the plugin) by not taking the center pixel value into account
in the average of the whole window, in case the thrershold number of
pixels P is not reached.

I'll try to see if it's easy to copy/paste the coding core from the
Sigma plugin to the RankFilter, but I'm not Java skilled so if it
involves more than a quick and dirty hack it will be difficult for me !
But hopefully someone more skilled can have a look and help me.


Christophe Leterrier


Michael Schmid a écrit :

> Hi Christophe,
>
> unfortunately the sigma filter code is not very short, so it
> is difficult for me to understand what exactly the filter does.
> I have no access to the 1983 article by J.S. Lee describing
> the filter.
>
> Anyhow, there are a few hints that I can give:
>
> Calculating the mean and sigma can be fast in ImageJ because
> these values are derived from sums over the pixel values and
> their squares.
> When moving from one pixel to the next, one can subtract the
> values that are not in the sum any more and add those that are
> new. This was the main trick for speeding up "mean" and
> "variance".
>
> This trick won't work with a procedure that needs to examine
> all the single pixel values, and the sigma filter contains such
> a loop.
>
> Nevertheless, you might do a few tricks to speed up the code
> significantly:
>
> - Convert it from a Plugin to a PlugInFilter (necessary for the
>   following steps). You can also convert it to an
>   ExtendedPlugInFilter, this will give you a the possibility
>   to add preview. For an example, see
>   http://imagejdocu.tudor.lu/Members/schmid/High_pass.java/view
>
> - Specify the PARALLELIZE_STACKS flag for running stack slices
>   in parallel on multiprocessor machines.
>
> - You might use the CONVERT_TO_FLOAT flag of an
>   (Extended)PlugInFilter.  Then, the run(ip) method of your
>   filter will be always called with a FloatProcessor (3 times
>   for an RGB image, once for each color channel).
>   This has the advantage that you can access the pixel values
>   directly from the pixels array of the FloatProcessor, without
>   the getPixelValue and putPixelValue methods. I guess that you
>   can gain a factor between 3 and 10 by this.
>   Another advantage is that RGB images won't be converted to
>   grayscale as in the current code.
>   The downside: The pixel values will be uncalibrated, in
>   contrast to getPixelValue, which gives calibrated pixel
>   values for 8-bit and 16-bit grayscale.  As I understand the
>   Sigma Filter, it won't matter whether you run it on calibrated
>   or uncalibrated data.
>
> - Finally, you could salvage the code for copying the image data
>   into a shorter cache array from the RankFilters.java in the
>   ImageJ source code. Since the cache array will remain in the
>   CPU cache, this will give you some speed gain again.
>   [Using a cache would also work if you need the calibrated values
>   obtained by getPixelValues since that method has to be called
>   only once per pixel to read the data into the cache, not
>   dozens of times.]
>   For details, see comment "data handling" in RankFilters.java.
>   Other advantages of using a cache:
>   -- The data written into the output image do not modify the
>      input any more. This is not properly done in the current
>      Sigma Filter: when accessing the neighborhood of a pixel,
>      the previously modified pixels are read. Thus, the filter
>      is not strictly isotropic.
>   -- Easier handling of edge pixels: The cache can be slightly
>      larger than the input image and its values corresponding
>      to out-of-image pixels can be set to the edge pixel.
>      Then, when reading the cache, there are no
>      "if-pixel-outside-image" conditionals that would make the
>      code complicated and slow.
>
> It might be that the easiest way would be taking the
> RankFilters.java source
>   http://rsb.info.nih.gov/ij/source/ij/plugin/filter/RankFilters.java
> There, delete the min/max/median code (except for the loop
> accessing the pixels one-by-one) and add the functionality
> required.  Having a circle with radius r instead of a square
> neighborhood won't hurt. For a square, you might simply change
> all occurrences of lineRadius[...] to radius (whereby radius is
> 1 for a 3x3 neighborhood, 2 for 5x5, and so on).
>
> Hope this helps,
>
> Michael
> ________________________________________________________________
>
> On 18 Oct 2007, at 19:11, Christophe Leterrier wrote:
>
>> The sigma filter is a "gentle smooth" filter found in Tony Collins'
>> MBF ImageJ.
>>
>> It's the best filter for processing confocal stacks before projection,
>> but it's really really slow compared to the improved version of the
>> ImageJ base filters (that are now a lot faster since 1.38u, thanks to
>> Michael Schmid). I process a lot of stacks and I find myself waiting
>> several minutes for each stack.
>>
>> Why is it so slow ? Is there a way to tweak it like the
>> Gaussian/Mean/Median filters, in order to get multiprocessor support
>> and to speed it ?
>>
>> The source of the filter can be found here if you want to take a look
>> at the code :
>> https://www.bio.espci.fr/upload/files/Sigma_Filter.java
>>
>> Thank you for your help and your support !
>>
>> Christophe Leterrier
>