Note
Aller à la fin pour télécharger le code complet de l’exemple.
Systèmes de coordonnées uniformes et non uniformes#
Cet exemple démontre l’utilisation de systèmes de coordonnées uniformes et non uniformes avec des images dans Sigima. Il montre comment créer, visualiser et travailler avec les deux types de systèmes de coordonnées, en mettant en évidence leurs différences et leurs cas d’utilisation appropriés.
L’exemple montre :
Création d’images avec des systèmes de coordonnées uniformes
Création d’images avec des systèmes de coordonnées non uniformes
Visualisation des grilles de coordonnées
Comparaison de l’espacement des pixels et du mappage des coordonnées
Travail avec des unités et des coordonnées du monde réel
Quand et comment utiliser chaque type de système de coordonnées
Ce tutoriel utilise PlotPy pour la visualisation, fournissant des graphiques interactifs qui vous permettent d’explorer en détail les effets du système de coordonnées.
Importation des modules nécessaires#
Nous commencerons par importer tous les modules nécessaires au traitement d’images et à la visualisation.
import numpy as np
from sigima.objects import create_image
from sigima.viz import view_images_side_by_side
Création d’images de test avec des coordonnées uniformes#
Les coordonnées uniformes ont un espacement constant entre les pixels dans les deux directions. C’est le cas le plus courant pour les systèmes d’imagerie réguliers.
# Create a simple test pattern - a sine wave pattern
size = 100
x_uniform = np.linspace(0, 4 * np.pi, size)
y_uniform = np.linspace(0, 4 * np.pi, size)
X_uniform, Y_uniform = np.meshgrid(x_uniform, y_uniform)
# Create a 2D sine wave pattern
data_uniform = np.sin(X_uniform) * np.cos(Y_uniform)
# Create the image object with uniform coordinates
uniform_image = create_image(
title="Uniform Coordinates",
data=data_uniform,
units=("μm", "μm", "intensity"),
labels=("X position", "Y position", "Signal"),
)
# Set uniform coordinate system with specific spacing and origin
dx = 0.1 # 0.1 μm per pixel in X
dy = 0.1 # 0.1 μm per pixel in Y
x0 = -2.0 # X origin at -2.0 μm
y0 = -2.0 # Y origin at -2.0 μm
uniform_image.set_uniform_coords(dx, dy, x0=x0, y0=y0)
print("✓ Uniform coordinate image created!")
print(f"Image shape: {uniform_image.data.shape}")
coord_type = "Uniform" if uniform_image.is_uniform_coords else "Non-uniform"
print(f"Coordinate system: {coord_type}")
print(f"X spacing (dx): {uniform_image.dx} μm")
print(f"Y spacing (dy): {uniform_image.dy} μm")
print(f"X origin: {uniform_image.x0} μm")
print(f"Y origin: {uniform_image.y0} μm")
x_end = uniform_image.x0 + uniform_image.dx * (uniform_image.data.shape[1] - 1)
y_end = uniform_image.y0 + uniform_image.dy * (uniform_image.data.shape[0] - 1)
print(f"X range: {uniform_image.x0:.1f} to {x_end:.1f} μm")
print(f"Y range: {uniform_image.y0:.1f} to {y_end:.1f} μm")
✓ Uniform coordinate image created!
Image shape: (100, 100)
Coordinate system: Uniform
X spacing (dx): 0.1 μm
Y spacing (dy): 0.1 μm
X origin: -2.0 μm
Y origin: -2.0 μm
X range: -2.0 to 7.9 μm
Y range: -2.0 to 7.9 μm
Création d’images de test avec des coordonnées non uniformes#
Les coordonnées non uniformes permettent un espacement variable entre les pixels, utile pour l’échantillonnage adaptatif, les coordonnées courbes ou les grilles irrégulières.
# Create the same sine wave pattern but with non-uniform coordinates
data_nonuniform = data_uniform.copy()
# Create non-uniform coordinate arrays
# X coordinates: denser near the center, sparser at edges
x_center = 2 * np.pi
x_range = 4 * np.pi
x_nonuniform = x_center + (x_range / 2) * np.tanh(np.linspace(-2, 2, size))
# Y coordinates: quadratic spacing (denser at bottom)
y_start = 0
y_end = 4 * np.pi
y_nonuniform = y_start + (y_end - y_start) * (np.linspace(0, 1, size) ** 2)
# Create the image object with non-uniform coordinates
nonuniform_image = create_image(
title="Non-Uniform Coordinates",
data=data_nonuniform,
units=("μm", "μm", "intensity"),
labels=("X position", "Y position", "Signal"),
)
# Set non-uniform coordinate system
nonuniform_image.set_coords(xcoords=x_nonuniform, ycoords=y_nonuniform)
print("\n✓ Non-uniform coordinate image created!")
print(f"Image shape: {nonuniform_image.data.shape}")
coord_type = "Uniform" if nonuniform_image.is_uniform_coords else "Non-uniform"
print(f"Coordinate system: {coord_type}")
print(f"X coordinates range: {x_nonuniform[0]:.3f} to {x_nonuniform[-1]:.3f} μm")
print(f"Y coordinates range: {y_nonuniform[0]:.3f} to {y_nonuniform[-1]:.3f} μm")
x_spacing_min = np.min(np.diff(x_nonuniform))
x_spacing_max = np.max(np.diff(x_nonuniform))
y_spacing_min = np.min(np.diff(y_nonuniform))
y_spacing_max = np.max(np.diff(y_nonuniform))
print(f"X spacing varies from {x_spacing_min:.4f} to {x_spacing_max:.4f} μm")
print(f"Y spacing varies from {y_spacing_min:.4f} to {y_spacing_max:.4f} μm")
✓ Non-uniform coordinate image created!
Image shape: (100, 100)
Coordinate system: Non-uniform
X coordinates range: 0.226 to 12.340 μm
Y coordinates range: 0.000 to 12.566 μm
X spacing varies from 0.0187 to 0.2538 μm
Y spacing varies from 0.0013 to 0.2526 μm
Visualisation des différences entre les systèmes de coordonnées#
Créons des visualisations de grilles de coordonnées pour mettre en évidence les différences entre les systèmes de coordonnées uniformes et non uniformes.
# Create coordinate grid images for visualization
grid_uniform = np.zeros_like(data_uniform)
grid_nonuniform = np.zeros_like(data_nonuniform)
# Add grid lines every 10 pixels for uniform coordinates
grid_uniform[::10, :] = 1.0 # Horizontal lines
grid_uniform[:, ::10] = 1.0 # Vertical lines
# Add grid lines every 10 pixels for non-uniform coordinates
grid_nonuniform[::10, :] = 1.0 # Horizontal lines
grid_nonuniform[:, ::10] = 1.0 # Vertical lines
# Create grid visualization images
uniform_grid = create_image(
title="Uniform Grid",
data=grid_uniform,
units=("μm", "μm", "grid"),
labels=("X position", "Y position", "Grid lines"),
)
uniform_grid.set_uniform_coords(dx, dy, x0=x0, y0=y0)
nonuniform_grid = create_image(
title="Non-Uniform Grid",
data=grid_nonuniform,
units=("μm", "μm", "grid"),
labels=("X position", "Y position", "Grid lines"),
)
nonuniform_grid.set_coords(xcoords=x_nonuniform, ycoords=y_nonuniform)
print("\n✓ Coordinate grid visualizations created!")
# Display the coordinate system comparison
view_images_side_by_side(
[uniform_image, nonuniform_image],
["Uniform Coordinates", "Non-Uniform Coordinates"],
title="Coordinate Systems Comparison - Data Images",
share_axes=False,
)
view_images_side_by_side(
[uniform_grid, nonuniform_grid],
["Uniform Grid", "Non-Uniform Grid"],
title="Coordinate Systems Comparison - Grid Visualization",
share_axes=False,
)
✓ Coordinate grid visualizations created!
Création d’exemples spécialisés de coordonnées non uniformes#
Créons des exemples plus réalistes de coordonnées non uniformes qui pourraient être rencontrées dans des applications réelles :
Spectroscopie résolue en temps avec une échelle de longueur d’onde logarithmique
Conversion polaire en cartésien
# Example 1: Logarithmic wavelength scale for spectroscopy
# Simulating a time-resolved spectroscopy measurement with log-spaced wavelengths
size_log = 80
wavelengths = np.logspace(np.log10(400), np.log10(800), size_log) # 400-800 nm
time_points = np.linspace(0, 200, size_log) # Time in milliseconds
W, T = np.meshgrid(wavelengths, time_points)
# Create a spectral response pattern: a peak that shifts over time
# Simulates fluorescence decay with spectral shift
peak_center = 500 + 0.5 * T # Peak shifts from 500 to 600 nm over time
spectral_data = np.exp(-(((W - peak_center) / 40) ** 2)) * np.exp(-T / 100)
spectral_image = create_image(
title="Time-Resolved Spectroscopy (Log λ)",
data=spectral_data,
units=("nm", "ms", "counts"),
labels=("Wavelength", "Time", "Fluorescence"),
)
spectral_image.set_coords(xcoords=wavelengths, ycoords=time_points)
print("\n✓ Time-resolved spectroscopy example created!")
print(f"Wavelength range: {wavelengths[0]:.1f} to {wavelengths[-1]:.1f} nm")
print(f"Time range: {time_points[0]:.1f} to {time_points[-1]:.1f} ms")
wl_spacing_min = np.min(np.diff(wavelengths))
wl_spacing_max = np.max(np.diff(wavelengths))
print(f"Log wavelength spacing: {wl_spacing_min:.2f} to {wl_spacing_max:.2f} nm")
# Example 2: Polar to Cartesian mapping
size_polar = 60
r_coords = np.linspace(1, 10, size_polar)
theta_coords = np.linspace(0, 2 * np.pi, size_polar)
# Convert to Cartesian coordinates for non-uniform mapping
x_polar = np.zeros((size_polar, size_polar))
y_polar = np.zeros((size_polar, size_polar))
for i, r in enumerate(r_coords):
for j, theta in enumerate(theta_coords):
x_polar[i, j] = r * np.cos(theta)
y_polar[i, j] = r * np.sin(theta)
# Create a radial pattern
polar_data = np.zeros((size_polar, size_polar))
for i, r in enumerate(r_coords):
for j, theta in enumerate(theta_coords):
polar_data[i, j] = np.sin(3 * theta) * np.exp(-r / 5)
# Note: For this example, we'll use the polar coordinates directly
# In practice, you might want to interpolate to a regular Cartesian grid
polar_image = create_image(
title="Polar Coordinate Mapping",
data=polar_data,
units=("mm", "rad", "signal"),
labels=("Radius", "Angle", "Amplitude"),
)
polar_image.set_coords(xcoords=r_coords, ycoords=theta_coords)
print("\n✓ Polar coordinate example created!")
print(f"Radial range: {r_coords[0]:.1f} to {r_coords[-1]:.1f} mm")
print(f"Angular range: {theta_coords[0]:.2f} to {theta_coords[-1]:.2f} rad")
# Display the specialized examples
view_images_side_by_side(
[spectral_image, polar_image],
["Time-Resolved Spectroscopy (Log λ)", "Polar Coordinates"],
title="Specialized Non-Uniform Coordinate Examples",
share_axes=False,
)
✓ Time-resolved spectroscopy example created!
Wavelength range: 400.0 to 800.0 nm
Time range: 0.0 to 200.0 ms
Log wavelength spacing: 3.53 to 6.99 nm
✓ Polar coordinate example created!
Radial range: 1.0 to 10.0 mm
Angular range: 0.00 to 6.28 rad
Résumé et meilleures pratiques#
Résumons quand utiliser chaque type de système de coordonnées.
print("\n" + "=" * 60)
print("COORDINATE SYSTEMS SUMMARY")
print("=" * 60)
print("\n🔲 UNIFORM COORDINATES:")
print(" ✓ Regular imaging systems (cameras, microscopes)")
print(" ✓ Constant pixel spacing in physical units")
print(" ✓ Simple and memory-efficient")
print(" ✓ Fast computations and interpolations")
print(" ✓ Easy integration with standard image processing")
print("\n🔳 NON-UNIFORM COORDINATES:")
print(" ✓ Adaptive sampling systems")
print(" ✓ Curved or distorted coordinate systems")
print(" ✓ Logarithmic or specialized scales")
print(" ✓ Irregular measurement grids")
print(" ✓ Coordinate transformations (polar to Cartesian)")
print("\n📊 PERFORMANCE CONSIDERATIONS:")
print(" • Uniform: O(1) coordinate lookup")
print(" • Non-uniform: O(n) coordinate lookup")
print(" • Memory: Uniform uses 4 parameters, Non-uniform uses 2×N arrays")
print("\n💾 FILE FORMAT SUPPORT:")
print(" • Both coordinate types supported in Sigima HDF5 format")
print(" • Coordinated text format supports non-uniform coordinates")
print(" • Standard image formats (TIFF, etc.) assume uniform coordinates")
# Final comparison view
view_images_side_by_side(
[uniform_image, nonuniform_image, spectral_image, polar_image],
[
"Uniform\n(Regular Grid)",
"Non-Uniform\n(Variable Grid)",
"Time-Resolved\n(Log Wavelength)",
"Polar\n(Radial Data)",
],
title="Complete Coordinate Systems Overview",
share_axes=False,
)
print("\n✨ Example completed successfully!")
print("This demonstrates the flexibility of Sigima's coordinate system support.")
============================================================
COORDINATE SYSTEMS SUMMARY
============================================================
🔲 UNIFORM COORDINATES:
✓ Regular imaging systems (cameras, microscopes)
✓ Constant pixel spacing in physical units
✓ Simple and memory-efficient
✓ Fast computations and interpolations
✓ Easy integration with standard image processing
🔳 NON-UNIFORM COORDINATES:
✓ Adaptive sampling systems
✓ Curved or distorted coordinate systems
✓ Logarithmic or specialized scales
✓ Irregular measurement grids
✓ Coordinate transformations (polar to Cartesian)
📊 PERFORMANCE CONSIDERATIONS:
• Uniform: O(1) coordinate lookup
• Non-uniform: O(n) coordinate lookup
• Memory: Uniform uses 4 parameters, Non-uniform uses 2×N arrays
💾 FILE FORMAT SUPPORT:
• Both coordinate types supported in Sigima HDF5 format
• Coordinated text format supports non-uniform coordinates
• Standard image formats (TIFF, etc.) assume uniform coordinates
✨ Example completed successfully!
This demonstrates the flexibility of Sigima's coordinate system support.