Add 2d ploting for axis lines
This commit is contained in:
@ -11,8 +11,8 @@ set(CMAKE_AUTORCC ON)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
find_package(QT NAMES Qt6 Qt5 COMPONENTS Widgets Concurrent REQUIRED)
|
||||
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Widgets Concurrent REQUIRED)
|
||||
find_package(QT NAMES Qt6 Qt5 COMPONENTS Widgets Concurrent PrintSupport REQUIRED)
|
||||
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Widgets Concurrent PrintSupport REQUIRED)
|
||||
find_package(OpenCV REQUIRED)
|
||||
|
||||
set(PROJECT_SOURCES
|
||||
@ -53,12 +53,23 @@ set(PROJECT_SOURCES
|
||||
src/ui/statisticsdialog.h
|
||||
src/ui/statisticsdialog.cpp
|
||||
src/ui/statisticsdialog.ui
|
||||
src/ui/plot.cpp
|
||||
src/ui/plot.h
|
||||
src/qcustomplot/qcustomplot.h
|
||||
src/qcustomplot/qcustomplot.cpp
|
||||
src/regessioncalculator.h
|
||||
src/regessioncalculator.cpp
|
||||
src/ui/regressiondiag.h
|
||||
src/ui/regressiondiag.cpp
|
||||
src/ui/regressiondiag.ui
|
||||
src/utilites.h
|
||||
src/utilites.cpp
|
||||
)
|
||||
|
||||
|
||||
add_executable(MAClient ${PROJECT_SOURCES})
|
||||
target_compile_options(MAClient PRIVATE "-std=gnu++17" "-Wall" "-O2" "-fno-strict-aliasing")
|
||||
target_link_libraries(MAClient PRIVATE Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Concurrent ${OpenCV_LIBS} -luvoscam -luvosled -luvosunwrap)
|
||||
target_link_libraries(MAClient PRIVATE Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Concurrent Qt${QT_VERSION_MAJOR}::PrintSupport ${OpenCV_LIBS} -luvoscam -luvosled -luvosunwrap)
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE ${OpenCV_INCLUDE_DIRS} src src/ui)
|
||||
|
||||
set(CMAKE_INSTALL_PREFIX "/usr")
|
||||
|
35496
src/qcustomplot/qcustomplot.cpp
Normal file
35496
src/qcustomplot/qcustomplot.cpp
Normal file
File diff suppressed because it is too large
Load Diff
7737
src/qcustomplot/qcustomplot.h
Normal file
7737
src/qcustomplot/qcustomplot.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -13,6 +13,8 @@ CvImageViewer::CvImageViewer(QWidget *parent, size_t lastId) :
|
||||
zoomAction_("Zoom to selection", nullptr),
|
||||
resetAction_("Reset Zoom", nullptr),
|
||||
statisticsAction_("Get selection properties", nullptr),
|
||||
xPlotAction_("Plot x axis", nullptr),
|
||||
yPlotAction_("Plot y axis", nullptr),
|
||||
roi_(0,0,0,0)
|
||||
{
|
||||
qimage_.load(":/images/noimage.png");
|
||||
@ -21,11 +23,20 @@ CvImageViewer::CvImageViewer(QWidget *parent, size_t lastId) :
|
||||
connect(&zoomAction_, &QAction::triggered, this, &CvImageViewer::zoomToSelection);
|
||||
connect(&resetAction_, &QAction::triggered, this, &CvImageViewer::resetZoom);
|
||||
connect(&statisticsAction_, &QAction::triggered, this, &CvImageViewer::showSatDiag);
|
||||
connect(&xPlotAction_, &QAction::triggered, this, &CvImageViewer::plotOnX);
|
||||
connect(&yPlotAction_, &QAction::triggered, this, &CvImageViewer::plotOnY);
|
||||
|
||||
imageContextMenu_.addAction(&saveAction_);
|
||||
imageContextMenu_.addAction(&zoomAction_);
|
||||
imageContextMenu_.addAction(&resetAction_);
|
||||
imageContextMenu_.addAction(&statisticsAction_);
|
||||
imageContextMenu_.addAction(&xPlotAction_);
|
||||
imageContextMenu_.addAction(&yPlotAction_);
|
||||
|
||||
plot.setMinimumWidth(800);
|
||||
plot.setMinimumHeight(600);
|
||||
|
||||
setMouseTracking(true);
|
||||
}
|
||||
|
||||
CvImageViewer::~CvImageViewer()
|
||||
@ -62,11 +73,8 @@ void CvImageViewer::saveImage()
|
||||
}
|
||||
}
|
||||
|
||||
void CvImageViewer::showSatDiag()
|
||||
cv::Rect CvImageViewer::roiFromSelection()
|
||||
{
|
||||
if(origImage_.channels() > 1 || selectionRect_.width() < 2 || selectionRect_.height() < 2)
|
||||
return;
|
||||
|
||||
int xA;
|
||||
int yA;
|
||||
int xB;
|
||||
@ -74,9 +82,21 @@ void CvImageViewer::showSatDiag()
|
||||
transfromToSourceCoordinates(selectionRect_.x(), selectionRect_.y(), xA, yA);
|
||||
transfromToSourceCoordinates(selectionRect_.x()+selectionRect_.width(), selectionRect_.y()+selectionRect_.height(), xB, yB);
|
||||
selectionRect_ = QRect(0, 0, 0, 0);
|
||||
cv::Rect roi(xA, yA, xB-xA, yB-yA);
|
||||
cv::Rect roi;
|
||||
if(xA > xB)
|
||||
roi = cv::Rect(xB, yB, xA-xB, yA-yB);
|
||||
else
|
||||
roi = cv::Rect(xA, yA, xB-xA, yB-yA);
|
||||
return roi;
|
||||
}
|
||||
|
||||
cv::Mat roiImage = origImage_(roi);
|
||||
void CvImageViewer::showSatDiag()
|
||||
{
|
||||
qDebug()<<selectionRect_.width()<<selectionRect_.height();
|
||||
if(!origImage_.data || origImage_.channels() > 1 || abs(selectionRect_.width()) < 2 || abs(selectionRect_.height()) < 2)
|
||||
return;
|
||||
|
||||
cv::Mat roiImage = origImage_(roiFromSelection());
|
||||
if(roiImage.type() != CV_64FC1)
|
||||
roiImage.convertTo(roiImage, CV_64FC1);
|
||||
|
||||
@ -92,10 +112,13 @@ void CvImageViewer::showSatDiag()
|
||||
|
||||
void CvImageViewer::setClamp(double max)
|
||||
{
|
||||
clamp_ = max;
|
||||
convertImage(origImage_);
|
||||
update();
|
||||
roi_ = cv::Rect(0, 0, image_.size().width, image_.size().height);
|
||||
if(origImage_.data)
|
||||
{
|
||||
clamp_ = max;
|
||||
convertImage(origImage_);
|
||||
update();
|
||||
roi_ = cv::Rect(0, 0, image_.size().width, image_.size().height);
|
||||
}
|
||||
}
|
||||
|
||||
void CvImageViewer::convertImage(cv::Mat image)
|
||||
@ -105,6 +128,8 @@ void CvImageViewer::convertImage(cv::Mat image)
|
||||
{
|
||||
qimage_ = QImage(image_.data, image_.cols, image_.rows, image_.step, QImage::Format_RGB888);
|
||||
statisticsAction_.setDisabled(true);
|
||||
xPlotAction_.setDisabled(true);
|
||||
yPlotAction_.setDisabled(true);
|
||||
}
|
||||
else if(image_.type() == CV_8UC1 || image_.type() == CV_8SC1)
|
||||
{
|
||||
@ -128,6 +153,8 @@ void CvImageViewer::convertImage(cv::Mat image)
|
||||
image_.convertTo(image_, CV_8UC1, a, b);
|
||||
qimage_ = QImage(image_.data, image_.cols, image_.rows, image_.step, QImage::Format_Grayscale8);
|
||||
statisticsAction_.setDisabled(false);
|
||||
xPlotAction_.setDisabled(false);
|
||||
yPlotAction_.setDisabled(false);
|
||||
}
|
||||
else if(image_.type() == CV_32FC3 || image_.type() == CV_64FC3)
|
||||
{
|
||||
@ -142,12 +169,16 @@ void CvImageViewer::convertImage(cv::Mat image)
|
||||
image_.convertTo(image_, CV_8UC3, a, b);
|
||||
qimage_ = QImage(image_.data, image_.cols, image_.rows, image_.step, QImage::Format_Grayscale8);
|
||||
statisticsAction_.setDisabled(true);
|
||||
xPlotAction_.setDisabled(true);
|
||||
yPlotAction_.setDisabled(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
image_.convertTo(image_, CV_8UC1, 255, 0);
|
||||
qimage_ = QImage(image_.data, image_.cols, image_.rows, image_.step, QImage::Format_Grayscale8);
|
||||
statisticsAction_.setDisabled(true);
|
||||
xPlotAction_.setDisabled(true);
|
||||
yPlotAction_.setDisabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -178,17 +209,10 @@ void CvImageViewer::resetZoom()
|
||||
|
||||
void CvImageViewer::zoomToSelection()
|
||||
{
|
||||
if(selectionRect_.width() > 2 && selectionRect_.height() > 2)
|
||||
if(abs(selectionRect_.width()) > 2 && abs(selectionRect_.height()) > 2)
|
||||
{
|
||||
convertImage(origImage_);
|
||||
int xA;
|
||||
int yA;
|
||||
int xB;
|
||||
int yB;
|
||||
transfromToSourceCoordinates(selectionRect_.x(), selectionRect_.y(), xA, yA);
|
||||
transfromToSourceCoordinates(selectionRect_.x()+selectionRect_.width(), selectionRect_.y()+selectionRect_.height(), xB, yB);
|
||||
selectionRect_ = QRect(0, 0, 0, 0);
|
||||
roi_ = cv::Rect(xA, yA, xB-xA, yB-yA);
|
||||
roi_ = roiFromSelection();
|
||||
cv::Mat cropped;
|
||||
cropped = image_(roi_);
|
||||
convertImage(cropped);
|
||||
@ -196,6 +220,68 @@ void CvImageViewer::zoomToSelection()
|
||||
}
|
||||
}
|
||||
|
||||
void CvImageViewer::plotOnX()
|
||||
{
|
||||
if(!xLine_.isNull() && origImage_.data && (origImage_.type() == CV_32FC1 || origImage_.type() == CV_64FC1))
|
||||
{
|
||||
plot.clear();
|
||||
QVector<double> keys;
|
||||
QVector<double> values;
|
||||
int x, y;
|
||||
transfromToSourceCoordinates(xLine_.p1().x(), xLine_.p1().y(), x, y);
|
||||
double max = 0;
|
||||
for(int i = 0; i < origImage_.cols; ++i)
|
||||
{
|
||||
keys.push_back(i);
|
||||
double value;
|
||||
if(origImage_.type() == CV_32FC1)
|
||||
value = origImage_.at<float>(y, i);
|
||||
else
|
||||
value = origImage_.at<double>(y, i);
|
||||
if(max < value)
|
||||
max = value;
|
||||
values.push_back(value);
|
||||
}
|
||||
|
||||
plot.setMaxValue(max);
|
||||
|
||||
plot.addData(keys, values, true);
|
||||
plot.show();
|
||||
plot.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
void CvImageViewer::plotOnY()
|
||||
{
|
||||
if(!xLine_.isNull() && origImage_.data && (origImage_.type() == CV_32FC1 || origImage_.type() == CV_64FC1))
|
||||
{
|
||||
plot.clear();
|
||||
QVector<double> keys;
|
||||
QVector<double> values;
|
||||
int x, y;
|
||||
transfromToSourceCoordinates(xLine_.p1().x(), xLine_.p1().y(), x, y);
|
||||
double max = 0;
|
||||
for(int i = 0; i < origImage_.rows; ++i)
|
||||
{
|
||||
keys.push_back(i);
|
||||
double value;
|
||||
if(origImage_.type() == CV_32FC1)
|
||||
value = origImage_.at<float>(i, x);
|
||||
else
|
||||
value = origImage_.at<double>(i, x);
|
||||
if(max < value)
|
||||
max = value;
|
||||
values.push_back(value);
|
||||
}
|
||||
|
||||
plot.setMaxValue(max);
|
||||
|
||||
plot.addData(keys, values, true);
|
||||
plot.show();
|
||||
plot.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
void CvImageViewer::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if(origImage_.data)
|
||||
@ -229,14 +315,35 @@ void CvImageViewer::mousePressEvent(QMouseEvent *event)
|
||||
|
||||
void CvImageViewer::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
if(selectionStarted_)
|
||||
if(origImage_.data && event->x() > imgrect_.x() && event->y() > imgrect_.y() && event->x() < imgrect_.x()+imgrect_.width() && event->y() < imgrect_.y()+imgrect_.height())
|
||||
{
|
||||
if(event->x() > imgrect_.x() && event->y() > imgrect_.y() && event->x() < imgrect_.x()+imgrect_.width() && event->y() < imgrect_.y()+imgrect_.height())
|
||||
if(selectionStarted_)
|
||||
{
|
||||
selectionRect_.setBottomRight(event->pos());
|
||||
repaint();
|
||||
}
|
||||
xLine_ = QLine(imgrect_.x(), event->y(), imgrect_.x()+imgrect_.width(), event->y());
|
||||
yLine_ = QLine(event->x(), imgrect_.y(), event->x(), imgrect_.y()+imgrect_.height());
|
||||
repaint();
|
||||
}
|
||||
else if(!xLine_.isNull() || !selectionRect_.isNull())
|
||||
{
|
||||
xLine_ = QLine();
|
||||
yLine_ = QLine();
|
||||
selectionRect_ = QRect();
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
void CvImageViewer::leaveEvent(QEvent *event)
|
||||
{
|
||||
if((!xLine_.isNull() || !selectionRect_.isNull()) && !imageContextMenu_.isActiveWindow() )
|
||||
{
|
||||
xLine_ = QLine();
|
||||
yLine_ = QLine();
|
||||
selectionRect_ = QRect();
|
||||
repaint();
|
||||
}
|
||||
QWidget::leaveEvent(event);
|
||||
}
|
||||
|
||||
void CvImageViewer::mouseReleaseEvent(QMouseEvent *event)
|
||||
@ -263,7 +370,10 @@ void CvImageViewer::paintEvent(QPaintEvent* event)
|
||||
imgrect_.setRect((rect().width()-rect().height()/ratio)/2, 0, rect().height()/ratio, rect().height());
|
||||
painter.drawImage(imgrect_, qimage_);
|
||||
|
||||
painter.setPen(QPen(QBrush(QColor(0,0,0,180)),1,Qt::DashLine));
|
||||
painter.setPen(QPen(QBrush(QColor(200,200,255,255)),1,Qt::DashLine));
|
||||
painter.drawLine(xLine_);
|
||||
painter.drawLine(yLine_);
|
||||
painter.setPen(Qt::NoPen);
|
||||
painter.setBrush(QBrush(QColor(255,255,255,120)));
|
||||
painter.drawRect(selectionRect_);
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <QSlider>
|
||||
#include <limits>
|
||||
#include "../cameras.h"
|
||||
#include "plot.h"
|
||||
|
||||
class CvImageViewer : public QWidget
|
||||
{
|
||||
@ -19,24 +20,33 @@ private:
|
||||
bool fixedOnWidth_ = false;
|
||||
size_t lastId_;
|
||||
QMenu imageContextMenu_;
|
||||
Plot plot;
|
||||
QAction saveAction_;
|
||||
QAction zoomAction_;
|
||||
QAction resetAction_;
|
||||
QAction statisticsAction_;
|
||||
QAction xPlotAction_;
|
||||
QAction yPlotAction_;
|
||||
QRect imgrect_;
|
||||
cv::Rect roi_;
|
||||
QRect selectionRect_;
|
||||
QLine xLine_;
|
||||
QLine yLine_;
|
||||
bool selectionStarted_ = false;
|
||||
double clamp_ = std::numeric_limits<double>::max();
|
||||
static QString lastSavePath_;
|
||||
|
||||
void transfromToSourceCoordinates(int inX, int inY, int& outX, int& outY);
|
||||
void convertImage(cv::Mat image);
|
||||
cv::Rect roiFromSelection();
|
||||
|
||||
private slots:
|
||||
void saveImage();
|
||||
void zoomToSelection();
|
||||
void resetZoom();
|
||||
void showSatDiag();
|
||||
void plotOnX();
|
||||
void plotOnY();
|
||||
|
||||
protected:
|
||||
virtual void paintEvent(QPaintEvent* event) override;
|
||||
@ -44,6 +54,7 @@ protected:
|
||||
virtual void mouseMoveEvent(QMouseEvent *event) override;
|
||||
virtual void mouseReleaseEvent(QMouseEvent *event) override;
|
||||
virtual void resizeEvent(QResizeEvent *event) override;
|
||||
virtual void leaveEvent(QEvent *event) override;
|
||||
|
||||
signals:
|
||||
void sigValue(size_t x, size_t y, double value);
|
||||
|
Reference in New Issue
Block a user