Skip to content

Commit

Permalink
Merge branch 'topic/default/fluidpivviewer' into 'branch/default'
Browse files Browse the repository at this point in the history
New files for fluidpivviewer

Closes #32

See merge request fluiddyn/fluidimage!85
  • Loading branch information
paugier committed Mar 27, 2024
2 parents 53f3a1c + 12ef0e1 commit c18023d
Show file tree
Hide file tree
Showing 25 changed files with 407 additions and 72 deletions.
11 changes: 10 additions & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
# Release notes

See also the
[unreleased changes](https://foss.heptapod.net/fluiddyn/fluidimage/-/compare/0.4.2...branch%2Fdefault).
[unreleased changes](https://foss.heptapod.net/fluiddyn/fluidimage/-/compare/0.4.3...branch%2Fdefault).

## [0.4.3] (2024-03-27)

- [!85](https://foss.heptapod.net/fluiddyn/fluidimage/-/merge_requests/85): `fluidpivviewer`.
- [!84](https://foss.heptapod.net/fluiddyn/fluidimage/-/merge_requests/84): `multi_exec_async`
using {class}`fluidimage.topologies.splitters.Splitter`.
- Other bugfixes and improvements (name PIV files and
{class}`fluidimage.postproc.vector_field.VectorFieldOnGrid`).

## [0.4.2] (2024-03-20)

Expand Down Expand Up @@ -168,3 +176,4 @@ This version contains incompatible API changes documented here.
[0.4.0]: https://foss.heptapod.net/fluiddyn/fluidimage/-/compare/0.3.0...0.4.0
[0.4.1]: https://foss.heptapod.net/fluiddyn/fluidimage/-/compare/0.4.0...0.4.1
[0.4.2]: https://foss.heptapod.net/fluiddyn/fluidimage/-/compare/0.4.1...0.4.2
[0.4.3]: https://foss.heptapod.net/fluiddyn/fluidimage/-/compare/0.4.2...0.4.3
13 changes: 4 additions & 9 deletions doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,13 @@

import os

os.environ["OMP_NUM_THREADS"] = "1"

import fluidimage

# we want this module to be importable.
try:
import fluidimage.topologies.optical_flow
except Exception:
import traceback

traceback.print_exc()
# we want these modules to be importable.
import fluidimage.topologies.preproc
import fluidimage.topologies.optical_flow

os.environ["OMP_NUM_THREADS"] = "1"
# -- General configuration ----------------------------------------------------

# If your documentation needs a minimal Sphinx version, state it here.
Expand Down
12 changes: 9 additions & 3 deletions doc/examples/piv_parallel.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,17 @@

params.series.path = get_path_image_samples() / "Karman/Images"

params.mask.strcrop = "50:350, 0:380"

params.piv0.shape_crop_im0 = 32
params.multipass.number = 2
params.multipass.use_tps = False
params.piv0.displacement_max = 5
params.piv0.nb_peaks_to_search = 2

params.mask.strcrop = ":, 50:500"
params.fix.correl_min = 0.4
params.fix.threshold_diff_neighbour = 2.0

params.multipass.number = 2
params.multipass.use_tps = "last"

# params.saving.how = 'complete'
params.saving.postfix = "piv_example"
Expand Down
14 changes: 6 additions & 8 deletions doc/examples/piv_try_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,18 @@

params = Work.create_default_params()

params.multipass.number = 2
params.multipass.use_tps = True
params.series.path = "../../image_samples/Oseen/Images"

params.mask.strcrop = "30:250, 100:"

params.piv0.shape_crop_im0 = 32
params.piv0.displacement_max = 5

params.fix.correl_min = 0.2
params.fix.threshold_diff_neighbour = 8

params.mask.strcrop = "30:250, 100:"

path = "../../image_samples/Oseen/Images"
# path = '../../image_samples/Karman/Images'
params.series.path = path
params.series.str_subset = "i+1:i+3"
params.multipass.number = 2
params.multipass.use_tps = True

work = Work(params=params)

Expand Down
28 changes: 28 additions & 0 deletions doc/examples/piv_try_params_Karman.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"""To be run in IPython to find a good set of parameters"""

from fluidimage.piv import Work

params = Work.create_default_params()

params.series.path = "../../image_samples/Karman/Images"

params.mask.strcrop = "50:350, 0:380"

params.fix.correl_min = 0.4
params.fix.threshold_diff_neighbour = 2.0

params.piv0.shape_crop_im0 = 32
params.piv0.displacement_max = 5
params.piv0.nb_peaks_to_search = 2

params.multipass.number = 2
params.multipass.use_tps = "last"

work = Work(params=params)

piv = work.process_1_serie()

# piv.display(show_interp=True, scale=0.3, show_error=False)
piv.display(show_interp=False, scale=1, show_error=True)

# piv.save()
33 changes: 28 additions & 5 deletions doc/tutorials/tuto_piv.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,17 @@ the input images:
path_src = get_path_image_samples() / "Karman/Images"
params.series.path = str(path_src)
params.piv0.shape_crop_im0 = 64
params.mask.strcrop = "50:350, 0:400"
params.piv0.shape_crop_im0 = 48
params.piv0.displacement_max = 5
params.piv0.nb_peaks_to_search = 2
params.fix.correl_min = 0.4
params.fix.threshold_diff_neighbour = 2.0
params.multipass.number = 2
params.multipass.use_tps = False
params.multipass.use_tps = "last"
```

After instantiating the `Work` class,
Expand Down Expand Up @@ -204,15 +212,23 @@ params.saving._print_doc()
path_src = get_path_image_samples() / "Karman/Images"
params.series.path = str(path_src)
params.piv0.shape_crop_im0 = 64
params.mask.strcrop = "50:350, 0:400"
params.piv0.shape_crop_im0 = 48
params.piv0.displacement_max = 5
params.piv0.nb_peaks_to_search = 2
params.fix.correl_min = 0.4
params.fix.threshold_diff_neighbour = 2.0
params.multipass.number = 2
params.multipass.use_tps = False
params.multipass.use_tps = "last"
params.saving.how = 'recompute'
params.saving.postfix = "doc_piv_ipynb"
```

In order to run the PIV computation, we have to instanciate an object of the class
In order to run the PIV computation, we have to instantiate an object of the class
{class}`fluidimage.piv.Topology`.

```{code-cell} ipython3
Expand Down Expand Up @@ -243,6 +259,13 @@ path_src
topology.path_dir_result
```

```{code-cell} ipython3
sorted(path.name for path in topology.path_dir_result.glob("*"))
```

Fluidimage provides the command `fluidpivviewer`, which starts a very simple GUI to
visualize the PIV results.

## Analyzing the computation

```{code-cell} ipython3
Expand Down
1 change: 1 addition & 0 deletions image_samples/Milestone/piv_0001a-b.h5
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ build-backend = 'mesonpy'

[project]
name = "fluidimage"
version = "0.4.2"
version = "0.4.3"
description = "Fluid image processing with Python."
authors = [
{name = "Pierre Augier", email = "[email protected]"},
Expand Down Expand Up @@ -55,6 +55,7 @@ Homepage = "https://foss.heptapod.net/fluiddyn/fluidimage"
fluidimviewer-pg = "fluidimage.gui.pg_main:main"
fluidimviewer = "fluidimage.gui.imviewer:main"
fluidimlauncher = "fluidimage.gui.launcher.main:main"
fluidpivviewer = "fluidimage.gui.piv_viewer:main"

[project.optional-dependencies]
pims = ["pims"]
Expand Down
4 changes: 4 additions & 0 deletions src/fluidimage/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ def get_path_image_samples():
if path_image_samples.exists():
return path_image_samples.resolve()

path_image_samples = Path.home() / "dev/fluidimage/image_samples"
if path_image_samples.exists():
return path_image_samples

# Gitlab and Github CI
for name_env_var_project_dir in ("CI_PROJECT_DIR", "GITHUB_WORKSPACE"):
ci_project_dir = os.getenv(name_env_var_project_dir)
Expand Down
2 changes: 2 additions & 0 deletions src/fluidimage/gui/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
.. autosummary::
:toctree:
base_matplotlib
imviewer
launcher
pg_main
piv_viewer
"""
32 changes: 32 additions & 0 deletions src/fluidimage/gui/base_matplotlib.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"""Base class using matplotlib widgets
"""

from matplotlib.widgets import Button, TextBox


class AppMatplotlibWidgets:

_buttons: dict
_textboxes: dict

def __init__(self):
self._buttons = {}
self._textboxes = {}

def _create_button(self, fig, rect, text, func):
ax = fig.add_axes(rect)
button = Button(ax, text)
button.on_clicked(func)
self._buttons[text] = button
return button

def _create_text_box(self, fig, rect, name, func, initial):
ax = fig.add_axes(rect)
textbox = TextBox(ax, name, initial=initial)
textbox.on_submit(func)
self._textboxes[name] = textbox
return textbox

def get_textbox(self, key):
return self._textboxes[key]
31 changes: 7 additions & 24 deletions src/fluidimage/gui/imviewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
from glob import glob

import matplotlib.pyplot as plt
from matplotlib.widgets import Button, TextBox

from fluiddyn.io.image import imread
from fluiddyn.util import time_as_str
from fluiddyn.util.serieofarrays import SerieOfArraysFromFiles
from fluidimage.gui.base_matplotlib import AppMatplotlibWidgets
from fluidimage.util import safe_eval

extensions = ["png", "tif", "tiff", "jpg", "jpeg", "bmp", "cine"]
Expand Down Expand Up @@ -66,7 +66,7 @@ def parse_args():
return parser.parse_args()


class ImageViewer:
class ImageViewer(AppMatplotlibWidgets):
"""Simple Image viewer."""

def __init__(self, args):
Expand Down Expand Up @@ -98,8 +98,7 @@ def __init__(self, args):
self.nb_images = len(self.path_files)
print(f"Will use {self.nb_images} images in the dir {path_dir}")

self._buttons = {}
self._textboxes = {}
super().__init__()

fig = self.fig = plt.figure()
fig.canvas.manager.set_window_title(
Expand Down Expand Up @@ -133,30 +132,28 @@ def __init__(self, args):
function_buttons[3] = self._increase_ifile_n

y = size_button / 3.0
for i, x in enumerate(x_buttons):
name = name_buttons[i]
func = function_buttons[i]
for x, name, func in zip(x_buttons, name_buttons, function_buttons):
self._create_button(fig, [x, y, size_button, size_button], name, func)

self._n = 1

self._create_text(
self._create_text_box(
fig,
[0.1, y, 2 * size_button, size_button],
"n = ",
self._submit_n,
"1",
)

self._create_text(
self._create_text_box(
fig,
[0.87, 0.92, 1.5 * size_button, size_button],
"cmax = ",
self._change_cmax,
"{:.2f}".format(self.clim[1]),
)

self._create_text(
self._create_text_box(
fig,
[0.87, 0.1, 1.5 * size_button, size_button],
"cmin = ",
Expand Down Expand Up @@ -235,20 +232,6 @@ def change_im(self):
print("\rchanged to file " + name_file + " " * 20)
self._image_changing = False

def _create_button(self, fig, rect, text, func):
ax = fig.add_axes(rect)
button = Button(ax, text)
button.on_clicked(func)
self._buttons[text] = button
return button

def _create_text(self, fig, rect, name, func, initial):
ax = fig.add_axes(rect)
textbox = TextBox(ax, name, initial=initial)
textbox.on_submit(func)
self._textboxes[name] = textbox
return textbox

def _switch(self):
if self._last_was_increase:
self._decrease_ifile_n()
Expand Down
3 changes: 3 additions & 0 deletions src/fluidimage/gui/meson.build
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@

python_sources = [
'__init__.py',
'base_matplotlib.py',
'imviewer.py',
'pg_main.py',
'pg_wrapper.py',
'piv_viewer.py',
'test_imviewer.py',
'test_imviewer_pg.py',
'test_piv_viewer.py',
]

py.install_sources(
Expand Down
Loading

0 comments on commit c18023d

Please sign in to comment.