2511-eiger-mask #2

Merged
leonarski_f merged 69 commits from 2511-eiger-mask into main 2025-11-09 12:42:28 +01:00
2 changed files with 55 additions and 19 deletions
Showing only changes of commit ceeff2279b - Show all commits

View File

@@ -36,6 +36,11 @@ JFJochSimpleImageViewer::JFJochSimpleImageViewer(QWidget *parent)
// Keep overlays in pixel units independent of zoom (for labels font sizing)
setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
// QTimer for smoother movement/updates
repaint_timer_.setInterval(16); // ~60 FPS
repaint_timer_.setSingleShot(false);
connect(&repaint_timer_, &QTimer::timeout, this, &JFJochSimpleImageViewer::onRepaintTimer);
}
void JFJochSimpleImageViewer::clear() {
@@ -463,7 +468,7 @@ void JFJochSimpleImageViewer::updateROI() {
roi_box_ = roi_box_.intersected(bounds);
}
updateScene();
scheduleSceneUpdate();
}
void JFJochSimpleImageViewer::drawROI(QGraphicsScene* scn) {
@@ -534,8 +539,9 @@ JFJochSimpleImageViewer::computeROIStats(const QRect& roi_px) const {
const int y1 = std::clamp(roi_px.bottom(), 0, std::max(0, H - 1));
if (x1 < x0 || y1 < y0) return s;
// First pass: min, max, sum
double sum = 0.0L;
// One pass: min, max, sum, sum of squares
double sum = 0.0;
double sumsq = 0.0;
s.min = std::numeric_limits<double>::infinity();
s.max = -std::numeric_limits<double>::infinity();
s.count = 0;
@@ -549,27 +555,48 @@ JFJochSimpleImageViewer::computeROIStats(const QRect& roi_px) const {
if (v < s.min) s.min = v;
if (v > s.max) s.max = v;
sum += v;
sumsq += v * v;
++s.count;
}
}
if (!s.valid()) return s;
s.avg = double(sum / s.count);
// Second pass: variance
double var_sum = 0.0L;
for (int y = y0; y <= y1; ++y) {
const size_t base = size_t(y) * size_t(W);
for (int x = x0; x <= x1; ++x) {
const size_t idx = base + size_t(x);
const double v = image_values_[idx];
if (std::isnan(v)) continue;
const double d = v - s.avg;
var_sum += d * d;
}
}
const double variance = (s.count > 1) ? (var_sum / s.count) : 0.0L;
s.stddev = std::sqrt(double(variance));
s.avg = sum / double(s.count);
double variance = sumsq / double(s.count) - s.avg * s.avg;
if (variance < 0.0) variance = 0.0; // guard small negatives from FP error
s.stddev = std::sqrt(variance);
return s;
}
void JFJochSimpleImageViewer::onRepaintTimer() {
// Apply any pending pan
if (!qFuzzyIsNull(pan_accum_.x()) || !qFuzzyIsNull(pan_accum_.y())) {
translate(pan_accum_.x(), pan_accum_.y());
pan_accum_ = QPointF(0.0, 0.0);
}
// Rebuild scene if requested
if (needs_scene_update_) {
updateScene();
needs_scene_update_ = false;
}
// Stop timer if nothing pending
if (qFuzzyIsNull(pan_accum_.x()) && qFuzzyIsNull(pan_accum_.y()) && !needs_scene_update_) {
repaint_timer_.stop();
}
}
void JFJochSimpleImageViewer::schedulePanDelta(const QPointF& d) {
pan_accum_ += d;
if (!repaint_timer_.isActive())
repaint_timer_.start();
}
void JFJochSimpleImageViewer::scheduleSceneUpdate() {
needs_scene_update_ = true;
if (!repaint_timer_.isActive())
repaint_timer_.start();
}

View File

@@ -9,6 +9,7 @@
#include <QPointF>
#include <QGraphicsTextItem>
#include <vector>
#include <QTimer>
#include "../SimpleImage.h"
#include "../../common/ColorScale.h"
@@ -70,6 +71,14 @@ private:
QPoint last_mouse_pos_;
bool panning_ = false;
// Smooth movement/repaint
QTimer repaint_timer_;
QPointF pan_accum_{0.0, 0.0};
bool needs_scene_update_ = false;
void schedulePanDelta(const QPointF& d);
void scheduleSceneUpdate();
void onRepaintTimer();
// Settings
float background_ = 0.0f;
float foreground_ = 10.0f;