jfjoch_viewer: Extra panel for ROI (tbd)
This commit is contained in:
@@ -56,6 +56,8 @@ ADD_EXECUTABLE(jfjoch_viewer jfjoch_viewer.cpp JFJochViewerWindow.cpp JFJochView
|
||||
windows/JFJochViewerReflectionListWindow.h
|
||||
widgets/JFJochOneOverResSqChartView.cpp
|
||||
widgets/JFJochOneOverResSqChartView.h
|
||||
JFJochViewerImageROIStatistics.cpp
|
||||
JFJochViewerImageROIStatistics.h
|
||||
)
|
||||
|
||||
TARGET_LINK_LIBRARIES(jfjoch_viewer Qt6::Core Qt6::Gui Qt6::Widgets Qt6::Charts Qt6::DBus
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <QGraphicsScene>
|
||||
#include <QWheelEvent>
|
||||
#include <QScrollBar>
|
||||
#include <QMenu>
|
||||
#include <cmath>
|
||||
|
||||
// Constructor
|
||||
@@ -107,6 +108,8 @@ void JFJochViewerImage::mousePressEvent(QMouseEvent *event) {
|
||||
else
|
||||
mouse_event_type = MouseEventType::Panning;
|
||||
}
|
||||
} else if (event->button() == Qt::RightButton) {
|
||||
mouse_event_type = MouseEventType::RightClickMenu;
|
||||
}
|
||||
QGraphicsView::mousePressEvent(event); // Call base implementation
|
||||
}
|
||||
@@ -175,7 +178,9 @@ void JFJochViewerImage::mouseReleaseEvent(QMouseEvent *event) {
|
||||
if (!scene() || !image) return;
|
||||
|
||||
setCursor(Qt::CursorShape::ArrowCursor);
|
||||
if (mouse_event_type == MouseEventType::MovingROI) {
|
||||
if (mouse_event_type == MouseEventType::RightClickMenu) {
|
||||
ShowImageMenu(event);
|
||||
} else if (mouse_event_type == MouseEventType::MovingROI) {
|
||||
if (roi_type == RoiType::RoiBox) {
|
||||
roiStartPos = RoundPoint(roiStartPos);
|
||||
roiEndPos = RoundPoint(roiEndPos);
|
||||
@@ -669,3 +674,57 @@ void JFJochViewerImage::highlightIceRings(bool input) {
|
||||
highlight_ice_rings = input;
|
||||
Redraw();
|
||||
}
|
||||
|
||||
void JFJochViewerImage::ShowImageMenu(QMouseEvent *event) {
|
||||
auto mouse_loc = mapToScene(event->pos());
|
||||
float radius = roi_box.height() / 2.0;
|
||||
QPointF center = roi_box.center();
|
||||
bool mouse_in_roi = false;
|
||||
|
||||
if (roi_box.width() * roi_box.height() > 0) {
|
||||
if (roi_box.contains(mouse_loc)) {
|
||||
if (roi_type == RoiType::RoiCircle) {
|
||||
float dx = mouse_loc.x() - center.x();
|
||||
float dy = mouse_loc.y() - center.y();
|
||||
float distance_sq = dx * dx + dy * dy;
|
||||
|
||||
if (distance_sq <= radius * radius) {
|
||||
mouse_in_roi = true;
|
||||
}
|
||||
} else
|
||||
mouse_in_roi = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (mouse_in_roi) {
|
||||
QMenu menu;
|
||||
|
||||
// Show ROI coordinates (read-only)
|
||||
|
||||
QString roi_coordinates;
|
||||
if (roi_type == RoiType::RoiBox) {
|
||||
roi_coordinates = QString("ROI Box x: [%1, %2] y: [%3, %4]")
|
||||
.arg(roi_box.left())
|
||||
.arg(roi_box.right())
|
||||
.arg(roi_box.top())
|
||||
.arg(roi_box.bottom());
|
||||
} else {
|
||||
roi_coordinates = QString("ROI Circle: center: [%1, %2] r: %3").arg(center.x()).arg(center.y()).arg(radius);
|
||||
}
|
||||
|
||||
menu.addAction(roi_coordinates)->setDisabled(true);
|
||||
|
||||
// Add or remove from user mask
|
||||
QAction *addMaskAction = menu.addAction("Add to user mask");
|
||||
QAction *removeMaskAction = menu.addAction("Remove from user mask");
|
||||
|
||||
// Show the menu at the cursor's position
|
||||
QAction *selectedAction = menu.exec(event->globalPos());
|
||||
|
||||
if (selectedAction == addMaskAction) {
|
||||
// Implement "Add to user mask" functionality here
|
||||
} else if (selectedAction == removeMaskAction) {
|
||||
// Implement "Remove from user mask" functionality here
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,6 +48,9 @@ private:
|
||||
void DrawTopPixels();
|
||||
void DrawSaturation();
|
||||
void DrawCross(float x, float y, float size, float width, float z = 1);
|
||||
|
||||
void ShowImageMenu(QMouseEvent *event);
|
||||
|
||||
double scale_factor = 1.0;
|
||||
ColorScale color_scale;
|
||||
std::shared_ptr<const JFJochReaderImage> image;
|
||||
@@ -71,7 +74,7 @@ private:
|
||||
QPointF roiEndPos;
|
||||
|
||||
enum class RoiType {RoiBox, RoiCircle};
|
||||
enum class MouseEventType {None, Panning, DrawingROI, MovingROI};
|
||||
enum class MouseEventType {None, Panning, DrawingROI, MovingROI, RightClickMenu};
|
||||
MouseEventType mouse_event_type = MouseEventType::None;
|
||||
RoiType roi_type = RoiType::RoiBox;
|
||||
|
||||
|
||||
43
viewer/JFJochViewerImageROIStatistics.cpp
Normal file
43
viewer/JFJochViewerImageROIStatistics.cpp
Normal file
@@ -0,0 +1,43 @@
|
||||
// SPDX-FileCopyrightText: 2025 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
#include "JFJochViewerImageROIStatistics.h"
|
||||
|
||||
#include "../../.cache/JetBrains/CLion2025.2/.docker/2025_2/Docker/gitea_psi_ch_leonarski_f_jfjoch_ubuntu2404_2510/usr/include/x86_64-linux-gnu/qt6/QtWidgets/QVBoxLayout"
|
||||
|
||||
JFJochViewerImageROIStatistics::JFJochViewerImageROIStatistics(QWidget *parent)
|
||||
: QWidget(parent) {
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
|
||||
roi_pos = new QLabel("None", this);
|
||||
roi_label = new QLabel("", this);
|
||||
|
||||
layout->addWidget(roi_pos);
|
||||
layout->addWidget(roi_label);
|
||||
}
|
||||
|
||||
void JFJochViewerImageROIStatistics::loadImage(std::shared_ptr<const JFJochReaderImage> image) {
|
||||
if (!image) {
|
||||
roi_pos->setText("None");
|
||||
roi_label->setText("");
|
||||
} else {
|
||||
auto roi = image->GetROI();
|
||||
|
||||
if (roi && roi->pixels > 0) {
|
||||
auto roi_npixel = static_cast<double>(roi->pixels);
|
||||
double roi_mean_val = static_cast<double>(roi->sum) / roi_npixel;
|
||||
double variance = static_cast<double>(roi->sum_square) / roi_npixel - roi_mean_val * roi_mean_val;
|
||||
|
||||
QString text = QString("Sum <b>%1</b> Mean <b>%2</b> Var <b>%3</b> Max <b>%4</b>")
|
||||
.arg(roi->sum)
|
||||
.arg(QString::number(roi_mean_val, 'f', 3))
|
||||
.arg(QString::number(variance, 'f', 3))
|
||||
.arg(roi->max_count);
|
||||
roi_label->setText(text);
|
||||
roi_pos->setText(QString::fromStdString(image->GetROIDescription()));
|
||||
} else {
|
||||
roi_label->setText("");
|
||||
roi_pos->setText("None");
|
||||
}
|
||||
}
|
||||
}
|
||||
23
viewer/JFJochViewerImageROIStatistics.h
Normal file
23
viewer/JFJochViewerImageROIStatistics.h
Normal file
@@ -0,0 +1,23 @@
|
||||
// SPDX-FileCopyrightText: 2025 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
|
||||
#ifndef JFJOCH_JFJOCHVIEWERIMAGEROISTATISTICS_H
|
||||
#define JFJOCH_JFJOCHVIEWERIMAGEROISTATISTICS_H
|
||||
|
||||
#include <QLabel>
|
||||
#include "../reader/JFJochReaderImage.h"
|
||||
|
||||
class JFJochViewerImageROIStatistics : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
QLabel *roi_pos;
|
||||
QLabel *roi_label;
|
||||
public:
|
||||
JFJochViewerImageROIStatistics(QWidget *parent);
|
||||
public slots:
|
||||
void loadImage(std::shared_ptr<const JFJochReaderImage> image);
|
||||
};
|
||||
|
||||
|
||||
#endif //JFJOCH_JFJOCHVIEWERIMAGEROISTATISTICS_H
|
||||
@@ -128,19 +128,6 @@ JFJochViewerImageStatistics::JFJochViewerImageStatistics(QWidget *parent) : QWid
|
||||
|
||||
b_factor = new QLabel(this);
|
||||
layout->addRow(new QLabel("B-factor:"), b_factor);
|
||||
|
||||
roi_sum = new QLabel(this);
|
||||
layout->addRow(new QLabel("ROI sum:"), roi_sum);
|
||||
|
||||
roi_mean = new QLabel(this);
|
||||
layout->addRow(new QLabel("ROI mean:"), roi_mean);
|
||||
|
||||
roi_stddev = new QLabel(this);
|
||||
layout->addRow(new QLabel("ROI st. dev.:"), roi_stddev);
|
||||
|
||||
roi_max = new QLabel(this);
|
||||
layout->addRow(new QLabel("ROI max:"), roi_max);
|
||||
|
||||
}
|
||||
|
||||
QString TrimZeros(double number, int precision) {
|
||||
@@ -172,10 +159,6 @@ void JFJochViewerImageStatistics::loadImage(std::shared_ptr<const JFJochReaderIm
|
||||
bkg_estimate->setText("");
|
||||
indexed->setText("");
|
||||
indexed->setToolTip("");
|
||||
roi_sum->setText("");
|
||||
roi_mean->setText("");
|
||||
roi_stddev->setText("");
|
||||
roi_max->setText("");
|
||||
b_factor->setText("");
|
||||
profile_radius->setText("");
|
||||
res_estimate->setText("");
|
||||
@@ -314,27 +297,4 @@ void JFJochViewerImageStatistics::loadImage(std::shared_ptr<const JFJochReaderIm
|
||||
} else {
|
||||
indexed->setText("N/A");
|
||||
}
|
||||
|
||||
auto roi = image->GetROI();
|
||||
if (roi && roi->pixels > 0) {
|
||||
text = QString("<b>%1</b>").arg(roi->sum);
|
||||
roi_sum->setText(text);
|
||||
|
||||
auto roi_npixel = static_cast<double>(roi->pixels);
|
||||
double roi_mean_val = static_cast<double>(roi->sum) / roi_npixel;
|
||||
text = QString("<b>%1</b>").arg(QString::number(roi_mean_val, 'f', 3));
|
||||
roi_mean->setText(text);
|
||||
|
||||
double variance = static_cast<double>(roi->sum_square) / roi_npixel - roi_mean_val * roi_mean_val;
|
||||
text = QString("<b>%1</b>").arg(QString::number(sqrt(variance), 'f', 3));
|
||||
roi_stddev->setText(text);
|
||||
|
||||
text = QString("<b>%1</b>").arg(roi->max_count);
|
||||
roi_max->setText(text);
|
||||
} else {
|
||||
roi_sum->setText("N/A");
|
||||
roi_mean->setText("N/A");
|
||||
roi_stddev->setText("N/A");
|
||||
roi_max->setText("N/A");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,11 +25,6 @@ class JFJochViewerImageStatistics : public QWidget {
|
||||
|
||||
QLabel *b_factor;
|
||||
QLabel *profile_radius;
|
||||
|
||||
QLabel *roi_sum;
|
||||
QLabel *roi_mean;
|
||||
QLabel *roi_stddev;
|
||||
QLabel *roi_max;
|
||||
public:
|
||||
JFJochViewerImageStatistics(QWidget *parent);
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#include <QComboBox>
|
||||
|
||||
#include "JFJochViewerSidePanel.h"
|
||||
|
||||
#include "JFJochViewerImageROIStatistics.h"
|
||||
#include "widgets/TitleLabel.h"
|
||||
#include "JFJochViewerImageStatistics.h"
|
||||
|
||||
@@ -21,8 +23,13 @@ JFJochViewerSidePanel::JFJochViewerSidePanel(QWidget *parent) : QWidget(parent)
|
||||
|
||||
auto stats = new JFJochViewerImageStatistics(this);
|
||||
layout->addWidget(stats);
|
||||
connect(this, &JFJochViewerSidePanel::imageLoaded,
|
||||
stats, &JFJochViewerImageStatistics::loadImage);
|
||||
connect(this, &JFJochViewerSidePanel::imageLoaded, stats, &JFJochViewerImageStatistics::loadImage);
|
||||
|
||||
layout->addWidget(new TitleLabel("ROI", this));
|
||||
|
||||
auto roi = new JFJochViewerImageROIStatistics(this);
|
||||
layout->addWidget(roi);
|
||||
connect(this, &JFJochViewerSidePanel::imageLoaded, roi, &JFJochViewerImageROIStatistics::loadImage);
|
||||
|
||||
layout->addWidget(new TitleLabel("Image features", this));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user