Viewer: drop the in-view ROI accumulation, the worker already does it
The statistics shown for a drawn ROI do not come from the view at all. Drawing one promotes it to a named ROI, roiGeometryEdited goes to the reading worker, and the worker's per-image results arrive in ImageData().roi, which is what the Inspector's ROI section displays. So accumulateROI/CalcROI/roiCalculated were a second implementation of the same thing whose output nothing read -- and the worker's version is the better one: it handles the mask and it persists per image. Remove them. The view now owns only the ROI's geometry and gestures, which is all the worker needs from it. This corrects the previous commit's claim that nothing surfaces ROI statistics: the Inspector does, via the worker. Verified by drawing a box over the beam centre: Sum 65453, Max 1634, Mean 0.468, centre of mass (786.3, 843.4) against a beam centre of (764, 850). Note the numbers appear from the next analysed frame onward, since the worker attaches them at analysis time and the displayed frame was analysed before the ROI existed -- that behaviour is unchanged here. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -877,7 +877,6 @@ void JFJochDiffractionImage::loadImage(std::shared_ptr<const JFJochReaderImage>
|
||||
LoadImageInternal();
|
||||
RenderImage();
|
||||
Redraw();
|
||||
CalcROI();
|
||||
} else {
|
||||
image.reset();
|
||||
W = 0; H = 0;
|
||||
@@ -887,8 +886,6 @@ void JFJochDiffractionImage::loadImage(std::shared_ptr<const JFJochReaderImage>
|
||||
resetScenePointers();
|
||||
hover_resolution = NAN;
|
||||
DrawResolutionText();
|
||||
|
||||
CalcROI();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -982,88 +979,7 @@ QString JFJochDiffractionImage::HoverResolutionLabel() const {
|
||||
return QString("d = %1 \u00C5").arg(QString::number(hover_resolution, 'f', 2));
|
||||
}
|
||||
|
||||
ROIMessage JFJochDiffractionImage::AccumulateROI(
|
||||
int64_t xmin, int64_t xmax, int64_t ymin, int64_t ymax,
|
||||
const std::function<bool(int64_t, int64_t)> &inside) const {
|
||||
int64_t roi_val = 0;
|
||||
uint64_t roi_val_2 = 0;
|
||||
int64_t roi_max = INT64_MIN;
|
||||
uint64_t roi_npixel = 0;
|
||||
uint64_t roi_npixel_masked = 0;
|
||||
float x_weighted = 0.0f;
|
||||
float y_weighted = 0.0f;
|
||||
|
||||
// Clamp bounds defensively to the image
|
||||
xmin = std::max<int64_t>(0, xmin);
|
||||
ymin = std::max<int64_t>(0, ymin);
|
||||
xmax = std::min<int64_t>(W, xmax);
|
||||
ymax = std::min<int64_t>(H, ymax);
|
||||
|
||||
const auto &pixels = image->Image();
|
||||
|
||||
for (int64_t y = ymin; y < ymax; ++y) {
|
||||
for (int64_t x = xmin; x < xmax; ++x) {
|
||||
if (!inside(x, y)) continue;
|
||||
|
||||
const int32_t val = pixels[x + W * y];
|
||||
|
||||
if (val == SATURATED_PXL_VALUE || val == ERROR_PXL_VALUE) {
|
||||
roi_npixel_masked++;
|
||||
} else if (val != GAP_PXL_VALUE) {
|
||||
x_weighted += static_cast<float>(val) * x;
|
||||
y_weighted += static_cast<float>(val) * y;
|
||||
roi_val += val;
|
||||
roi_val_2 += static_cast<uint64_t>(val) * val;
|
||||
if (val > roi_max) roi_max = val;
|
||||
roi_npixel++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ROIMessage{
|
||||
.sum = roi_val,
|
||||
.sum_square = roi_val_2,
|
||||
.max_count = roi_max,
|
||||
.pixels = roi_npixel,
|
||||
.pixels_masked = roi_npixel_masked,
|
||||
.x_weighted = std::lroundf(x_weighted),
|
||||
.y_weighted = std::lroundf(y_weighted),
|
||||
};
|
||||
}
|
||||
|
||||
void JFJochDiffractionImage::CalcROI() {
|
||||
if (!image || W * H == 0) {
|
||||
auto msg = ROIMessage{.pixels = 0, .pixels_masked = 0};
|
||||
emit roiCalculated(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
auto box_norm = roiBox.normalized();
|
||||
|
||||
// Using the rectangle as-is; you can adjust inclusivity if needed
|
||||
const int64_t xmin = box_norm.left();
|
||||
const int64_t xmax = box_norm.right();
|
||||
const int64_t ymin = box_norm.top();
|
||||
const int64_t ymax = box_norm.bottom();
|
||||
|
||||
ROIMessage msg{};
|
||||
if (roi_type == RoiType::RoiBox)
|
||||
msg = AccumulateROI(xmin, xmax, ymin, ymax,
|
||||
[](int64_t, int64_t) { return true; }); // everything in the rectangle
|
||||
else {
|
||||
const QPointF delta = roiStartPos - roiEndPos;
|
||||
const float cx = static_cast<float>(roiStartPos.x());
|
||||
const float cy = static_cast<float>(roiStartPos.y());
|
||||
const float r2 = static_cast<float>(delta.x() * delta.x() + delta.y() * delta.y());
|
||||
msg = AccumulateROI(xmin, xmax, ymin, ymax,
|
||||
[cx, cy, r2](int64_t x, int64_t y) {
|
||||
const float dx = static_cast<float>(x) - cx;
|
||||
const float dy = static_cast<float>(y) - cy;
|
||||
return dx * dx + dy * dy <= r2;
|
||||
});
|
||||
}
|
||||
emit roiCalculated(msg);
|
||||
}
|
||||
|
||||
QString JFJochDiffractionImage::PixelLabel(int x, int y) const {
|
||||
if (!image)
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include <QPainterPath>
|
||||
|
||||
#include "JFJochImage.h"
|
||||
@@ -34,9 +32,7 @@ Q_OBJECT
|
||||
|
||||
// This is the view that has detector counts, so it is the one that offers an ROI
|
||||
[[nodiscard]] bool AllowROI() const override { return true; }
|
||||
void CalcROI() override;
|
||||
[[nodiscard]] ROIMessage AccumulateROI(int64_t xmin, int64_t xmax, int64_t ymin, int64_t ymax,
|
||||
const std::function<bool(int64_t, int64_t)> &inside) const;
|
||||
|
||||
void drawForeground(QPainter *painter, const QRectF &rect) override;
|
||||
public:
|
||||
enum class RingMode {Auto, Estimation, Manual, None, IceRings};
|
||||
@@ -119,7 +115,6 @@ private:
|
||||
void mouseHover(const QPointF &scenePos, Qt::KeyboardModifiers modifiers) override;
|
||||
|
||||
signals:
|
||||
void roiCalculated(ROIMessage &output);
|
||||
void roiGeometryEdited(ROIDefinition rois);
|
||||
void roiSelected(QString name); // user picked an ROI by clicking it on the image
|
||||
public slots:
|
||||
|
||||
@@ -514,7 +514,6 @@ void JFJochImage::saveImageToFile(bool with_overlay) {
|
||||
void JFJochImage::clearROIInternal() {
|
||||
roiBox = QRectF(); // clear any ROI
|
||||
// Keep current roi_type; ROI simply becomes empty
|
||||
CalcROI(); // will emit a zeroed ROI message
|
||||
updateOverlay();
|
||||
emit writeStatusBar(tr("ROI cleared"), 1500);
|
||||
}
|
||||
@@ -602,7 +601,6 @@ void JFJochImage::updateROI() {
|
||||
}
|
||||
emit roiCircleUpdated(roiStartPos.x(), roiStartPos.y(), radius);
|
||||
}
|
||||
CalcROI();
|
||||
updateOverlay();
|
||||
}
|
||||
|
||||
|
||||
@@ -185,9 +185,6 @@ protected:
|
||||
|
||||
ResizeHandle hitTestROIHandle(const QPointF& scenePos, qreal tol = 3.0) const;
|
||||
|
||||
// Statistics over roiBox, for the view that has pixel values to accumulate
|
||||
virtual void CalcROI() {}
|
||||
|
||||
void updateOverlay();
|
||||
void RenderImage();
|
||||
PixelColorMap MakeColorMap() const;
|
||||
|
||||
Reference in New Issue
Block a user