Skip to content

Commit 4327055

Browse files
committed
video.normalize: add dtype argument, support complex numbers
1 parent a890f32 commit 4327055

File tree

3 files changed

+42
-36
lines changed

3 files changed

+42
-36
lines changed

docs/tutorials/io.ipynb

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -282,20 +282,12 @@
282282
},
283283
"outputs": [],
284284
"source": [
285-
"om.save_video('video.npy', video)"
286-
]
287-
},
288-
{
289-
"cell_type": "code",
290-
"execution_count": null,
291-
"metadata": {
292-
"tags": [
293-
"skip-execution"
294-
]
295-
},
296-
"outputs": [],
297-
"source": [
298-
"om.save_video('video.mat', video)"
285+
"# NumPy NPY format\n",
286+
"om.save_video('video.npy', video)\n",
287+
"# MATLAB\n",
288+
"om.save_video('video.mat', video)\n",
289+
"# TIFF image stack\n",
290+
"om.save_video('video.tif', video)"
299291
]
300292
},
301293
{
@@ -350,13 +342,8 @@
350342
},
351343
"outputs": [],
352344
"source": [
353-
"import numpy as np\n",
354-
"\n",
355-
"om.print_properties(video)\n",
356-
"video = video.astype(np.float32)\n",
357-
"video = (video-np.min(video))/np.max(video)*255 # alternatively *65536 for 16-bit\n",
358-
"om.print_properties(video)\n",
359-
"video = video.astype(np.uint8) # alternatively np.uint16 for 16-bit\n",
345+
"# Convert to uint8 with range [0-255]\n",
346+
"video = om.video.normalize(video, ymin=0, ymax=255, dtype=\"uint8\")\n",
360347
"om.print_properties(video)"
361348
]
362349
},
@@ -431,7 +418,7 @@
431418
"outputs": [],
432419
"source": [
433420
"video_waves = om.video.normalize_pixelwise(video)\n",
434-
"om.export_video_with_overlay(\"video.mp4\", video, video_waves)"
421+
"om.video.export_video_with_overlay(\"video.mp4\", video, video_waves)"
435422
]
436423
},
437424
{

optimap/video/_filters.py

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@
77
from ..utils import _print
88

99

10-
def normalize(video: np.ndarray, ymin=0, ymax=1, vmin=None, vmax=None, clip=True):
11-
"""Normalizes video to interval [``ymin``, ``ymax``]. If ``vmin`` or ``vmax`` are specified,
12-
the normalization is done using these values and the resulting video will be clipped.
10+
def normalize(array: np.ndarray, ymin=0, ymax=1, vmin=None, vmax=None, clip=True, dtype=np.float32):
11+
"""Normalizes array (video, image, ...) to interval [``ymin``, ``ymax``].
12+
13+
If ``vmin`` or ``vmax`` are specified, the normalization is done using these values and the resulting array will be clipped.
1314
1415
Parameters
1516
----------
16-
video : {t, x, y} ndarray
17-
The input video to be normalized.
17+
array : ndarray
18+
The input array to be normalized.
1819
ymin : float, optional
1920
Minimum value of the resulting video, by default 0
2021
ymax : float, optional
@@ -28,26 +29,37 @@ def normalize(video: np.ndarray, ymin=0, ymax=1, vmin=None, vmax=None, clip=True
2829
clip : bool, optional
2930
If True, the resulting video will be clipped to [``ymin``, ``ymax``], by default True
3031
Only applies if ``vmin`` or ``vmax`` are specified.
32+
dtype : type, optional
33+
Data type of the resulting array, by default np.float32
3134
3235
Returns
3336
-------
34-
{t, x, y} ndarray
35-
Normalized video.
37+
ndarray
38+
Normalized array/video/image.
3639
"""
3740
_print(f"normalizing video to interval [{ymin}, {ymax}] ...")
38-
video = video.astype("float32")
41+
dtype = np.dtype(dtype)
3942
do_clip = clip and (vmin is not None or vmax is not None)
43+
44+
if not (np.issubdtype(array.dtype, np.floating)
45+
or np.issubdtype(array.dtype, np.complexfloating)):
46+
array = array.astype(np.float32)
47+
4048
if vmin is None:
41-
vmin = np.nanmin(video)
49+
vmin = np.nanmin(array)
4250
if vmax is None:
43-
vmax = np.nanmax(video)
51+
vmax = np.nanmax(array)
4452

45-
eps = np.finfo(np.float32).eps
46-
video = (video - vmin) / (vmax - vmin + eps) * (ymax - ymin) + ymin
53+
eps = np.finfo(array.dtype).eps
54+
array = (array - vmin) / (vmax - vmin + eps) * (ymax - ymin) + ymin
4755

4856
if do_clip:
49-
video = np.clip(video, ymin, ymax)
50-
return video
57+
array = np.clip(array, ymin, ymax)
58+
59+
if dtype == array.dtype:
60+
return array
61+
else:
62+
return array.astype(dtype)
5163

5264

5365
def normalize_pixelwise(video: np.ndarray, ymin=0, ymax=1):

tests/test_video.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,13 @@ def test_normalize():
1212
assert np.all(out >= -0.5)
1313
assert np.all(out <= 0.5)
1414

15+
vid = vid.astype(np.float64)
16+
out = om.video.normalize(vid, dtype="float64")
17+
assert out.dtype == np.float64
18+
19+
out = om.video.normalize(vid, ymax=255, dtype="uint8")
20+
assert out.dtype == np.uint8
21+
1522
def test_normalize_pixelwise():
1623
vid = (np.random.random((10, 128, 128)) * 8000).astype(np.uint16)
1724
out = om.video.normalize_pixelwise(vid, -0.5, 0.5)

0 commit comments

Comments
 (0)