zea 0.0.6__py3-none-any.whl → 0.0.7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- zea/__init__.py +54 -19
- zea/agent/__init__.py +12 -12
- zea/agent/masks.py +2 -1
- zea/backend/tensorflow/dataloader.py +2 -1
- zea/beamform/beamformer.py +100 -50
- zea/beamform/lens_correction.py +9 -2
- zea/beamform/pfield.py +9 -2
- zea/config.py +34 -25
- zea/data/__init__.py +22 -16
- zea/data/convert/camus.py +2 -1
- zea/data/convert/echonet.py +4 -4
- zea/data/convert/echonetlvh/convert_raw_to_usbmd.py +1 -1
- zea/data/convert/matlab.py +11 -4
- zea/data/data_format.py +31 -30
- zea/data/datasets.py +7 -5
- zea/data/file.py +104 -2
- zea/data/layers.py +3 -3
- zea/datapaths.py +16 -4
- zea/display.py +7 -5
- zea/interface.py +14 -16
- zea/internal/_generate_keras_ops.py +6 -7
- zea/internal/cache.py +2 -49
- zea/internal/config/validation.py +1 -2
- zea/internal/core.py +69 -6
- zea/internal/device.py +6 -2
- zea/internal/dummy_scan.py +330 -0
- zea/internal/operators.py +114 -2
- zea/internal/parameters.py +101 -70
- zea/internal/setup_zea.py +5 -6
- zea/internal/utils.py +282 -0
- zea/io_lib.py +247 -19
- zea/keras_ops.py +74 -4
- zea/log.py +9 -7
- zea/metrics.py +15 -7
- zea/models/__init__.py +30 -20
- zea/models/base.py +30 -14
- zea/models/carotid_segmenter.py +19 -4
- zea/models/diffusion.py +173 -12
- zea/models/echonet.py +22 -8
- zea/models/echonetlvh.py +31 -7
- zea/models/lpips.py +19 -2
- zea/models/lv_segmentation.py +28 -11
- zea/models/preset_utils.py +5 -5
- zea/models/regional_quality.py +30 -10
- zea/models/taesd.py +21 -5
- zea/models/unet.py +15 -1
- zea/ops.py +390 -196
- zea/probes.py +6 -6
- zea/scan.py +109 -49
- zea/simulator.py +24 -21
- zea/tensor_ops.py +406 -302
- zea/tools/hf.py +1 -1
- zea/tools/selection_tool.py +47 -86
- zea/utils.py +92 -480
- zea/visualize.py +177 -39
- {zea-0.0.6.dist-info → zea-0.0.7.dist-info}/METADATA +4 -2
- zea-0.0.7.dist-info/RECORD +114 -0
- zea-0.0.6.dist-info/RECORD +0 -112
- {zea-0.0.6.dist-info → zea-0.0.7.dist-info}/WHEEL +0 -0
- {zea-0.0.6.dist-info → zea-0.0.7.dist-info}/entry_points.txt +0 -0
- {zea-0.0.6.dist-info → zea-0.0.7.dist-info}/licenses/LICENSE +0 -0
zea/tools/hf.py
CHANGED
|
@@ -41,7 +41,7 @@ def load_model_from_hf(repo_id, revision="main", verbose=True):
|
|
|
41
41
|
if verbose:
|
|
42
42
|
log.info(
|
|
43
43
|
log.yellow(
|
|
44
|
-
f"
|
|
44
|
+
f"Successfully loaded model {commit_message} from "
|
|
45
45
|
f"'https://huggingface.co/{repo_id}'. Last updated on {commit_time}."
|
|
46
46
|
)
|
|
47
47
|
)
|
zea/tools/selection_tool.py
CHANGED
|
@@ -17,19 +17,20 @@ Key Features
|
|
|
17
17
|
|
|
18
18
|
Example
|
|
19
19
|
-------
|
|
20
|
-
.. code-block:: python
|
|
21
20
|
|
|
22
|
-
|
|
23
|
-
from zea.tools.selection_tool import interactive_selector
|
|
21
|
+
.. doctest::
|
|
24
22
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
23
|
+
>>> import matplotlib.pyplot as plt
|
|
24
|
+
>>> import numpy as np
|
|
25
|
+
>>> from zea.tools.selection_tool import interactive_selector
|
|
26
|
+
|
|
27
|
+
>>> image = np.zeros((100, 100)) # Load your 2D image array
|
|
28
|
+
>>> fig, ax = plt.subplots()
|
|
29
|
+
>>> _ = ax.imshow(image, cmap="gray")
|
|
30
|
+
>>> patches, masks = interactive_selector(image, ax, selector="rectangle") # doctest: +SKIP
|
|
29
31
|
|
|
30
32
|
"""
|
|
31
33
|
|
|
32
|
-
import tkinter as tk
|
|
33
34
|
from collections.abc import Iterable
|
|
34
35
|
from pathlib import Path
|
|
35
36
|
from typing import Union
|
|
@@ -43,7 +44,6 @@ from matplotlib.path import Path as pltPath
|
|
|
43
44
|
from matplotlib.widgets import LassoSelector, RectangleSelector
|
|
44
45
|
from PIL import Image, ImageDraw
|
|
45
46
|
from scipy.interpolate import interp1d
|
|
46
|
-
from skimage import measure
|
|
47
47
|
from skimage.measure import approximate_polygon, find_contours
|
|
48
48
|
from sklearn.metrics import pairwise_distances
|
|
49
49
|
|
|
@@ -55,7 +55,8 @@ from zea.internal.viewer import (
|
|
|
55
55
|
)
|
|
56
56
|
from zea.io_lib import _SUPPORTED_VID_TYPES, load_image, load_video
|
|
57
57
|
from zea.metrics import get_metric
|
|
58
|
-
from zea.
|
|
58
|
+
from zea.tensor_ops import translate
|
|
59
|
+
from zea.visualize import plot_rectangle_from_mask, plot_shape_from_mask
|
|
59
60
|
|
|
60
61
|
|
|
61
62
|
def crop_array(array, value=None):
|
|
@@ -180,16 +181,30 @@ def interactive_selector(
|
|
|
180
181
|
for mask in masks:
|
|
181
182
|
patches.append(crop_array(data * mask, value=0))
|
|
182
183
|
|
|
183
|
-
|
|
184
|
+
# Early return if no confirmation is required
|
|
185
|
+
if not confirm_selection:
|
|
186
|
+
return patches, masks
|
|
187
|
+
|
|
188
|
+
try:
|
|
189
|
+
from tkinter import Tk, messagebox
|
|
190
|
+
except ImportError as e:
|
|
191
|
+
raise ImportError(
|
|
192
|
+
log.error("Failed to import tkinter. Please install it with 'apt install python3-tk'.")
|
|
193
|
+
) from e
|
|
194
|
+
|
|
195
|
+
# Create root window once for messagebox dialogs
|
|
196
|
+
root = Tk()
|
|
197
|
+
root.withdraw()
|
|
184
198
|
|
|
199
|
+
like_selection = False
|
|
185
200
|
while not like_selection:
|
|
186
201
|
print(f"You have made {len(patches)} selection(s).")
|
|
187
202
|
# draw masks on top of data
|
|
188
|
-
for
|
|
189
|
-
|
|
203
|
+
for current_mask in masks:
|
|
204
|
+
plot_shape_from_mask(ax, current_mask, alpha=0.5)
|
|
190
205
|
plt.draw()
|
|
191
|
-
|
|
192
|
-
like_selection =
|
|
206
|
+
|
|
207
|
+
like_selection = messagebox.askyesno("Like Selection", "Do you like your selection?")
|
|
193
208
|
|
|
194
209
|
if not like_selection:
|
|
195
210
|
remove_masks_from_axs(ax)
|
|
@@ -199,68 +214,12 @@ def interactive_selector(
|
|
|
199
214
|
_execute_selector()
|
|
200
215
|
|
|
201
216
|
patches = []
|
|
202
|
-
for
|
|
203
|
-
patches.append(crop_array(data *
|
|
204
|
-
|
|
205
|
-
return patches, masks
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
def add_rectangle_from_mask(ax, mask, **kwargs):
|
|
209
|
-
"""add a rectangle box to axis from mask array.
|
|
210
|
-
|
|
211
|
-
Args:
|
|
212
|
-
ax (plt.ax): matplotlib axis
|
|
213
|
-
mask (ndarray): numpy array with rectangle non-zero
|
|
214
|
-
box defining the region of interest.
|
|
215
|
-
Kwargs:
|
|
216
|
-
edgecolor (str): color of the shape's edge
|
|
217
|
-
facecolor (str): color of the shape's face
|
|
218
|
-
linewidth (int): width of the shape's edge
|
|
217
|
+
for current_mask in masks:
|
|
218
|
+
patches.append(crop_array(data * current_mask, value=0))
|
|
219
219
|
|
|
220
|
-
|
|
221
|
-
plt.ax: matplotlib axis with rectangle added
|
|
222
|
-
"""
|
|
223
|
-
# Create a Rectangle patch
|
|
224
|
-
y1, y2 = np.where(np.diff(mask, axis=0).sum(axis=1))[0]
|
|
225
|
-
x1, x2 = np.where(np.diff(mask, axis=1).sum(axis=0))[0]
|
|
226
|
-
rect = Rectangle(
|
|
227
|
-
(x1, y1),
|
|
228
|
-
(x2 - x1),
|
|
229
|
-
(y2 - y1),
|
|
230
|
-
**kwargs,
|
|
231
|
-
)
|
|
232
|
-
|
|
233
|
-
# Add the patch to the Axes
|
|
234
|
-
rect_obj = ax.add_patch(rect)
|
|
235
|
-
return rect_obj
|
|
220
|
+
root.destroy()
|
|
236
221
|
|
|
237
|
-
|
|
238
|
-
def add_shape_from_mask(ax, mask, **kwargs):
|
|
239
|
-
"""add a shape to axis from mask array.
|
|
240
|
-
|
|
241
|
-
Args:
|
|
242
|
-
ax (plt.ax): matplotlib axis
|
|
243
|
-
mask (ndarray): numpy array with non-zero
|
|
244
|
-
shape defining the region of interest.
|
|
245
|
-
Kwargs:
|
|
246
|
-
edgecolor (str): color of the shape's edge
|
|
247
|
-
facecolor (str): color of the shape's face
|
|
248
|
-
linewidth (int): width of the shape's edge
|
|
249
|
-
|
|
250
|
-
Returns:
|
|
251
|
-
plt.ax: matplotlib axis with shape added
|
|
252
|
-
"""
|
|
253
|
-
# Pad mask to ensure edge contours are found
|
|
254
|
-
padded_mask = np.pad(mask, pad_width=1, mode="constant", constant_values=0)
|
|
255
|
-
contours = measure.find_contours(padded_mask, 0.5)
|
|
256
|
-
patches = []
|
|
257
|
-
for contour in contours:
|
|
258
|
-
# Remove padding offset
|
|
259
|
-
contour -= 1
|
|
260
|
-
path = pltPath(contour[:, ::-1])
|
|
261
|
-
patch = PathPatch(path, **kwargs)
|
|
262
|
-
patches.append(ax.add_patch(patch))
|
|
263
|
-
return patches
|
|
222
|
+
return patches, masks
|
|
264
223
|
|
|
265
224
|
|
|
266
225
|
def interactive_selector_with_plot_and_metric(
|
|
@@ -334,9 +293,9 @@ def interactive_selector_with_plot_and_metric(
|
|
|
334
293
|
_ax.set_title(title + "\n" + f"{metric}: {score:.3f}")
|
|
335
294
|
for mask in masks:
|
|
336
295
|
if selector == "rectangle":
|
|
337
|
-
|
|
296
|
+
plot_rectangle_from_mask(_ax, mask, alpha=0.5)
|
|
338
297
|
else:
|
|
339
|
-
|
|
298
|
+
plot_shape_from_mask(_ax, mask, alpha=0.5)
|
|
340
299
|
plt.tight_layout()
|
|
341
300
|
|
|
342
301
|
# plot patches and masks
|
|
@@ -350,7 +309,7 @@ def interactive_selector_with_plot_and_metric(
|
|
|
350
309
|
ax_new[2].imshow(mask, aspect="auto")
|
|
351
310
|
|
|
352
311
|
if selector == "rectangle":
|
|
353
|
-
|
|
312
|
+
plot_rectangle_from_mask(ax_base, mask)
|
|
354
313
|
|
|
355
314
|
for _ax in ax_new:
|
|
356
315
|
_ax.axis("off")
|
|
@@ -723,9 +682,9 @@ def update_imshow_with_mask(
|
|
|
723
682
|
imshow_obj.set_array(images[frame_no])
|
|
724
683
|
remove_masks_from_axs(axs)
|
|
725
684
|
if selector == "rectangle":
|
|
726
|
-
mask_obj =
|
|
685
|
+
mask_obj = plot_rectangle_from_mask(axs, masks[frame_no])
|
|
727
686
|
else:
|
|
728
|
-
mask_obj =
|
|
687
|
+
mask_obj = plot_shape_from_mask(axs, masks[frame_no], alpha=0.5)
|
|
729
688
|
return imshow_obj, mask_obj
|
|
730
689
|
|
|
731
690
|
|
|
@@ -821,9 +780,9 @@ def main():
|
|
|
821
780
|
pos, size = get_matplotlib_figure_props(fig)
|
|
822
781
|
|
|
823
782
|
if selector == "rectangle":
|
|
824
|
-
|
|
783
|
+
plot_rectangle_from_mask(axs, mask[0], alpha=0.5)
|
|
825
784
|
else:
|
|
826
|
-
|
|
785
|
+
plot_shape_from_mask(axs, mask[0], alpha=0.5)
|
|
827
786
|
plt.close()
|
|
828
787
|
selection_masks.append(mask[0])
|
|
829
788
|
|
|
@@ -840,13 +799,15 @@ def main():
|
|
|
840
799
|
imshow_obj = axs.imshow(images[0], cmap="gray")
|
|
841
800
|
|
|
842
801
|
if selector == "rectangle":
|
|
843
|
-
|
|
802
|
+
plot_rectangle_from_mask(axs, interpolated_masks[0])
|
|
844
803
|
else:
|
|
845
|
-
|
|
804
|
+
plot_shape_from_mask(axs, interpolated_masks[0], alpha=0.5)
|
|
846
805
|
|
|
847
806
|
filestem = Path(file.parent / f"{file.stem}_{title}_annotations.gif")
|
|
848
807
|
np.save(filestem.with_suffix(".npy"), interpolated_masks)
|
|
849
|
-
print(
|
|
808
|
+
print(
|
|
809
|
+
f"Successfully saved interpolated masks to {log.yellow(filestem.with_suffix('.npy'))}"
|
|
810
|
+
)
|
|
850
811
|
|
|
851
812
|
fps = ask_save_animation_with_fps()
|
|
852
813
|
|
|
@@ -859,7 +820,7 @@ def main():
|
|
|
859
820
|
)
|
|
860
821
|
filename = filestem.with_suffix(".gif")
|
|
861
822
|
ani.save(filename, writer="pillow")
|
|
862
|
-
print(f"
|
|
823
|
+
print(f"Successfully saved animation as {log.yellow(filename)}")
|
|
863
824
|
|
|
864
825
|
|
|
865
826
|
if __name__ == "__main__":
|