[ImageJ-devel] Local Neighborhood stuff

Tobias Pietzsch pietzsch at mpi-cbg.de
Mon Aug 20 08:08:51 CDT 2012


Hi,

> A basic question: how do we deal with out-of-bounds? Some strategies
> might require to know whether you are outside bounds, or even
> specify the OOBS. Example: an average filter wants to skip the pixels
> that are not inside the image.
>
> How do we get that with the neighborhood iterator?

I think there is no simple answer to that. It depends on what you want.
In my opinion, there are two things an algorithm requires out-of-bounds
type behaviour.

1.) get out-of-bounds values. Here the algorithm (e.g. a min filter)
needs values of out-of-bounds pixels, but actually it doesn't care where
they come from. Maybe the image is bigger than the interval the 
algorithm was called on, then these are real image values. Maybe these
values are generated by an OutOfBounds strategy. In this case, the
algorithm doesn't need to know where the values come from and you can 
just use the current design, e.g.
   Shape.neighborhoods( Views.extendMirrorSingle( img ) );

2.) an algorithm needs to know whether a given pixel is out-of-bounds
to take some action like skip that pixel (e.g. in that average filter).

In the second case the algorithm does usually not require a value for 
the out-of-bounds pixel. I would not realize this using the existing
OutOfBounds mechanisms (I also have to admit, that I do not see an easy 
way to do it).

I would propose the following:
Make a "BoundedShape" wrapper, that takes a Shape and a clipping 
interval. BoundedShape produces Accessibles on Neighborhoods that have 
cursors that implement Bounded. This could be a general wrapper that 
works on every neighborhood shape.

Then on top of that, one could implement another wrapper that just skips
out-of-bounds pixels altogether. So in your average filter, a 3x3 
neighborhood on the clipping border would just become a 2x3 
neighborhood, eliminating the out-of-bounds check in the algorithm.


Another thing -- There should be a change to the Shape interface:
Shape.neighborhoodsRandomAccessible() should take a RandomAccessible, 
not necessarily an RandomAccessibleInterval. There is no reason not to
have a RandomAccess<Neighborhood<T>> on an infinite image.

I will implement this as soon as possible.


best regards,
Tobias

On 08/18/2012 09:37 PM, Jean-Yves Tinevez wrote:
> Hi Tobias,
>
> Congratulations on this very clever design!
>
> I totally buy it, and just have basic questions.
>
>
>     Cursor/RandomAccess< Neighborhood<T> >
>     ==============================__==========
>     To move a neighborhood around, we use standard accessor interfaces.
>     Assume you have a RandomAccess<Neighborhood<T>> a.
>     Using a.setPosition() you can position the center of the neighborhood.
>     Using a.get() you obtain a Neighborhood<T> (which you can then iterate).
>
>     In many ways, the Neighborhood is like a NativeType. It is just a
>     reference into an underlying structure. If you have a Cursor<T> of
>     a NativeType, then the result T t = cursor.get() will be invalidated
>     when you advance the cursor. The same holds for Cursor<Neighborhood<T>>.
>     When you move the cursor, the neighborhood Neighborhood<T> n =
>     cursor.get() will be invalidated when you advance the cursor.
>
>
> This is really clever, clearly in the lines of master Stephan. Every
> time I ask a question, he tells me to focus on a new type.
>
>
>     IterableInterval/__RandomAccessible< Neighborhood<T> >
>     ==============================__======================
>     Of course, once you have the Accessors, it's easy to put the into
>     Accessibles and benefit from all the goodies that are in ImgLib already.
>     For example, if you have implemented a RandomAccess<Neighborhood<T>>
>     it is straightforward to wrap it into a RandomAccessible and use
>     Views.iterable() to get a Cursor over Neighborhood<T>.
>
>     This results is pure syntactic sugar and lets you write sexy code like
>     this:
>        for ( Neighborhood<T> n : neighborhoods )
>            for ( T t : n )
>                ...
>
>
> A basic question: how do we deal with out-of-bounds? Some strategies
> might require to know whether you are outside bounds, or even specify
> the OOBS. Example: an average filter wants to skip the pixels that are
> not inside the image.
>
> How do we get that with the neighborhood iterator?
>
>     As you might have noticed, I have completely neclected the copyOn() and
>     updateSource() methods we discussed before.  I don't really see the need
>     for them in the above design.
>
>     Ok, I hope you will have a look at the code
>     (branch "tobias-neighborhood-__experiments") and tell me what you think.
>
> Will do!
> Thanks!
> jy
>




More information about the ImageJ-devel mailing list