0
# Image Processing
1
2
Access to ImageJ2's extensive image processing capabilities through Python-friendly interfaces, including mathematical operations, filtering, array-like access, and transformation functions on ImgLib2 RandomAccessibleInterval objects.
3
4
## Capabilities
5
6
### Mathematical Operations
7
8
Perform element-wise mathematical operations on RandomAccessibleInterval objects using Python operators.
9
10
```python { .api }
11
# Mathematical operators (applied to RandomAccessibleInterval objects)
12
def __add__(self, other):
13
"""Element-wise addition: image + value or image + image"""
14
15
def __sub__(self, other):
16
"""Element-wise subtraction: image - value or image - image"""
17
18
def __mul__(self, other):
19
"""Element-wise multiplication: image * value or image * image"""
20
21
def __truediv__(self, other):
22
"""Element-wise division: image / value or image / image"""
23
```
24
25
**Usage Examples:**
26
27
```python
28
# Load or create images
29
img1 = ij.py.to_img(np.random.rand(100, 100))
30
img2 = ij.py.to_img(np.random.rand(100, 100))
31
32
# Mathematical operations
33
result_add = img1 + img2 # Image addition
34
result_scale = img1 * 2.5 # Scalar multiplication
35
result_subtract = img1 - 128 # Offset subtraction
36
result_normalize = img1 / img1.max() # Normalization
37
38
# Convert back to Python for display
39
result_array = ij.py.from_java(result_add)
40
```
41
42
### Array-Like Access and Slicing
43
44
Access image data using familiar Python array indexing and slicing syntax.
45
46
```python { .api }
47
def __getitem__(self, key):
48
"""
49
Array-like access with support for integer indexing and slice objects.
50
51
Args:
52
key: int, slice, or tuple of int/slice objects
53
54
Returns:
55
Single pixel value or sliced RandomAccessibleInterval
56
"""
57
```
58
59
**Usage Examples:**
60
61
```python
62
# Create test image
63
img = ij.py.to_img(np.random.rand(100, 100, 50))
64
65
# Single pixel access
66
pixel_value = img[50, 50, 25]
67
68
# Slicing operations
69
roi = img[10:90, 20:80, :] # Region of interest
70
plane = img[:, :, 25] # Single Z plane
71
subset = img[::2, ::2, ::5] # Downsampled version
72
73
# Multi-dimensional slicing
74
volume = img[25:75, 25:75, 10:40] # 3D subvolume
75
```
76
77
### Image Transformations
78
79
Transform image geometry and dimensions using ImgLib2 operations.
80
81
```python { .api }
82
def transpose() -> "RandomAccessibleInterval":
83
"""Transpose all dimensions of the image."""
84
85
@property
86
def T() -> "RandomAccessibleInterval":
87
"""Shorthand property for transpose operation."""
88
89
def squeeze(axis=None):
90
"""
91
Remove axes of length one from the image.
92
93
Args:
94
axis: int, tuple of ints, or None for all single-dimension axes
95
96
Returns:
97
RandomAccessibleInterval with singleton dimensions removed
98
"""
99
```
100
101
**Usage Examples:**
102
103
```python
104
# Create test image with singleton dimensions
105
img = ij.py.to_img(np.random.rand(1, 100, 100, 1, 50))
106
print(f"Original shape: {img.shape}") # (1, 100, 100, 1, 50)
107
108
# Remove all singleton dimensions
109
squeezed = img.squeeze()
110
print(f"Squeezed shape: {squeezed.shape}") # (100, 100, 50)
111
112
# Remove specific axis
113
partial_squeeze = img.squeeze(axis=0)
114
print(f"Partial squeeze: {partial_squeeze.shape}") # (100, 100, 1, 50)
115
116
# Transpose operations
117
transposed = img.transpose()
118
# or equivalently:
119
transposed = img.T
120
```
121
122
### Type and Shape Information
123
124
Query image properties and characteristics.
125
126
```python { .api }
127
@property
128
def dtype():
129
"""Get the dtype of the RandomAccessibleInterval as ImgLib2 Type subclass."""
130
131
@property
132
def shape():
133
"""Get shape tuple of the interval dimensions."""
134
135
@property
136
def ndim():
137
"""Get number of dimensions in the image."""
138
```
139
140
**Usage Examples:**
141
142
```python
143
img = ij.py.to_img(np.random.rand(256, 256, 100).astype(np.float32))
144
145
# Query image properties
146
print(f"Shape: {img.shape}") # (256, 256, 100)
147
print(f"Dimensions: {img.ndim}") # 3
148
print(f"Data type: {img.dtype}") # FloatType class
149
print(f"Min coords: {[img.min(d) for d in range(img.ndim)]}")
150
print(f"Max coords: {[img.max(d) for d in range(img.ndim)]}")
151
```
152
153
### ImageJ2 Ops Integration
154
155
Access ImageJ2's Ops framework for advanced image processing operations.
156
157
```python { .api }
158
# Through the ImageJ2 gateway, access ops for processing
159
# Examples of common operations available via ij.op()
160
```
161
162
**Usage Examples:**
163
164
```python
165
# Create test image
166
img = ij.py.to_img(np.random.rand(256, 256))
167
168
# ImageJ2 Ops operations
169
gaussian_filtered = ij.op().filter().gauss(img, 2.0)
170
median_filtered = ij.op().filter().median(img, ij.op().create().kernelGauss([3, 3]))
171
thresholded = ij.op().threshold().otsu(img)
172
173
# Mathematical operations via Ops
174
img_doubled = ij.op().math().multiply(img, 2.0)
175
img_log = ij.op().math().log(img)
176
177
# Morphological operations
178
opened = ij.op().morphology().open(img, ij.op().create().kernelDisk(5))
179
closed = ij.op().morphology().close(img, ij.op().create().kernelDisk(5))
180
181
# Convert results back to Python
182
result = ij.py.from_java(gaussian_filtered)
183
```
184
185
### Stack and Volume Operations
186
187
Specialized functions for working with multi-dimensional image stacks.
188
189
```python { .api }
190
def rai_slice(rai, imin: tuple, imax: tuple, istep: tuple):
191
"""
192
Slice ImgLib2 RandomAccessibleInterval using Python slice notation.
193
194
Args:
195
rai: Input RandomAccessibleInterval
196
imin: Tuple of minimum values for each dimension
197
imax: Tuple of maximum values for each dimension
198
istep: Tuple of step sizes for each dimension
199
200
Returns:
201
Sliced RandomAccessibleInterval including both imin and imax bounds
202
"""
203
```
204
205
**Usage Examples:**
206
207
```python
208
from imagej.stack import rai_slice
209
210
# Create 3D volume
211
volume = ij.py.to_img(np.random.rand(100, 100, 50))
212
213
# Extract middle region with custom stepping
214
roi = rai_slice(
215
volume,
216
imin=(25, 25, 10), # Start coordinates
217
imax=(75, 75, 40), # End coordinates
218
istep=(1, 1, 2) # Step sizes (every other Z slice)
219
)
220
221
# Convert back to examine
222
roi_array = ij.py.from_java(roi)
223
print(f"ROI shape: {roi_array.shape}")
224
```
225
226
## Integration with ImageJ2 Services
227
228
RandomAccessibleInterval objects integrate seamlessly with ImageJ2 services:
229
230
- **Ops Service**: `ij.op().run("operation.name", img, params)`
231
- **Convert Service**: `ij.convert().convert(img, target_type)`
232
- **Dataset Service**: `ij.dataset().create(img)`
233
234
## Performance Considerations
235
236
- **View Operations**: Slicing and transformations create views, not copies
237
- **Memory Sharing**: ImgLib2 images can share memory with NumPy arrays via imglyb
238
- **Lazy Evaluation**: Many operations are computed on-demand
239
- **Threading**: ImgLib2 operations are thread-safe and can utilize multiple cores
240
241
## Error Handling
242
243
Common issues when working with image processing:
244
245
- **Dimension Mismatch**: Ensure compatible dimensions for mathematical operations
246
- **Type Compatibility**: Some operations require specific numeric types
247
- **Memory Limits**: Large images may require increased JVM heap size
248
- **Index Bounds**: Slicing operations validate bounds automatically