0
# Morphology
1
2
Morphological image processing operations including erosion, dilation, opening, closing, skeletonization, and advanced morphological algorithms. Supports both binary and grayscale morphology with customizable structuring elements.
3
4
## Capabilities
5
6
### Basic Binary Morphology
7
8
Fundamental morphological operations on binary images using structuring elements to modify object shapes and connectivity.
9
10
```python { .api }
11
def binary_erosion(image, footprint=None, out=None, border_value=0, brute_force=False):
12
"""
13
Perform binary erosion of an image.
14
15
Parameters:
16
image : array_like
17
Binary input image
18
footprint : array_like, optional
19
Structuring element used for erosion
20
out : ndarray, optional
21
Array for storing result
22
border_value : int, optional
23
Value at border
24
brute_force : bool, optional
25
Memory condition for border_value != 0
26
27
Returns:
28
ndarray
29
Eroded binary image
30
"""
31
32
def binary_dilation(image, footprint=None, out=None, border_value=0, brute_force=False):
33
"""
34
Perform binary dilation of an image.
35
36
Parameters:
37
image : array_like
38
Binary input image
39
footprint : array_like, optional
40
Structuring element used for dilation
41
out : ndarray, optional
42
Array for storing result
43
border_value : int, optional
44
Value at border
45
brute_force : bool, optional
46
Memory condition for border_value != 0
47
48
Returns:
49
ndarray
50
Dilated binary image
51
"""
52
53
def binary_opening(image, footprint=None, out=None, border_value=0, brute_force=False):
54
"""
55
Perform binary opening (erosion followed by dilation).
56
57
Parameters:
58
image : array_like
59
Binary input image
60
footprint : array_like, optional
61
Structuring element
62
out : ndarray, optional
63
Array for storing result
64
border_value : int, optional
65
Value at border
66
brute_force : bool, optional
67
Memory condition for border_value != 0
68
69
Returns:
70
ndarray
71
Opened binary image
72
"""
73
74
def binary_closing(image, footprint=None, out=None, border_value=0, brute_force=False):
75
"""
76
Perform binary closing (dilation followed by erosion).
77
78
Parameters:
79
image : array_like
80
Binary input image
81
footprint : array_like, optional
82
Structuring element
83
out : ndarray, optional
84
Array for storing result
85
border_value : int, optional
86
Value at border
87
brute_force : bool, optional
88
Memory condition for border_value != 0
89
90
Returns:
91
ndarray
92
Closed binary image
93
"""
94
```
95
96
### Grayscale Morphology
97
98
Morphological operations on grayscale images that preserve intensity information while modifying image structure.
99
100
```python { .api }
101
def erosion(image, footprint=None, out=None, shift_x=False, shift_y=False):
102
"""
103
Perform grayscale erosion of an image.
104
105
Parameters:
106
image : array_like
107
Input image
108
footprint : array_like, optional
109
Structuring element for erosion
110
out : ndarray, optional
111
Array for storing result
112
shift_x : bool, optional
113
Shift structuring element about center
114
shift_y : bool, optional
115
Shift structuring element about center
116
117
Returns:
118
ndarray
119
Eroded image
120
"""
121
122
def dilation(image, footprint=None, out=None, shift_x=False, shift_y=False):
123
"""
124
Perform grayscale dilation of an image.
125
126
Parameters:
127
image : array_like
128
Input image
129
footprint : array_like, optional
130
Structuring element for dilation
131
out : ndarray, optional
132
Array for storing result
133
shift_x : bool, optional
134
Shift structuring element about center
135
shift_y : bool, optional
136
Shift structuring element about center
137
138
Returns:
139
ndarray
140
Dilated image
141
"""
142
143
def opening(image, footprint=None, out=None):
144
"""
145
Perform grayscale opening (erosion followed by dilation).
146
147
Parameters:
148
image : array_like
149
Input image
150
footprint : array_like, optional
151
Structuring element
152
out : ndarray, optional
153
Array for storing result
154
155
Returns:
156
ndarray
157
Opened image
158
"""
159
160
def closing(image, footprint=None, out=None):
161
"""
162
Perform grayscale closing (dilation followed by erosion).
163
164
Parameters:
165
image : array_like
166
Input image
167
footprint : array_like, optional
168
Structuring element
169
out : ndarray, optional
170
Array for storing result
171
172
Returns:
173
ndarray
174
Closed image
175
"""
176
177
def white_tophat(image, footprint=None, out=None):
178
"""
179
Perform white top-hat transform (image - opening).
180
181
Parameters:
182
image : array_like
183
Input image
184
footprint : array_like, optional
185
Structuring element
186
out : ndarray, optional
187
Array for storing result
188
189
Returns:
190
ndarray
191
White top-hat transformed image
192
"""
193
194
def black_tophat(image, footprint=None, out=None):
195
"""
196
Perform black top-hat transform (closing - image).
197
198
Parameters:
199
image : array_like
200
Input image
201
footprint : array_like, optional
202
Structuring element
203
out : ndarray, optional
204
Array for storing result
205
206
Returns:
207
ndarray
208
Black top-hat transformed image
209
"""
210
```
211
212
### Structuring Elements
213
214
Create various shaped structuring elements for morphological operations.
215
216
```python { .api }
217
def disk(radius, dtype=np.uint8):
218
"""
219
Generate a disk-shaped structuring element.
220
221
Parameters:
222
radius : int
223
Radius of the disk
224
dtype : data-type, optional
225
Data type of structuring element
226
227
Returns:
228
ndarray
229
Disk-shaped structuring element
230
"""
231
232
def square(width, dtype=np.uint8):
233
"""
234
Generate a square structuring element.
235
236
Parameters:
237
width : int
238
Width and height of the square
239
dtype : data-type, optional
240
Data type of structuring element
241
242
Returns:
243
ndarray
244
Square structuring element
245
"""
246
247
def rectangle(width, height, dtype=np.uint8):
248
"""
249
Generate a rectangular structuring element.
250
251
Parameters:
252
width : int
253
Width of the rectangle
254
height : int
255
Height of the rectangle
256
dtype : data-type, optional
257
Data type of structuring element
258
259
Returns:
260
ndarray
261
Rectangular structuring element
262
"""
263
264
def diamond(radius, dtype=np.uint8):
265
"""
266
Generate a diamond-shaped structuring element.
267
268
Parameters:
269
radius : int
270
Radius of the diamond
271
dtype : data-type, optional
272
Data type of structuring element
273
274
Returns:
275
ndarray
276
Diamond-shaped structuring element
277
"""
278
279
def star(a, dtype=np.uint8):
280
"""
281
Generate a star-shaped structuring element.
282
283
Parameters:
284
a : int
285
Parameter for star shape
286
dtype : data-type, optional
287
Data type of structuring element
288
289
Returns:
290
ndarray
291
Star-shaped structuring element
292
"""
293
294
def ellipse(width, height, dtype=np.uint8):
295
"""
296
Generate an elliptical structuring element.
297
298
Parameters:
299
width : int
300
Width of the ellipse
301
height : int
302
Height of the ellipse
303
dtype : data-type, optional
304
Data type of structuring element
305
306
Returns:
307
ndarray
308
Elliptical structuring element
309
"""
310
311
def octagon(m, n, dtype=np.uint8):
312
"""
313
Generate an octagonal structuring element.
314
315
Parameters:
316
m : int
317
First parameter for octagon shape
318
n : int
319
Second parameter for octagon shape
320
dtype : data-type, optional
321
Data type of structuring element
322
323
Returns:
324
ndarray
325
Octagonal structuring element
326
"""
327
```
328
329
### 3D Structuring Elements
330
331
Create three-dimensional structuring elements for volumetric morphological operations.
332
333
```python { .api }
334
def ball(radius, dtype=np.uint8):
335
"""
336
Generate a 3D ball-shaped structuring element.
337
338
Parameters:
339
radius : int
340
Radius of the ball
341
dtype : data-type, optional
342
Data type of structuring element
343
344
Returns:
345
ndarray
346
3D ball-shaped structuring element
347
"""
348
349
def cube(width, dtype=np.uint8):
350
"""
351
Generate a 3D cube structuring element.
352
353
Parameters:
354
width : int
355
Width, height, and depth of the cube
356
dtype : data-type, optional
357
Data type of structuring element
358
359
Returns:
360
ndarray
361
3D cube structuring element
362
"""
363
364
def octahedron(radius, dtype=np.uint8):
365
"""
366
Generate a 3D octahedral structuring element.
367
368
Parameters:
369
radius : int
370
Radius of the octahedron
371
dtype : data-type, optional
372
Data type of structuring element
373
374
Returns:
375
ndarray
376
3D octahedral structuring element
377
"""
378
```
379
380
### Skeletonization and Thinning
381
382
Extract skeleton and perform morphological thinning operations for shape analysis.
383
384
```python { .api }
385
def skeletonize(image, method='lee'):
386
"""
387
Compute skeleton of a binary image.
388
389
Parameters:
390
image : array_like
391
Input binary image
392
method : str, optional
393
Algorithm to use ('lee' or 'zhang')
394
395
Returns:
396
ndarray
397
Skeleton of the input image
398
"""
399
400
def medial_axis(image, mask=None, return_distance=False):
401
"""
402
Compute medial axis transform of a binary image.
403
404
Parameters:
405
image : array_like
406
Input binary image
407
mask : array_like, optional
408
Mask to limit computation region
409
return_distance : bool, optional
410
Whether to return distance transform
411
412
Returns:
413
ndarray or tuple of ndarrays
414
Medial axis and optionally distance transform
415
"""
416
417
def thin(image, max_num_iter=None):
418
"""
419
Perform morphological thinning of a binary image.
420
421
Parameters:
422
image : array_like
423
Input binary image
424
max_num_iter : int, optional
425
Maximum number of iterations
426
427
Returns:
428
ndarray
429
Thinned binary image
430
"""
431
```
432
433
### Object Removal and Cleaning
434
435
Remove unwanted objects and clean binary images based on size and connectivity criteria.
436
437
```python { .api }
438
def remove_small_objects(ar, min_size=64, connectivity=1, in_place=False):
439
"""
440
Remove objects smaller than specified size.
441
442
Parameters:
443
ar : array_like
444
Input labeled or binary image
445
min_size : int, optional
446
Minimum size of objects to keep
447
connectivity : int, optional
448
Pixel connectivity (1, 2, or 3 for 2D; 1, 2, 3, or 26 for 3D)
449
in_place : bool, optional
450
Whether to modify input array
451
452
Returns:
453
ndarray
454
Cleaned image with small objects removed
455
"""
456
457
def remove_small_holes(ar, area_threshold=64, connectivity=1, in_place=False):
458
"""
459
Remove small holes in binary objects.
460
461
Parameters:
462
ar : array_like
463
Input binary image
464
area_threshold : int, optional
465
Maximum size of holes to fill
466
connectivity : int, optional
467
Pixel connectivity
468
in_place : bool, optional
469
Whether to modify input array
470
471
Returns:
472
ndarray
473
Binary image with small holes filled
474
"""
475
```
476
477
### Convex Hull Operations
478
479
Compute convex hull of binary objects for shape analysis and object completion.
480
481
```python { .api }
482
def convex_hull_image(image, offset_coordinates=True, tolerance=1e-10):
483
"""
484
Compute convex hull image of a binary image.
485
486
Parameters:
487
image : array_like
488
Input binary image
489
offset_coordinates : bool, optional
490
Whether to use offset coordinates
491
tolerance : float, optional
492
Tolerance for geometric calculations
493
494
Returns:
495
ndarray
496
Binary image with convex hull filled
497
"""
498
499
def convex_hull_object(image, neighbors=8):
500
"""
501
Compute convex hull of all objects in a binary image.
502
503
Parameters:
504
image : array_like
505
Input binary image
506
neighbors : int, optional
507
Connectivity for object identification
508
509
Returns:
510
ndarray
511
Binary image with convex hulls of all objects
512
"""
513
```
514
515
### Morphological Reconstruction
516
517
Perform morphological reconstruction operations for selective object enhancement and noise removal.
518
519
```python { .api }
520
def reconstruction(seed, mask, method='dilation', footprint=None, offset=None):
521
"""
522
Perform morphological reconstruction.
523
524
Parameters:
525
seed : array_like
526
Seed image for reconstruction
527
mask : array_like
528
Mask image that limits reconstruction
529
method : str, optional
530
Type of reconstruction ('dilation' or 'erosion')
531
footprint : array_like, optional
532
Structuring element
533
offset : array_like, optional
534
Offset for structuring element
535
536
Returns:
537
ndarray
538
Reconstructed image
539
"""
540
```
541
542
### Extrema Detection
543
544
Detect local maxima and minima using morphological operations.
545
546
```python { .api }
547
def local_maxima(image, min_distance=1, threshold_abs=None, threshold_rel=None, exclude_border=True, num_peaks=np.inf, footprint=None, labels=None, num_peaks_per_label=np.inf, p_norm=np.inf):
548
"""
549
Find local maxima in an image.
550
551
Parameters:
552
image : array_like
553
Input image
554
min_distance : int, optional
555
Minimum distance between peaks
556
threshold_abs : float, optional
557
Minimum absolute intensity
558
threshold_rel : float, optional
559
Minimum relative intensity
560
exclude_border : bool, optional
561
Whether to exclude border
562
num_peaks : int, optional
563
Maximum number of peaks
564
footprint : array_like, optional
565
Footprint for peak detection
566
labels : array_like, optional
567
Labeled regions
568
num_peaks_per_label : int, optional
569
Maximum peaks per label
570
p_norm : float, optional
571
P-norm for distance calculation
572
573
Returns:
574
ndarray
575
Binary image with local maxima
576
"""
577
578
def local_minima(image, min_distance=1, threshold_abs=None, threshold_rel=None, exclude_border=True, num_peaks=np.inf, footprint=None, labels=None, num_peaks_per_label=np.inf, p_norm=np.inf):
579
"""
580
Find local minima in an image.
581
582
Parameters:
583
image : array_like
584
Input image
585
min_distance : int, optional
586
Minimum distance between peaks
587
threshold_abs : float, optional
588
Maximum absolute intensity
589
threshold_rel : float, optional
590
Maximum relative intensity
591
exclude_border : bool, optional
592
Whether to exclude border
593
num_peaks : int, optional
594
Maximum number of peaks
595
footprint : array_like, optional
596
Footprint for peak detection
597
labels : array_like, optional
598
Labeled regions
599
num_peaks_per_label : int, optional
600
Maximum peaks per label
601
p_norm : float, optional
602
P-norm for distance calculation
603
604
Returns:
605
ndarray
606
Binary image with local minima
607
"""
608
609
def h_maxima(image, h, footprint=None):
610
"""
611
Determine h-maxima of an image.
612
613
Parameters:
614
image : array_like
615
Input image
616
h : float
617
Height threshold for maxima
618
footprint : array_like, optional
619
Structuring element
620
621
Returns:
622
ndarray
623
Binary image with h-maxima
624
"""
625
626
def h_minima(image, h, footprint=None):
627
"""
628
Determine h-minima of an image.
629
630
Parameters:
631
image : array_like
632
Input image
633
h : float
634
Height threshold for minima
635
footprint : array_like, optional
636
Structuring element
637
638
Returns:
639
ndarray
640
Binary image with h-minima
641
"""
642
```
643
644
## Usage Examples
645
646
### Basic Morphological Operations
647
648
```python
649
from skimage import data, morphology
650
import matplotlib.pyplot as plt
651
652
# Load binary image
653
image = data.horse()
654
655
# Create structuring element
656
footprint = morphology.disk(5)
657
658
# Apply basic operations
659
eroded = morphology.erosion(image, footprint)
660
dilated = morphology.dilation(image, footprint)
661
opened = morphology.opening(image, footprint)
662
closed = morphology.closing(image, footprint)
663
664
# Display results
665
fig, axes = plt.subplots(2, 3, figsize=(15, 10))
666
axes[0, 0].imshow(image, cmap='gray')
667
axes[0, 0].set_title('Original')
668
axes[0, 1].imshow(eroded, cmap='gray')
669
axes[0, 1].set_title('Erosion')
670
axes[0, 2].imshow(dilated, cmap='gray')
671
axes[0, 2].set_title('Dilation')
672
axes[1, 0].imshow(opened, cmap='gray')
673
axes[1, 0].set_title('Opening')
674
axes[1, 1].imshow(closed, cmap='gray')
675
axes[1, 1].set_title('Closing')
676
plt.show()
677
```
678
679
### Object Cleaning and Analysis
680
681
```python
682
from skimage import data, morphology, measure
683
import numpy as np
684
685
# Create noisy binary image
686
image = data.binary_blobs(length=256, blob_size_fraction=0.1)
687
688
# Add noise
689
noisy = image.copy()
690
noise = np.random.random(image.shape) < 0.05
691
noisy[noise] = ~noisy[noise]
692
693
# Clean image
694
cleaned = morphology.remove_small_objects(noisy, min_size=50)
695
filled = morphology.remove_small_holes(cleaned, area_threshold=20)
696
697
# Label and analyze objects
698
labeled = measure.label(filled)
699
props = measure.regionprops(labeled)
700
701
print(f"Original objects: {len(np.unique(measure.label(image))) - 1}")
702
print(f"Noisy objects: {len(np.unique(measure.label(noisy))) - 1}")
703
print(f"Cleaned objects: {len(props)}")
704
```
705
706
### Skeletonization and Shape Analysis
707
708
```python
709
from skimage import data, morphology
710
import matplotlib.pyplot as plt
711
712
# Load and skeletonize
713
image = data.horse()
714
skeleton = morphology.skeletonize(image)
715
medial_axis, distance = morphology.medial_axis(image, return_distance=True)
716
717
# Compare methods
718
fig, axes = plt.subplots(1, 3, figsize=(15, 5))
719
axes[0].imshow(image, cmap='gray')
720
axes[0].set_title('Original')
721
axes[1].imshow(skeleton, cmap='gray')
722
axes[1].set_title('Skeleton')
723
axes[2].imshow(distance * medial_axis, cmap='hot')
724
axes[2].set_title('Medial Axis with Distance')
725
plt.show()
726
```
727
728
## Types
729
730
```python { .api }
731
from typing import Optional, Union, Tuple
732
from numpy.typing import NDArray
733
import numpy as np
734
735
# Morphological structures
736
Footprint = Optional[NDArray[np.bool_]]
737
StructuringElement = NDArray[np.bool_]
738
739
# Morphological parameters
740
BorderValue = int
741
Connectivity = int
742
MorphMethod = str
743
744
# Results
745
BinaryImage = NDArray[np.bool_]
746
GrayscaleImage = NDArray[np.number]
747
SkeletonResult = Union[NDArray[np.bool_], Tuple[NDArray[np.bool_], NDArray[np.floating]]]
748
```