Skip to content

Commit

Permalink
Move media into same directory structure
Browse files Browse the repository at this point in the history
And clean up some links.
  • Loading branch information
ctrueden committed Apr 21, 2024
1 parent c438ffa commit d717306
Show file tree
Hide file tree
Showing 69 changed files with 62 additions and 62 deletions.
4 changes: 2 additions & 2 deletions imglib2/accessibles.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ sidebar: true

In ImgLib2, images are represented by *Accessibles*. *Image* here refers to any (partial) function from coordinates to values.

In the [ previous section](/imglib2/accessors) we have seen how pixel values can be manipulated using [ Accessors](/imglib2/accessors). Accessors are obtained from *Accessibles*. For example we have used:
In the [ previous section](accessors) we have seen how pixel values can be manipulated using [ Accessors](accessors). Accessors are obtained from *Accessibles*. For example we have used:
```
final Cursor< UnsignedByteType > cursor = img.localizingCursor();
```
Expand All @@ -20,7 +20,7 @@ The UML diagram below shows the integer part of the *Accessible* interface hiera

[RandomAccessible](http://javadoc.scijava.org/ImgLib2/net/imglib2/RandomAccessible.html) and [RandomAccessibleInterval](http://javadoc.scijava.org/ImgLib2/net/imglib2/RandomAccessibleInterval.html) represent images that are random-accessible at integer coordinates. (Remember: an image is a - possibly partial - function from coordinates to values.) You can obtain a RandomAccess on the data using the `randomAccess()` or `randomAccess(Interval)` methods.

All ImgLib2 classes representing pixel images are [RandomAccessibles](http://javadoc.scijava.org/ImgLib2/net/imglib2/RandomAccessible.html). We already used this in [ a previous example](/imglib2/accessors#randomaccess) to obtain a `RandomAccess` on an `ArrayImg`.
All ImgLib2 classes representing pixel images are [RandomAccessibles](http://javadoc.scijava.org/ImgLib2/net/imglib2/RandomAccessible.html). We already used this in [ a previous example](accessors#randomaccess) to obtain a `RandomAccess` on an `ArrayImg`.
```
final RandomAccess< UnsignedByteType > r = img.randomAccess();
```
Expand Down
14 changes: 7 additions & 7 deletions imglib2/accessors.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ In ImgLib2, images are manipulated using *Accessors*. For pixel images, you can

The accessors provided by ImgLib2 typically implement `Cursor` or `RandomAccess`. `Cursor` and `RandomAccess` are aggregations of interfaces covering the above three points. A simplified UML diagram for the interface hierarchy is shown below. (The simplification is with respect to real-coordinate interfaces for continuous images that are left out for now.)

!["imglib2-accessors-simplified-integer"](media/imglib2/imglib2-accessors-simplified-integer.png)
!["imglib2-accessors-simplified-integer"](imglib2-accessors-simplified-integer.png)

ImgLib2 supports two basic access patterns:

Expand Down Expand Up @@ -62,7 +62,7 @@ public class DrawWhitePixels
}
```

In lines *013-015* we create a 8-bit gray-level image, in line *029* we show the result (like in the [ previous example](/imglib2/getting-started.md#opening-and-displaying-image-files)).
In lines *013-015* we create a 8-bit gray-level image, in line *029* we show the result (like in the [ previous example](getting-started.md#opening-and-displaying-image-files)).

In line *017* we create a `RandomAccess` to the image. `Img` implements the [RandomAccessible](http://javadoc.scijava.org/ImgLib2/net/imglib2/RandomAccessible.html) interface, thus we can use `randomAccess()` to obtain one. The `RandomAccess` has the same generic type, `UnsignedByteType`, as the image.

Expand Down Expand Up @@ -456,7 +456,7 @@ Lines *028-031* show how to use `findmax` and get the maximum value and coordina

### Notes

- The iteration order is subject to implementation, specialized for each memory layout to minimize access time. For example, an [ArrayImg](http://javadoc.scijava.org/ImgLib2/net/imglib2/img/array/ArrayImg.html) has a different iteration order from a [CellImg](http://javadoc.scijava.org/ImgLib2/net/imglib2/img/cell/CellImg.html). This is nicely illustrated in [ ImgLib2 Example 2b - Duplicating an Img using a different ImgFactory ](/imglib2/examples#example-2b---duplicating-an-img-using-a-different-imgfactory).
- The iteration order is subject to implementation, specialized for each memory layout to minimize access time. For example, an [ArrayImg](http://javadoc.scijava.org/ImgLib2/net/imglib2/img/array/ArrayImg.html) has a different iteration order from a [CellImg](http://javadoc.scijava.org/ImgLib2/net/imglib2/img/cell/CellImg.html). This is nicely illustrated in [ ImgLib2 Example 2b - Duplicating an Img using a different ImgFactory ](examples#example-2b---duplicating-an-img-using-a-different-imgfactory).
- Typically, there are two variants of Cursors available. One that calculates its location per each iteration and one that calculates it only per localization request. The former is more efficient when localization occurs frequently, the latter otherwise. In the *maximum-finding* example, we use the latter because localization is only required once after the maximum has been found. The former one could be obtained using `localizingCursor()` instead of `cursor()` (see [IterableInterval](http://javadoc.scijava.org/ImgLib2/net/imglib2/IterableInterval.html) API doc.)
- `copyCursor()` is a work-around to circumvent a *javac* bug with covariant return type overriding (see [bug report](http://bugs.sun.com/view_bug.do?bug_id=6656332)). In the future (with JDK7) every `Sampler` can be copied using `copy()` instead of having specialised `copyCursor()`, `copyRandomAccess()`, ... methods.

Expand All @@ -470,7 +470,7 @@ ImgLib2 is not restricted to rasterized images and integer coordinates It also s

The following image shows the UML diagram for the ImgLib2 accessor interface hierarchy. The real-coordinate counterparts that were missing in the simplified version [ above](accessors.md) are highlighted.

![UML for ImgLib2 accessor interfaces](media/imglib2/imglib2-accessors-real.png)
![UML for ImgLib2 accessor interfaces](imglib2-accessors-real.png)

Real equivalents of the `Positionable` and `Localizable` interfaces have been added by which real-valued coordinates can be accessed.

Expand Down Expand Up @@ -555,7 +555,7 @@ Our super class [RealPoint](http://javadoc.scijava.org/ImgLib2/net/imglib2/RealP

Finally, we provide the `copy()` and `copyRealRandomAccess()` methods to complete the `RealRandomAccess` interface implementation. A copied accessor is supposed to refer to the same position and value, therefore we `setPosition` in line *051*.

![UML for abstract RealRandomAccess class hierarchy](Media_imglib2/imglib2-abstract-accessors-real-new-vertical.png)
![UML for abstract RealRandomAccess class hierarchy](imglib2-abstract-accessors-real-new-vertical.png)

Now let's use the `MandelbrotRealRandomAccess` to render a pixel image:

Expand Down Expand Up @@ -625,7 +625,7 @@ cursor.get().set( mb.get() );
`cursor.get()` gives the `UnsignedByteType` reference to the value under the cursor. `mb.get()` gives the `UnsignedByteType` reference to the value computed by the `MandelbrotRealRandomAccess`. Then we `set()` the value of the former to the value of the latter.
When you run the code you will see this:
![mandelbrot-1](media/imglib2/mandelbrot-1.png){style="width: 300px" caption="Mandelbrot fractal"}
![mandelbrot-1](mandelbrot-1.png){style="width: 300px" caption="Mandelbrot fractal"}
Because we have a `RealRandomAccess` you can zoom in indefinitely (until you hit the `double` precision limit). If you like, you can play around with the scale and offset values. Here is another example obtained with
Expand All @@ -635,7 +635,7 @@ final double[] offset = new double[] { -1.3875, 0.045 };
```
![](media/imglib2/mandelbrot-2.png){style="width: 300px" caption="Mandelbrot fractal"}
![](mandelbrot-2.png){style="width: 300px" caption="Mandelbrot fractal"}
### Notes
Expand Down
File renamed without changes
6 changes: 3 additions & 3 deletions imglib2/changes-from-imglib1.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ At the [Madison hackathon](/events/2011-hackathon-in-madison), quite a lot has b

## Where is the Image?

![Fig. 1](media/imglib2/imglib2-data.png "Title: **Fig1** ")
![Fig. 1](imglib2-data.png "Title: **Fig1** ")
ImgLib2 interfaces for data collections in *n*-dimensional Euclidean space. The key feature is distinction between random access vs. iteration and real vs. integer coordinate access.'%}

In *ImgLib*, the *Image* class was a wrapper for a limited subset of possible meta-data and a *Container* that provided access to the actual pixels. The overwhelming majority of methods in both *Image* and *Container* were almost identical. Furthermore, implementing algorithms for *Image* limited their portability to situations where different meta-data or less meta-data was required or different strategies for pixel access were appropriate.}

[Fig]]media/imglib2/imglib2-data.png' title='**Fig. 1** ImgLib2 interfaces for data collections in *n*-dimensional Euclidean space. The key feature is distinction between random access vs. iteration and real vs. integer coordinate access.'%} In *ImgLib*, the *Image* class was a wrapper for a limited subset of possible meta-data and a *Container* that provided access to the actual pixels. The overwhelming majority of methods in both *Image* and *Container* were almost identical. Furthermore, implementing algorithms for *Image* limited their portability to situations where different meta-data or less meta-data was required or different strategies for pixel access were appropriate.
[Fig]]imglib2-data.png' title='**Fig. 1** ImgLib2 interfaces for data collections in *n*-dimensional Euclidean space. The key feature is distinction between random access vs. iteration and real vs. integer coordinate access.'%} In *ImgLib*, the *Image* class was a wrapper for a limited subset of possible meta-data and a *Container* that provided access to the actual pixels. The overwhelming majority of methods in both *Image* and *Container* were almost identical. Furthermore, implementing algorithms for *Image* limited their portability to situations where different meta-data or less meta-data was required or different strategies for pixel access were appropriate.

In ImgLib2, the Image class has been abandoned. Instead, there is a set of interfaces that describe how data elements (pixels) can be accessed. Fig. 2 shows a UML-diagram visualizing the interface inheritance graph. The most important interfaces are

Expand All @@ -37,7 +37,7 @@ Opposed to the intuitive shortcut that you would just replace *Image* by *Img* t

## Where is the LocalizableCursor?

{% include thumbnail src='/media/imglib2/imglib2-access.png' title='**Fig. 2** ImgLib2 interfaces for access to sample data and to real and integer coordinates in *n*-dimensional Euclidean space.'%} Iteration in ImgLib2 (as in ImgLib) implies constant and thus repeatable order. Therefore a *Cursor* can always localize itself, either by going the hard way and reasoning the position from it's iteration index or by tracking the position per move. There is no extra interface required to distinguish this behavior but you can choose which *Cursor* to acquire by *Iterable(Real)Interval.cursor()* and *Iterable(Real)Interval.localizingCursor()*. Fig. 2 shows a UML-diagram visualizing the interface inheritance graph.
{% include thumbnail src='imglib2-access.png' title='**Fig. 2** ImgLib2 interfaces for access to sample data and to real and integer coordinates in *n*-dimensional Euclidean space.'%} Iteration in ImgLib2 (as in ImgLib) implies constant and thus repeatable order. Therefore a *Cursor* can always localize itself, either by going the hard way and reasoning the position from it's iteration index or by tracking the position per move. There is no extra interface required to distinguish this behavior but you can choose which *Cursor* to acquire by *Iterable(Real)Interval.cursor()* and *Iterable(Real)Interval.localizingCursor()*. Fig. 2 shows a UML-diagram visualizing the interface inheritance graph.

{% include clear%}

Expand Down
4 changes: 2 additions & 2 deletions imglib2/developing.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ sidebar: true

## Introduction

The [ImgLib2](/imglib2) library uses [Maven](/develop/maven) to manage project dependencies. One advantage of this approach is nice integration with various development environments ([IDEs](/develop/ides)).
The [ImgLib2](/imglib2) library uses [Maven](https://imagej.net/develop/maven) to manage project dependencies. One advantage of this approach is nice integration with various development environments ([IDEs](https://imagej.net/develop/ides)).

Because people tend to have differing IDE configurations, we do not put project metadata files (e.g., `.classpath`, `.project` and `.settings` for Eclipse) into the git repository. Instead, the IDE can use Maven's `pom.xml` file directly to manage your dependencies in a better way.

Expand All @@ -17,7 +17,7 @@ You can clone the ImgLib2 code using Git with the URL: **<git://github.com/imgli

To develop ImgLib2 in Eclipse, follow these steps:

1. [Install the Maven plugin](/develop/maven-and-eclipse)
1. [Install the Maven plugin](https://imagej.net/develop/maven-and-eclipse)
2. Choose {% include bc path='File | Import'%} from the Eclipse menu
3. Select "Existing Maven Projects" and click Next
4. For the Root Directory, specify the path where you cloned ImgLib2
Expand Down
File renamed without changes.
File renamed without changes
File renamed without changes.
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
14 changes: 7 additions & 7 deletions imglib2/discussion.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,23 +156,23 @@ RandomAccessibleIntervalView< FloatType > view4 = Views.superIntervalView( view3
```
The original `img` looks like this:

![](/media/imglib2/imglib2views-img.png)
![](imglib2views-img.png)

This is extended to infinity (using mirroring strategy) resulting in the unbounded `RandomAccessible view1`. A crop of `view1` looks like this:

![](/media/imglib2/imglib2views-ext1.png)
![](imglib2views-ext1.png)

Then we take a subview `view2` (which is again a bounded interval)

![](/media/imglib2/imglib2views-extsub1.png)
![](imglib2views-extsub1.png)

We extend that to get `view3` and take a subview `view4` which looks like this:

![](/media/imglib2/imglib2views-extsub1extsub2.png)
![](imglib2views-extsub1extsub2.png)

Now assume that we want `RandomAccess` into `view4`. If we know in advance interval in which we will use the access, `view4` can possibly provide more efficient access. Consider this:

![](/media/imglib2/imglib2views-extsub1extsub2regions.png)
![](imglib2views-extsub1extsub2regions.png)

If we want to access only the green region, the `RandomAccess` can fall through all the way to the original `img` without needing out-of-bounds values. We simply wrap a `RandomAccess` on `img` with a coordinate translation to the top-left corner of `view4`

Expand All @@ -186,7 +186,7 @@ A view hierarchy may consist of an arbitrary sequence of views that do coordinat

### Transformation Hierarchies

{% include thumbnail src='/media/imglib2/imglib2-transform.png' title='Simplified visualization of the hierarchy of ImgLib2 transforms that can be reduced by concatenation. Note that the interfaces responsible for concatenation are not implemented by the transform hierarchy. Necessary access to trivial parameters in specialized transforms is implemented just once in abstract classes.'%} We thought that it might at some point be useful to have a generic way of contracting chains of transforms. The idea is to have a hierarchy of transformations, i.e., a Translation is a Rigid transform is an Affine transform, etc. The hierarchy determines which transformations can be concatenated. It would be hard to concatenate transformations from different branches in the tree. For example, it is possible to concatenate a Translation and a Rotation to a Rigid transform. However, it is not clear whether we always want to do that. So we decided that transforms should be concatenable with their descendants in the hierarchy but not the other way around. That is, a Rigid can be concatenated with a Translation (resulting in another Rigid). But a Translation can not be concatenated with a Rigid (because this would not always result in another Translation).
{% include thumbnail src='imglib2-transform.png' title='Simplified visualization of the hierarchy of ImgLib2 transforms that can be reduced by concatenation. Note that the interfaces responsible for concatenation are not implemented by the transform hierarchy. Necessary access to trivial parameters in specialized transforms is implemented just once in abstract classes.'%} We thought that it might at some point be useful to have a generic way of contracting chains of transforms. The idea is to have a hierarchy of transformations, i.e., a Translation is a Rigid transform is an Affine transform, etc. The hierarchy determines which transformations can be concatenated. It would be hard to concatenate transformations from different branches in the tree. For example, it is possible to concatenate a Translation and a Rotation to a Rigid transform. However, it is not clear whether we always want to do that. So we decided that transforms should be concatenable with their descendants in the hierarchy but not the other way around. That is, a Rigid can be concatenated with a Translation (resulting in another Rigid). But a Translation can not be concatenated with a Rigid (because this would not always result in another Translation).

Having a generic way of concatenating Rigid with all of its children means that all children must also be a Rigid. That is, we must be able to ask a Translation for its rotation matrix and so on. I was afraid, that this adds too much (implementation) overhead, but Stephan convinced me that this is the best way to go. Actually, it should be possible to make this relatively painless by having an hierarchy of abstract transform classes.

Expand Down Expand Up @@ -284,7 +284,7 @@ Tobias and Preibisch discussed today that the name `ExtendedRandomAccessibleInte

It is irritating as it is actually NOT an Interval. Instead one could name it for example `OutOfBoundsView`, which is also much shorter. It is only used for this purpose and the name is self-explanatory.

We also added some convenience methods in the Views class to construct them very easily, see here: [ How does ImgLib2 handle OutOfBounds?](/imglib2/changes-from-imglib1#how-does-imglib2-handle-outofbounds)
We also added some convenience methods in the Views class to construct them very easily, see here: [ How does ImgLib2 handle OutOfBounds?](changes-from-imglib1#how-does-imglib2-handle-outofbounds)

### Should Iterator (and so Cursor) have a bck() call?

Expand Down
File renamed without changes
File renamed without changes
File renamed without changes
6 changes: 3 additions & 3 deletions imglib2/documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ title: ImgLib2 Documentation
sidebar: true
---

1. [ Getting Started](/imglib2/getting-started)
2. [ Accessors](/imglib2/accessors)
3. [ Accessibles](/imglib2/accessibles)
1. [ Getting Started](getting-started)
2. [ Accessors](accessors)
3. [ Accessibles](accessibles)
Loading

0 comments on commit d717306

Please sign in to comment.