diff --git a/python_app/gui/controllers/app_window_plot/gpr_plot_mixin.py b/python_app/gui/controllers/app_window_plot/gpr_plot_mixin.py index 6947feb..94b87f7 100644 --- a/python_app/gui/controllers/app_window_plot/gpr_plot_mixin.py +++ b/python_app/gui/controllers/app_window_plot/gpr_plot_mixin.py @@ -14,6 +14,12 @@ from python_app.orchestration.gpr_locator import ( gpr_object_rows as extract_gpr_object_rows, ) +# Fraction of the frame maximum below which the heatmap is not highlighted +# (same as cloud-threshold=0.75 in the VNA_AlGo 3D SAR animation): the color +# scale is stretched over [frac*max, max], everything below falls into the +# darkest LUT color. +HEATMAP_DISPLAY_THRESHOLD_FRAC = 0.75 + class AppWindowGprPlotMixin: """Renders GPR accumulator heatmaps and detected object overlays.""" @@ -244,7 +250,9 @@ class AppWindowGprPlotMixin: self._gpr_image_item.setImage(image, autoLevels=False) self._gpr_image_item.setRect(rect) self._gpr_image_item.setLookupTable(self._gpr_lookup_table) - self._gpr_image_item.setLevels((float(np.min(image)), float(np.max(image) + 1e-6))) + image_max = float(np.max(image)) + self._gpr_image_item.setLevels( + (HEATMAP_DISPLAY_THRESHOLD_FRAC * image_max, image_max + 1e-6)) self._gpr_image_item.show() visible_x_min, visible_x_max, visible_z_min, visible_z_max = self._gpr_visible_bounds() diff --git a/python_app/gui/controllers/app_window_plot/sar3d_plot_mixin.py b/python_app/gui/controllers/app_window_plot/sar3d_plot_mixin.py index 2c5253d..80d93f9 100644 --- a/python_app/gui/controllers/app_window_plot/sar3d_plot_mixin.py +++ b/python_app/gui/controllers/app_window_plot/sar3d_plot_mixin.py @@ -21,6 +21,9 @@ from PyQt6.QtCore import QRectF import numpy as np import pyqtgraph as pg +from python_app.gui.controllers.app_window_plot.gpr_plot_mixin import ( + HEATMAP_DISPLAY_THRESHOLD_FRAC, +) from python_app.gui.runtime.sar3d_views import sar3d_bottom_view_deg_from_label from python_app.models.dataset_model import ResultCollection @@ -111,8 +114,9 @@ class AppWindowSar3dPlotMixin: image_item.setImage(image, autoLevels=False) image_item.setRect(rect) image_item.setLookupTable(self._sar3d_lookup_table) - # Projections are normalized to [0, 1] by the processor. - image_item.setLevels((0.0, 1.0)) + # Projections are normalized to [0, 1] by the processor; stretch the + # colors over [threshold, 1] like the 3D animation cloud cutoff. + image_item.setLevels((HEATMAP_DISPLAY_THRESHOLD_FRAC, 1.0)) image_item.show() plot.setXRange(x_min, x_max, padding=0.0) plot.setYRange(y_min, y_max, padding=0.0)