Compare commits
10 commits
feceb3287c
...
0ddaa0bacd
Author | SHA1 | Date | |
---|---|---|---|
|
0ddaa0bacd | ||
|
5b07c96ce7 | ||
|
6354b0379d | ||
|
24646e82ed | ||
|
1b6c3672b6 | ||
|
7350c6ce96 | ||
![]() |
a9f263b22d | ||
|
65cdc7b78f | ||
|
3c788f57c2 | ||
|
42da1746b5 |
|
@ -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")
|
||||
|
|
|
@ -6,9 +6,9 @@ Version=1.0
|
|||
# The name of the application
|
||||
Name=Lubricant Thickness Detector
|
||||
# A comment which can/will be used as a tooltip
|
||||
Comment=MAClient -sd 0 -t 30
|
||||
Comment=MAClient
|
||||
# The executable of the application, possibly with arguments.
|
||||
Exec=MAClient
|
||||
Exec=MAClient -sd 0 -t 30
|
||||
# The name of the icon that will be used to display this entry
|
||||
Icon=MAClient
|
||||
# Describes whether this application needs to be run in a terminal or not
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
/*UVOS*/
|
||||
|
||||
/* This file is part of MAClient copyright © 2021 Carl Philipp Klemm.
|
||||
*
|
||||
* MAClient is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License (GPL) version
|
||||
* 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* MAClient is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with MAClient. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "camera.h"
|
||||
#include <QRandomGenerator>
|
||||
#include <string>
|
||||
|
|
16
src/camera.h
16
src/camera.h
|
@ -1,3 +1,19 @@
|
|||
/*UVOS*/
|
||||
|
||||
/* This file is part of MAClient copyright © 2021 Carl Philipp Klemm.
|
||||
*
|
||||
* MAClient is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License (GPL) version
|
||||
* 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* MAClient is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with MAClient. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef CAMERA_H
|
||||
#define CAMERA_H
|
||||
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
/*UVOS*/
|
||||
|
||||
/* This file is part of MAClient copyright © 2021 Carl Philipp Klemm.
|
||||
*
|
||||
* MAClient is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License (GPL) version
|
||||
* 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* MAClient is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with MAClient. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "cameras.h"
|
||||
#include <QRandomGenerator>
|
||||
#include <string>
|
||||
|
@ -157,13 +173,20 @@ void Cameras::trigger()
|
|||
if(serial_)
|
||||
{
|
||||
if(captureingCamera == 0)
|
||||
lightFor(lighting_, exposrueTime_*1.5*cameras_.size());
|
||||
{
|
||||
lightFor(lighting_, 10000);
|
||||
qDebug()<<__func__<<"started";
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(static_cast<long>(exposrueTime_)));
|
||||
}
|
||||
cameras_[captureingCamera]->cam()->trigger();
|
||||
++captureingCamera;
|
||||
if(captureingCamera < cameras_.size())
|
||||
QTimer::singleShot(exposrueTime_*1000, this, &Cameras::trigger);
|
||||
else
|
||||
{
|
||||
captureingCamera = 0;
|
||||
qDebug()<<__func__<<"finished";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -271,6 +294,7 @@ void Cameras::imageRecived(Camera::Image img)
|
|||
|
||||
if(images_.size() == cameras_.size())
|
||||
{
|
||||
lightOff();
|
||||
cameraFailureTimer.stop();
|
||||
newImages(images_);
|
||||
images_.clear();
|
||||
|
@ -300,9 +324,16 @@ double Cameras::getMeanTemp()
|
|||
void Cameras::setSetup(const std::vector<CameraSetup>& setups)
|
||||
{
|
||||
for(auto& camera : cameras_)
|
||||
{
|
||||
for(auto& setup : setups)
|
||||
{
|
||||
if(camera->id() == setup.id)
|
||||
{
|
||||
camera->cam()->setBayerMode(setup.bayerMode);
|
||||
camera->cam()->setGain(setup.gain);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cameras::store(QSettings &settings)
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
/*UVOS*/
|
||||
|
||||
/* This file is part of MAClient copyright © 2021 Carl Philipp Klemm.
|
||||
*
|
||||
* MAClient is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License (GPL) version
|
||||
* 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* MAClient is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with MAClient. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef CAMERAS_H
|
||||
#define CAMERAS_H
|
||||
|
||||
|
|
|
@ -1,4 +1,20 @@
|
|||
#include "imagepipeline.h"
|
||||
/*UVOS*/
|
||||
|
||||
/* This file is part of MAClient copyright © 2021 Carl Philipp Klemm.
|
||||
*
|
||||
* MAClient is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License (GPL) version
|
||||
* 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* MAClient is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with MAClient. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "imagepipeline.h"
|
||||
#include <uvosunwrap/unwrap.h>
|
||||
#include <uvosunwrap/normalize.h>
|
||||
#include <uvosunwrap/curve.h>
|
||||
|
@ -7,6 +23,7 @@
|
|||
#include <QDebug>
|
||||
#include <algorithm>
|
||||
#include <opencv2/highgui.hpp>
|
||||
#include <math.h>
|
||||
|
||||
ImagePipeline::ImagePipeline(Cameras* cameras, bool simpleStichingAlg, QObject *parent):
|
||||
QObject(parent), cameras_(cameras), simpleStichingAlg_(simpleStichingAlg)
|
||||
|
@ -43,6 +60,19 @@ void ImagePipeline::applyDarkMap(cv::Mat& image, const cv::Mat& darkmap)
|
|||
image = subtracted;
|
||||
}
|
||||
|
||||
void ImagePipeline::sanityCheckMap(cv::Mat& mat)
|
||||
{
|
||||
for(int y = 0; y < mat.rows; y++)
|
||||
{
|
||||
float* col = mat.ptr<float>(y);
|
||||
for(int x = 0; x < mat.cols; ++x)
|
||||
{
|
||||
if(isnan(col[x]) || isinf(col[x]))
|
||||
col[x] = 0.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cv::Mat ImagePipeline::process(const Profile profile, std::vector<Camera::Image> images, bool simpleStichingAlg)
|
||||
{
|
||||
qDebug()<<__func__<<"got"<<images.size()<<"images";
|
||||
|
@ -85,7 +115,12 @@ cv::Mat ImagePipeline::process(const Profile profile, std::vector<Camera::Image>
|
|||
RemapedImage remaped = applyRemap(image.mat, camera.remapMap);
|
||||
qDebug()<<"Camera"<<camera.id<<"image remaped to"<<remaped.image.data<<remaped.image.rows<<remaped.image.cols
|
||||
<<"at"<<remaped.origin.x<<'x'<<remaped.origin.y;
|
||||
remapedImages.push_back(applyRemap(image.mat, camera.remapMap));
|
||||
RemapedImage remapedImage = applyRemap(image.mat, camera.remapMap);
|
||||
if(profile.kFactor != 0 && remapedImage.image.type() == CV_8UC1)
|
||||
applyKfactor(remapedImage.image, remapedImage.angle, profile.kFactor);
|
||||
else if(profile.kFactor != 0)
|
||||
qWarning()<<"Can not apply k factor due to image format";
|
||||
remapedImages.push_back(remapedImage);
|
||||
matched = true;
|
||||
break;
|
||||
}
|
||||
|
@ -104,7 +139,8 @@ cv::Mat ImagePipeline::process(const Profile profile, std::vector<Camera::Image>
|
|||
|
||||
if(remapedImages.size() > 0)
|
||||
{
|
||||
std::sort(remapedImages.begin(), remapedImages.end(), [](const RemapedImage& imgA, const RemapedImage& imgB) -> bool {return imgA.origin.x < imgB.origin.x;});
|
||||
std::sort(remapedImages.begin(), remapedImages.end(),
|
||||
[](const RemapedImage& imgA, const RemapedImage& imgB) -> bool {return imgA.origin.x < imgB.origin.x;});
|
||||
cv::Mat output;
|
||||
if(simpleStichingAlg)
|
||||
output = simpleStich(remapedImages);
|
||||
|
@ -136,6 +172,9 @@ cv::Mat ImagePipeline::process(const Profile profile, std::vector<Camera::Image>
|
|||
|
||||
if(profile.calcurve.data)
|
||||
applyCurve(output, profile.calcurve);
|
||||
|
||||
sanityCheckMap(output);
|
||||
|
||||
return output;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
/*UVOS*/
|
||||
|
||||
/* This file is part of MAClient copyright © 2021 Carl Philipp Klemm.
|
||||
*
|
||||
* MAClient is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License (GPL) version
|
||||
* 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* MAClient is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with MAClient. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef IMAGEPIPELINE_H
|
||||
#define IMAGEPIPELINE_H
|
||||
|
||||
|
@ -23,6 +39,7 @@ private:
|
|||
|
||||
static cv::Mat process(const Profile profile, std::vector<Camera::Image> images, bool simpleStich);
|
||||
static void applyDarkMap(cv::Mat& image, const cv::Mat &darkmap);
|
||||
static void sanityCheckMap(cv::Mat& mat);
|
||||
|
||||
private slots:
|
||||
|
||||
|
|
88
src/main.cpp
88
src/main.cpp
|
@ -1,3 +1,19 @@
|
|||
/*UVOS*/
|
||||
|
||||
/* This file is part of MAClient copyright © 2021 Carl Philipp Klemm.
|
||||
*
|
||||
* MAClient is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License (GPL) version
|
||||
* 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* MAClient is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with MAClient. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <QApplication>
|
||||
#include <uvoscam.h>
|
||||
#include <QSettings>
|
||||
|
@ -68,7 +84,7 @@ int main(int argc, char *argv[])
|
|||
QCoreApplication::setOrganizationName("UVOS");
|
||||
QCoreApplication::setOrganizationDomain("uvos.xyz");
|
||||
QCoreApplication::setApplicationName("MAClient");
|
||||
QCoreApplication::setApplicationVersion("0.1");
|
||||
QCoreApplication::setApplicationVersion("0.5");
|
||||
|
||||
//parse comand line
|
||||
QCommandLineParser parser;
|
||||
|
@ -122,41 +138,44 @@ int main(int argc, char *argv[])
|
|||
|
||||
MainWindow w(parser.isSet(viewerOption));
|
||||
|
||||
QObject::connect(&cameras, &Cameras::cameraAdded, &w, &MainWindow::addCamera);
|
||||
QObject::connect(&cameras, &Cameras::cameraRemoved, &w, &MainWindow::removeCamera);
|
||||
QObject::connect(&cameras, &Cameras::enableCapture, &w, &MainWindow::enableCapture);
|
||||
QObject::connect(&w, &MainWindow::sigCapture, [&cameras](){cameras.start(); cameras.trigger();});
|
||||
|
||||
QTimer temperatureTimer;
|
||||
temperatureTimer.setSingleShot(false);
|
||||
QObject::connect(&temperatureTimer, &QTimer::timeout, [&cameras, &w](){w.setTemperature(cameras.getMeanTemp());});
|
||||
temperatureTimer.start(1000);
|
||||
|
||||
QObject::connect(&w, &MainWindow::sigChooseCameras, [&cameras, &w]()
|
||||
if(!parser.isSet(viewerOption))
|
||||
{
|
||||
bool accepted;
|
||||
std::vector<cam::Camera::Description> descs = showCameraSelectionDialog(&accepted, &w);
|
||||
if(accepted)
|
||||
cameras.setCameras(descs);
|
||||
});
|
||||
QObject::connect(&cameras, &Cameras::cameraAdded, &w, &MainWindow::addCamera);
|
||||
QObject::connect(&cameras, &Cameras::cameraRemoved, &w, &MainWindow::removeCamera);
|
||||
QObject::connect(&cameras, &Cameras::enableCapture, &w, &MainWindow::enableCapture);
|
||||
QObject::connect(&w, &MainWindow::sigCapture, [&cameras](){cameras.start(); cameras.trigger();});
|
||||
|
||||
QObject::connect(&w, &MainWindow::sigEditProfiles, [&cameras, &w](){showProfileDialog(&cameras, &w); w.refreshProfiles();});
|
||||
QObject::connect(&pipe, &ImagePipeline::sigResult, w.mainImageViewer(), &CvImageViewer::setImage, Qt::QueuedConnection);
|
||||
QObject::connect(&pipe, &ImagePipeline::sigResult, [&w](){w.statusMsg("idle");});
|
||||
QObject::connect(&pipe, &ImagePipeline::sigInvalidProfile, &w, &MainWindow::profileInconpatible);
|
||||
QTimer temperatureTimer;
|
||||
temperatureTimer.setSingleShot(false);
|
||||
QObject::connect(&temperatureTimer, &QTimer::timeout, [&cameras, &w](){w.setTemperature(cameras.getMeanTemp());});
|
||||
temperatureTimer.start(1000);
|
||||
|
||||
QObject::connect(&w, &MainWindow::sigProfile, [&pipe](QString name)
|
||||
{
|
||||
Profile profile;
|
||||
profile.load(name);
|
||||
if(profile.cameras.size() != 0)
|
||||
qDebug()<<"loading profile"<<name<<"with"<<profile.cameras.size()<<"cameras and first camera"<<profile.cameras.at(0).id;
|
||||
else
|
||||
qDebug()<<"empty profile!!";
|
||||
pipe.setProfile(profile);
|
||||
});
|
||||
QObject::connect(&w, &MainWindow::sigChooseCameras, [&cameras, &w]()
|
||||
{
|
||||
bool accepted;
|
||||
std::vector<cam::Camera::Description> descs = showCameraSelectionDialog(&accepted, &w);
|
||||
if(accepted)
|
||||
cameras.setCameras(descs);
|
||||
});
|
||||
|
||||
cameras.load(settings);
|
||||
QObject::connect(&w, &MainWindow::sigEditProfiles, [&cameras, &w](){showProfileDialog(&cameras, &w); w.refreshProfiles();});
|
||||
QObject::connect(&pipe, &ImagePipeline::sigResult, w.mainImageViewer(), &CvImageViewer::setImage, Qt::QueuedConnection);
|
||||
QObject::connect(&pipe, &ImagePipeline::sigResult, [&w](){w.statusMsg("idle");});
|
||||
QObject::connect(&pipe, &ImagePipeline::sigInvalidProfile, &w, &MainWindow::profileInconpatible);
|
||||
|
||||
QObject::connect(&w, &MainWindow::sigProfile, [&pipe](QString name)
|
||||
{
|
||||
Profile profile;
|
||||
profile.load(name);
|
||||
if(profile.cameras.size() != 0)
|
||||
qDebug()<<"loading profile"<<name<<"with"<<profile.cameras.size()<<"cameras and first camera"<<profile.cameras.at(0).id;
|
||||
else
|
||||
qDebug()<<"empty profile!!";
|
||||
pipe.setProfile(profile);
|
||||
});
|
||||
|
||||
cameras.load(settings);
|
||||
}
|
||||
|
||||
splash.hide();
|
||||
w.show();
|
||||
|
@ -183,8 +202,9 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
ret = a.exec();
|
||||
|
||||
cameras.store(settings);
|
||||
|
||||
if(!parser.isSet(viewerOption))
|
||||
cameras.store(settings);
|
||||
}
|
||||
|
||||
if(uvosledRet >= 0)
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
/*UVOS*/
|
||||
|
||||
/* This file is part of MAClient copyright © 2021 Carl Philipp Klemm.
|
||||
*
|
||||
* MAClient is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License (GPL) version
|
||||
* 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* MAClient is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with MAClient. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "profile.h"
|
||||
#include <opencv2/imgcodecs.hpp>
|
||||
#include <QStandardPaths>
|
||||
|
@ -23,6 +39,7 @@ void CameraSetup::store(const QString &filename) const
|
|||
matf<<("_"+QString::number(id)+"_bgmask").toStdString()<<bgmask;
|
||||
}
|
||||
matf<<("_"+QString::number(id)+"_bayermode").toStdString()<<bayerMode;
|
||||
matf<<("_"+QString::number(id)+"_gain").toStdString()<<gain;
|
||||
matf.release();
|
||||
}
|
||||
|
||||
|
@ -38,6 +55,15 @@ void CameraSetup::load(const QString &filename, size_t cameraId)
|
|||
matf[("_"+QString::number(id)+"_ymat").toStdString()]>>remapMap.yMat;
|
||||
matf[("_"+QString::number(id)+"_origin").toStdString()]>>remapMap.topLeftCoordinate;
|
||||
matf[("_"+QString::number(id)+"_bayermode").toStdString()]>>bayerMode;
|
||||
try
|
||||
{
|
||||
matf[("_"+QString::number(id)+"_gain").toStdString()]>>gain;
|
||||
}
|
||||
catch(cv::Exception& e)
|
||||
{
|
||||
qWarning()<<"Profile dose not have gain";
|
||||
gain = 1.0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -66,6 +92,7 @@ void Profile::store(QSettings& settings) const
|
|||
settings.setValue(GROUP + QString("/exposureTime"), exposureTime);
|
||||
settings.setValue(GROUP + QString("/name"), name_);
|
||||
settings.setValue(GROUP + QString("/nodistort"), nodistort);
|
||||
settings.setValue(GROUP + QString("/kfact"), kFactor);
|
||||
|
||||
if(lightmap.data)
|
||||
cv::imwrite((profileLocation() + QString::number(id) + ".lightmap.png").toStdString(), lightmap);
|
||||
|
@ -97,6 +124,8 @@ void Profile::load(QSettings &settings)
|
|||
name_ = settings.value(GROUP + QString("/name"), "NULL").toString();
|
||||
nodistort = settings.value(GROUP + QString("/nodistort"), "NULL").toBool();
|
||||
|
||||
kFactor = settings.value(GROUP + QString("/kfact"), 0).toDouble();
|
||||
|
||||
lightmap = cv::imread((profileLocation() + QString::number(id) + ".lightmap.png").toStdString());
|
||||
|
||||
int size = settings.beginReadArray(GROUP + QString("/cameras"));
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
/*UVOS*/
|
||||
|
||||
/* This file is part of MAClient copyright © 2021 Carl Philipp Klemm.
|
||||
*
|
||||
* MAClient is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License (GPL) version
|
||||
* 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* MAClient is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with MAClient. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef PROFILE_H
|
||||
#define PROFILE_H
|
||||
#include <QSettings>
|
||||
|
@ -18,6 +34,7 @@ public:
|
|||
cv::Mat darkmap;
|
||||
cv::Mat bgmask;
|
||||
cam::Camera::BayerMode bayerMode = cam::Camera::BAYER_BLUE;
|
||||
double gain = 1.0;
|
||||
void store(const QString& filename) const;
|
||||
void load(const QString& name, size_t cameraId);
|
||||
};
|
||||
|
@ -48,6 +65,7 @@ public:
|
|||
cv::Mat calcurve;
|
||||
std::vector<CameraSetup> cameras;
|
||||
bool nodistort = false;
|
||||
float kFactor = 0;
|
||||
|
||||
Profile(const QString& name = "");
|
||||
void store(QSettings& settings) const;
|
||||
|
|
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
50
src/regessioncalculator.cpp
Normal file
50
src/regessioncalculator.cpp
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*UVOS*/
|
||||
|
||||
/* This file is part of MAClient copyright © 2021 Carl Philipp Klemm.
|
||||
*
|
||||
* MAClient is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License (GPL) version
|
||||
* 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* MAClient is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with MAClient. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "regessioncalculator.h"
|
||||
#include <stdexcept>
|
||||
#include <math.h>
|
||||
#include <QDebug>
|
||||
|
||||
RegessionCalculator::RegessionCalculator(const std::vector<double>& xValues, const std::vector<double>& yValues)
|
||||
{
|
||||
if(xValues.size() == yValues.size())
|
||||
{
|
||||
this->xValues = xValues;
|
||||
this->yValues = yValues;
|
||||
|
||||
double sumY = 0;
|
||||
double sumX = 0;
|
||||
double sumXTimesY = 0;
|
||||
double sumSquaredX = 0;
|
||||
double sumSquaredY = 0;
|
||||
for (unsigned i = 0; i < xValues.size(); i++)
|
||||
{
|
||||
sumY += yValues[i];
|
||||
sumX += xValues[i];
|
||||
sumSquaredX += xValues[i]*xValues[i];
|
||||
sumSquaredY += yValues[i]*yValues[i];
|
||||
sumXTimesY += xValues[i]*yValues[i];
|
||||
}
|
||||
|
||||
slope = (sumXTimesY - (sumX*sumY)/xValues.size()) / (sumSquaredX - (sumX*sumX)/xValues.size());
|
||||
offset = sumY/xValues.size() - slope*(sumX/xValues.size());
|
||||
|
||||
double error = (xValues.size()*sumSquaredY-sumY*sumY-slope*slope*(xValues.size()*sumSquaredX-sumX*sumX)) / (xValues.size()*(xValues.size()-2));
|
||||
stdError = sqrt( (error*error*xValues.size() ) / ( xValues.size()*sumSquaredX-sumX*sumX));
|
||||
}
|
||||
else throw std::invalid_argument("xValues and yValues need to be the same size");
|
||||
}
|
35
src/regessioncalculator.h
Normal file
35
src/regessioncalculator.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*UVOS*/
|
||||
|
||||
/* This file is part of MAClient copyright © 2021 Carl Philipp Klemm.
|
||||
*
|
||||
* MAClient is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License (GPL) version 3 as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* MAClient is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with MAClient. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef REGESSIONCALCULATOR_H
|
||||
#define REGESSIONCALCULATOR_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
class RegessionCalculator
|
||||
{
|
||||
public:
|
||||
std::vector<double> xValues;
|
||||
std::vector<double> yValues;
|
||||
|
||||
double slope;
|
||||
double offset;
|
||||
double stdError;
|
||||
|
||||
RegessionCalculator(const std::vector<double>& xValues, const std::vector<double>& yValues);
|
||||
};
|
||||
|
||||
#endif // REGESSIONCALCULATOR_H
|
39
src/ui/aboutdiag.cpp
Normal file
39
src/ui/aboutdiag.cpp
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*UVOS*/
|
||||
|
||||
/* This file is part of MAClient copyright © 2021 Carl Philipp Klemm.
|
||||
*
|
||||
* MAClient is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License (GPL) version
|
||||
* 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* MAClient is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with MAClient. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "aboutdiag.h"
|
||||
#include "ui_aboutdiag.h"
|
||||
#include <QPalette>
|
||||
|
||||
AboutDiag::AboutDiag(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::AboutDiag)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setFixedSize(size());
|
||||
|
||||
QPalette pal = palette();
|
||||
pal.setColor(QPalette::Window, QColor(52,52,60));
|
||||
pal.setColor(QPalette::WindowText, QColor(255,255,255));
|
||||
pal.setColor(QPalette::Text, QColor(255,255,255));
|
||||
setAutoFillBackground(true);
|
||||
setPalette(pal);
|
||||
}
|
||||
|
||||
AboutDiag::~AboutDiag()
|
||||
{
|
||||
delete ui;
|
||||
}
|
38
src/ui/aboutdiag.h
Normal file
38
src/ui/aboutdiag.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*UVOS*/
|
||||
|
||||
/* This file is part of MAClient copyright © 2021 Carl Philipp Klemm.
|
||||
*
|
||||
* MAClient is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License (GPL) version
|
||||
* 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* MAClient is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with MAClient. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef ABOUTTELSYS_H
|
||||
#define ABOUTTELSYS_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui {
|
||||
class AboutDiag;
|
||||
}
|
||||
|
||||
class AboutDiag : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit AboutDiag(QWidget *parent = 0);
|
||||
~AboutDiag();
|
||||
|
||||
private:
|
||||
Ui::AboutDiag *ui;
|
||||
};
|
||||
|
||||
#endif // ABOUTTELSYS_H
|
85
src/ui/aboutdiag.ui
Normal file
85
src/ui/aboutdiag.ui
Normal file
|
@ -0,0 +1,85 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>AboutDiag</class>
|
||||
<widget class="QDialog" name="AboutDiag">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>812</width>
|
||||
<height>315</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>80000</width>
|
||||
<height>15200</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>About</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>30</horstretch>
|
||||
<verstretch>50</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>800</width>
|
||||
<height>200</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="../../res/resources.qrc">:/images/splash.png</pixmap>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p><span style=" font-weight:600;">UVOS MAClient Version: 0.5</span></p><p>© 2021 Carl Philipp Klemm</p></body></html></string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../../res/resources.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -1,3 +1,19 @@
|
|||
/*UVOS*/
|
||||
|
||||
/* This file is part of MAClient copyright © 2021 Carl Philipp Klemm.
|
||||
*
|
||||
* MAClient is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License (GPL) version
|
||||
* 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* MAClient is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with MAClient. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "cameradialog.h"
|
||||
#include "ui_cameradialog.h"
|
||||
#include "../cameras.h"
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
/*UVOS*/
|
||||
|
||||
/* This file is part of MAClient copyright © 2021 Carl Philipp Klemm.
|
||||
*
|
||||
* MAClient is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License (GPL) version
|
||||
* 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* MAClient is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with MAClient. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef CAMERADIALOG_H
|
||||
#define CAMERADIALOG_H
|
||||
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
/*UVOS*/
|
||||
|
||||
/* This file is part of MAClient copyright © 2021 Carl Philipp Klemm.
|
||||
*
|
||||
* MAClient is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License (GPL) version
|
||||
* 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* MAClient is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with MAClient. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "cameralistwidget.h"
|
||||
#include <QDebug>
|
||||
#include <QHeaderView>
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
/*UVOS*/
|
||||
|
||||
/* This file is part of MAClient copyright © 2021 Carl Philipp Klemm.
|
||||
*
|
||||
* MAClient is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License (GPL) version
|
||||
* 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* MAClient is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with MAClient. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef CAMERALISTWIDGET_H
|
||||
#define CAMERALISTWIDGET_H
|
||||
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
/*UVOS*/
|
||||
|
||||
/* This file is part of MAClient copyright © 2021 Carl Philipp Klemm.
|
||||
*
|
||||
* MAClient is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License (GPL) version
|
||||
* 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* MAClient is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with MAClient. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "configurecameradialog.h"
|
||||
#include "ui_configurecameradialog.h"
|
||||
|
||||
|
@ -51,6 +67,9 @@ ConfigureCameraDialog::ConfigureCameraDialog(const CameraSetup& setup, std::shar
|
|||
break;
|
||||
}
|
||||
|
||||
ui->doubleSpinBoxGain->setValue(setup_.gain);
|
||||
|
||||
camera_->cam()->setGain(setup_.gain);
|
||||
camera_->cam()->setBayerMode(setup_.bayerMode);
|
||||
|
||||
uint64_t min, max;
|
||||
|
@ -70,6 +89,7 @@ ConfigureCameraDialog::ConfigureCameraDialog(const CameraSetup& setup, std::shar
|
|||
connect(ui->pushButtonBgShow, &QPushButton::clicked, [this](){if(setup_.bgmask.data) ui->widget_4->setImage(Camera::Image(setup_.bgmask, 0));});
|
||||
connect(ui->pushButtonDarkImageShow, &QPushButton::clicked, [this](){if(setup_.darkmap.data) ui->widget_4->setImage(Camera::Image(setup_.darkmap, 0));});
|
||||
connect(ui->comboBox_bayer, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &ConfigureCameraDialog::bayerIndexChanged);
|
||||
connect(ui->doubleSpinBoxGain, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &ConfigureCameraDialog::setExposure);
|
||||
|
||||
checkConfig();
|
||||
}
|
||||
|
@ -87,6 +107,15 @@ void ConfigureCameraDialog::setExposure(double value)
|
|||
qDebug()<<"set exposure to "<<value*1000000.0;
|
||||
}
|
||||
|
||||
void ConfigureCameraDialog::setGain(double value)
|
||||
{
|
||||
if(!camera_->cam()->setGain(value))
|
||||
QMessageBox::warning(this, "Warning", "Failed to set exposure");
|
||||
else
|
||||
qDebug()<<"set gain to "<<value;
|
||||
setup_.gain = value;
|
||||
}
|
||||
|
||||
void ConfigureCameraDialog::bayerIndexChanged(int index)
|
||||
{
|
||||
switch(index)
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
/*UVOS*/
|
||||
|
||||
/* This file is part of MAClient copyright © 2021 Carl Philipp Klemm.
|
||||
*
|
||||
* MAClient is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License (GPL) version
|
||||
* 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* MAClient is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with MAClient. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef CONFIGURECAMERADIALOG_H
|
||||
#define CONFIGURECAMERADIALOG_H
|
||||
|
||||
|
@ -36,6 +52,7 @@ private slots:
|
|||
void takeImage();
|
||||
void setExposure(double value);
|
||||
void bayerIndexChanged(int index);
|
||||
void setGain(double value);
|
||||
|
||||
public slots:
|
||||
void accept() override;
|
||||
|
|
|
@ -31,13 +31,10 @@
|
|||
<property name="horizontalSpacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="1" column="4">
|
||||
<widget class="QPushButton" name="pushButtonRemapClear">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<item row="3" column="3">
|
||||
<widget class="QPushButton" name="pushButtonBgCreate">
|
||||
<property name="text">
|
||||
<string>Clear</string>
|
||||
<string>Create</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -57,6 +54,33 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="3">
|
||||
<widget class="QPushButton" name="pushButtonDarkImageCreate">
|
||||
<property name="text">
|
||||
<string>Create</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="4">
|
||||
<widget class="QPushButton" name="pushButtonRemapClear">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Clear</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QPushButton" name="pushButtonDarkImageShow">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Show</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="4">
|
||||
<widget class="QPushButton" name="pushButtonDarkImageClear">
|
||||
<property name="enabled">
|
||||
|
@ -67,6 +91,27 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Dark image</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Remap Map (required)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QPushButton" name="pushButtonRemapCreate">
|
||||
<property name="text">
|
||||
<string>Create</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="Led" name="ledDark" native="true">
|
||||
<property name="sizePolicy">
|
||||
|
@ -83,58 +128,6 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Background image</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="3">
|
||||
<widget class="QPushButton" name="pushButtonBgCreate">
|
||||
<property name="text">
|
||||
<string>Create</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QPushButton" name="pushButtonRemapCreate">
|
||||
<property name="text">
|
||||
<string>Create</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Dark image</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="QPushButton" name="pushButtonBgShow">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Show</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Remap Map (required)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="3">
|
||||
<widget class="QPushButton" name="pushButtonDarkImageCreate">
|
||||
<property name="text">
|
||||
<string>Create</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="Led" name="ledRemap" native="true">
|
||||
<property name="sizePolicy">
|
||||
|
@ -151,16 +144,6 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QPushButton" name="pushButtonDarkImageShow">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Show</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="4">
|
||||
<widget class="QPushButton" name="pushButtonBgClear">
|
||||
<property name="enabled">
|
||||
|
@ -171,6 +154,33 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="QPushButton" name="pushButtonBgShow">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Show</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Background image</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Gain</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="3">
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBoxGain"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
/*UVOS*/
|
||||
|
||||
/* This file is part of MAClient copyright © 2021 Carl Philipp Klemm.
|
||||
*
|
||||
* MAClient is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License (GPL) version
|
||||
* 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* MAClient is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with MAClient. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "cvimageviewer.h"
|
||||
#include <QPicture>
|
||||
#include <QDebug>
|
||||
|
@ -10,22 +26,38 @@ CvImageViewer::CvImageViewer(QWidget *parent, size_t lastId) :
|
|||
QWidget(parent),
|
||||
lastId_(lastId),
|
||||
saveAction_("Save Image", nullptr),
|
||||
exportAction_("Export Image as PNG", nullptr),
|
||||
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");
|
||||
|
||||
connect(&saveAction_, &QAction::triggered, this, &CvImageViewer::saveImage);
|
||||
connect(&exportAction_, &QAction::triggered, this, &CvImageViewer::exportImage);
|
||||
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(&exportAction_);
|
||||
imageContextMenu_.addAction(&zoomAction_);
|
||||
imageContextMenu_.addAction(&resetAction_);
|
||||
imageContextMenu_.addAction(&statisticsAction_);
|
||||
imageContextMenu_.addAction(&xPlotAction_);
|
||||
imageContextMenu_.addAction(&yPlotAction_);
|
||||
|
||||
plot.setMinimumWidth(800);
|
||||
plot.setMinimumHeight(600);
|
||||
plot.setWindowIcon(windowIcon());
|
||||
plot.setWindowTitle(windowTitle());
|
||||
|
||||
setMouseTracking(true);
|
||||
}
|
||||
|
||||
CvImageViewer::~CvImageViewer()
|
||||
|
@ -34,39 +66,36 @@ CvImageViewer::~CvImageViewer()
|
|||
|
||||
void CvImageViewer::saveImage()
|
||||
{
|
||||
QString fileName;
|
||||
if(origImage_.type() == CV_8UC3 || origImage_.type() == CV_8SC3 || origImage_.type() == CV_8UC1 || origImage_.type() == CV_8SC1)
|
||||
{
|
||||
fileName = QFileDialog::getSaveFileName(this, "Save Image", "./", "*.mat *.png" );
|
||||
}
|
||||
else
|
||||
{
|
||||
fileName = QFileDialog::getSaveFileName(this, "Save Image", "./", "*.mat" );
|
||||
}
|
||||
QString fileName = QFileDialog::getSaveFileName(this, "Save Image", lastSavePath_, "*.mat" );
|
||||
if(!fileName.isEmpty())
|
||||
{
|
||||
lastSavePath_= fileName.mid(0, fileName.lastIndexOf('/'));
|
||||
QStringList tokens = fileName.split('.');
|
||||
if(tokens.back() != "mat" && tokens.back() != "png")
|
||||
if(tokens.back() != "mat")
|
||||
fileName.append(".mat");
|
||||
tokens = fileName.split('.');
|
||||
if(tokens.back() == "png")
|
||||
{
|
||||
imwrite(fileName.toStdString(), origImage_);
|
||||
}
|
||||
else
|
||||
{
|
||||
cv::FileStorage matf(fileName.toStdString(), cv::FileStorage::WRITE);
|
||||
matf<<"image"<<origImage_;
|
||||
matf.release();
|
||||
}
|
||||
cv::FileStorage matf(fileName.toStdString(), cv::FileStorage::WRITE);
|
||||
matf<<"image"<<origImage_;
|
||||
matf.release();
|
||||
}
|
||||
}
|
||||
|
||||
void CvImageViewer::showSatDiag()
|
||||
void CvImageViewer::exportImage()
|
||||
{
|
||||
if(origImage_.channels() > 1 || selectionRect_.width() < 2 || selectionRect_.height() < 2)
|
||||
if(!(origImage_.type() == CV_8UC3 || origImage_.type() == CV_8SC3 || origImage_.type() == CV_8UC1 || origImage_.type() == CV_8SC1))
|
||||
return;
|
||||
QString fileName = QFileDialog::getSaveFileName(this, "Save Image", lastSavePath_, "*.png" );
|
||||
if(!fileName.isEmpty())
|
||||
{
|
||||
lastSavePath_= fileName.mid(0, fileName.lastIndexOf('/'));
|
||||
QStringList tokens = fileName.split('.');
|
||||
if(tokens.back() != "png")
|
||||
fileName.append(".png");
|
||||
imwrite(fileName.toStdString(), origImage_);
|
||||
}
|
||||
}
|
||||
|
||||
cv::Rect CvImageViewer::roiFromSelection()
|
||||
{
|
||||
int xA;
|
||||
int yA;
|
||||
int xB;
|
||||
|
@ -74,9 +103,18 @@ 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;
|
||||
roi = cv::Rect(std::min(xA, xB), std::min(yA, yB), std::abs(xA-xB), std::abs(yA-yB));
|
||||
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 +130,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,11 +146,17 @@ 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);
|
||||
exportAction_.setDisabled(false);
|
||||
}
|
||||
else if(image_.type() == CV_8UC1 || image_.type() == CV_8SC1)
|
||||
{
|
||||
qimage_ = QImage(image_.data, image_.cols, image_.rows, image_.step, QImage::Format_Grayscale8);
|
||||
statisticsAction_.setDisabled(false);
|
||||
xPlotAction_.setDisabled(false);
|
||||
yPlotAction_.setDisabled(false);
|
||||
exportAction_.setDisabled(false);
|
||||
}
|
||||
else if(image_.type() == CV_32FC1 || image_.type() == CV_64FC1)
|
||||
{
|
||||
|
@ -128,6 +175,9 @@ 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);
|
||||
exportAction_.setDisabled(true);
|
||||
}
|
||||
else if(image_.type() == CV_32FC3 || image_.type() == CV_64FC3)
|
||||
{
|
||||
|
@ -142,18 +192,25 @@ 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);
|
||||
exportAction_.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);
|
||||
statisticsAction_.setDisabled(false);
|
||||
xPlotAction_.setDisabled(false);
|
||||
yPlotAction_.setDisabled(false);
|
||||
exportAction_.setDisabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
void CvImageViewer::setImage(Camera::Image img)
|
||||
{
|
||||
origImage_=img.mat;
|
||||
clamp_ = std::numeric_limits<double>::max();
|
||||
qDebug()<<"viwer got"<<image_.rows<<'x'<<image_.cols<<" type "<<image_.type()<<"image from camera"<<img.cameraId;
|
||||
convertImage(img.mat);
|
||||
update();
|
||||
|
@ -178,17 +235,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 +246,78 @@ void CvImageViewer::zoomToSelection()
|
|||
}
|
||||
}
|
||||
|
||||
void CvImageViewer::plotOnX()
|
||||
{
|
||||
if(!xLine_.isNull() && origImage_.data && (origImage_.type() == CV_32FC1 || origImage_.type() == CV_64FC1 || origImage_.type() == CV_8UC1))
|
||||
{
|
||||
cv::Mat plotImage;
|
||||
if(origImage_.type() == CV_8UC1)
|
||||
origImage_.convertTo(plotImage, CV_32FC1);
|
||||
else
|
||||
plotImage = origImage_;
|
||||
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 < plotImage.cols; ++i)
|
||||
{
|
||||
keys.push_back(i);
|
||||
double value;
|
||||
if(plotImage.type() == CV_32FC1)
|
||||
value = plotImage.at<float>(y, i);
|
||||
else
|
||||
value = plotImage.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 || origImage_.type() == CV_8UC1))
|
||||
{
|
||||
cv::Mat plotImage;
|
||||
if(origImage_.type() == CV_8UC1)
|
||||
origImage_.convertTo(plotImage, CV_32FC1);
|
||||
else
|
||||
plotImage = origImage_;
|
||||
plot.clear();
|
||||
QVector<double> keys;
|
||||
QVector<double> values;
|
||||
int x, y;
|
||||
transfromToSourceCoordinates(yLine_.p1().x(), yLine_.p1().y(), x, y);
|
||||
double max = 0;
|
||||
for(int i = 0; i < plotImage.rows; ++i)
|
||||
{
|
||||
keys.push_back(i);
|
||||
double value;
|
||||
if(plotImage.type() == CV_32FC1)
|
||||
value = plotImage.at<float>(i, x);
|
||||
else
|
||||
value = plotImage.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 +351,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 +406,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_);
|
||||
}
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
/*UVOS*/
|
||||
|
||||
/* This file is part of MAClient copyright © 2021 Carl Philipp Klemm.
|
||||
*
|
||||
* MAClient is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License (GPL) version
|
||||
* 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* MAClient is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with MAClient. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef CVIMAGEVIEWER_H
|
||||
#define CVIMAGEVIEWER_H
|
||||
|
||||
|
@ -7,6 +23,7 @@
|
|||
#include <QSlider>
|
||||
#include <limits>
|
||||
#include "../cameras.h"
|
||||
#include "plot.h"
|
||||
|
||||
class CvImageViewer : public QWidget
|
||||
{
|
||||
|
@ -19,24 +36,35 @@ private:
|
|||
bool fixedOnWidth_ = false;
|
||||
size_t lastId_;
|
||||
QMenu imageContextMenu_;
|
||||
Plot plot;
|
||||
QAction saveAction_;
|
||||
QAction exportAction_;
|
||||
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();
|
||||
inline 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 exportImage();
|
||||
void zoomToSelection();
|
||||
void resetZoom();
|
||||
void showSatDiag();
|
||||
void plotOnX();
|
||||
void plotOnY();
|
||||
|
||||
protected:
|
||||
virtual void paintEvent(QPaintEvent* event) override;
|
||||
|
@ -44,6 +72,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);
|
||||
|
@ -63,3 +92,4 @@ public:
|
|||
};
|
||||
|
||||
#endif // CVIMAGEVIEWER_H
|
||||
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
/*UVOS*/
|
||||
|
||||
/* This file is part of MAClient copyright © 2021 Carl Philipp Klemm.
|
||||
*
|
||||
* MAClient is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License (GPL) version
|
||||
* 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* MAClient is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with MAClient. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "editprofiledialog.h"
|
||||
#include "ui_editprofiledialog.h"
|
||||
#include <uvosled.h>
|
||||
|
@ -20,6 +36,7 @@ EditProfileDialog::EditProfileDialog(Cameras* cameras, const Profile profile, QW
|
|||
ui->lineEditName->setText(name);
|
||||
ui->doubleSpinBoxBrightness->setValue(profile_.lighting.brightness*100.0);
|
||||
ui->doubleSpinBoxExposure->setValue(profile_.exposureTime);
|
||||
ui->doubleSpinBox_kFactor->setValue(profile_.kFactor);
|
||||
|
||||
qDebug()<<"Mask: "<<profile_.lighting.mask<<" & "<<(profile_.lighting.mask & CHANNEL_A);
|
||||
|
||||
|
@ -50,6 +67,7 @@ EditProfileDialog::EditProfileDialog(Cameras* cameras, const Profile profile, QW
|
|||
|
||||
connect(ui->doubleSpinBoxBrightness, QOverload<double>::of(&QDoubleSpinBox::valueChanged), [this](double in){profile_.lighting.brightness = in/100.0;});
|
||||
connect(ui->doubleSpinBoxExposure, QOverload<double>::of(&QDoubleSpinBox::valueChanged), [this](double in){profile_.exposureTime = in;});
|
||||
connect(ui->doubleSpinBox_kFactor, QOverload<double>::of(&QDoubleSpinBox::valueChanged), [this](double in){profile_.kFactor = in;});
|
||||
connect(ui->lineEditName, &QLineEdit::textChanged, [this](QString in){profile_.setName(in);});
|
||||
connect(ui->checkBoxCh1, &QCheckBox::clicked, this, &EditProfileDialog::setMask);
|
||||
connect(ui->checkBoxCh2, &QCheckBox::clicked, this, &EditProfileDialog::setMask);
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
/*UVOS*/
|
||||
|
||||
/* This file is part of MAClient copyright © 2021 Carl Philipp Klemm.
|
||||
*
|
||||
* MAClient is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License (GPL) version
|
||||
* 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* MAClient is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with MAClient. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef EDDITPROFILEDIALOG_H
|
||||
#define EDDITPROFILEDIALOG_H
|
||||
|
||||
|
|
|
@ -192,25 +192,35 @@
|
|||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<property name="topMargin">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="text">
|
||||
<string>k factor:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_kFactor">
|
||||
<property name="minimum">
|
||||
<double>-100.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>100.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="topMargin">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Calibration curve:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>Lightmap:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="Led" name="calLed" native="true">
|
||||
<property name="sizePolicy">
|
||||
|
@ -227,6 +237,20 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QPushButton" name="pushButtonLightmapLoad">
|
||||
<property name="text">
|
||||
<string>Load</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>Lightmap:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QPushButton" name="pushButtonCalLoad">
|
||||
<property name="sizePolicy">
|
||||
|
@ -240,10 +264,17 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QPushButton" name="pushButtonLightmapLoad">
|
||||
<item row="0" column="3">
|
||||
<widget class="QPushButton" name="pushButtonCalClear">
|
||||
<property name="text">
|
||||
<string>Load</string>
|
||||
<string>Clear</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Calibration curve:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -263,13 +294,6 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QPushButton" name="pushButtonCalClear">
|
||||
<property name="text">
|
||||
<string>Clear</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QPushButton" name="pushButtonLightmapClear">
|
||||
<property name="text">
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
/*UVOS*/
|
||||
|
||||
/* This file is part of MAClient copyright © 2021 Carl Philipp Klemm.
|
||||
*
|
||||
* MAClient is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License (GPL) version
|
||||
* 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* MAClient is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with MAClient. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "led.h"
|
||||
#include <QPainter>
|
||||
|
||||
|
|
16
src/ui/led.h
16
src/ui/led.h
|
@ -1,3 +1,19 @@
|
|||
/*UVOS*/
|
||||
|
||||
/* This file is part of MAClient copyright © 2021 Carl Philipp Klemm.
|
||||
*
|
||||
* MAClient is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License (GPL) version
|
||||
* 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* MAClient is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with MAClient. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef LED_H
|
||||
#define LED_H
|
||||
|
||||
|
|
|
@ -1,9 +1,27 @@
|
|||
/*UVOS*/
|
||||
|
||||
/* This file is part of MAClient copyright © 2021 Carl Philipp Klemm.
|
||||
*
|
||||
* MAClient is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License (GPL) version
|
||||
* 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* MAClient is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with MAClient. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "mainwindow.h"
|
||||
#include "./ui_mainwindow.h"
|
||||
#include <QDebug>
|
||||
#include <QMessageBox>
|
||||
#include <uvosled.h>
|
||||
#include <QFileDialog>
|
||||
#include <opencv2/imgcodecs.hpp>
|
||||
#include <opencv2/imgproc.hpp>
|
||||
|
||||
#include "../profile.h"
|
||||
|
||||
|
@ -55,9 +73,10 @@ void MainWindow::saveImage()
|
|||
return;
|
||||
}
|
||||
|
||||
QString fileName = QFileDialog::getSaveFileName(this, "Save Image", "./", "*.mat");
|
||||
QString fileName = QFileDialog::getSaveFileName(this, "Save Image", lastSavedPath_, "*.mat");
|
||||
if(!fileName.isEmpty())
|
||||
{
|
||||
lastSavedPath_= fileName.mid(0, fileName.lastIndexOf('/'));
|
||||
QStringList tokens = fileName.split('.');
|
||||
if(tokens.back() != "mat")
|
||||
fileName.append(".mat");
|
||||
|
@ -69,33 +88,47 @@ void MainWindow::saveImage()
|
|||
|
||||
void MainWindow::openImage()
|
||||
{
|
||||
QString fileName = QFileDialog::getOpenFileName(this, "Open Image", "./", "*.mat");
|
||||
QString fileName = QFileDialog::getOpenFileName(this, "Open Image", lastSavedPath_, "*.mat *.png");
|
||||
if(!fileName.isEmpty())
|
||||
{
|
||||
cv::Mat image;
|
||||
cv::FileStorage matf(fileName.toStdString(), cv::FileStorage::READ);
|
||||
try
|
||||
QStringList tokens = fileName.split('.');
|
||||
if(tokens.back() == "png")
|
||||
{
|
||||
matf["image"]>>image;
|
||||
image = cv::imread(fileName.toStdString());
|
||||
if(image.data && image.channels() == 3)
|
||||
cv::cvtColor(image, image, cv::COLOR_BGR2GRAY);
|
||||
image.convertTo(image, CV_32FC1, 1.0/255.0, 0);
|
||||
}
|
||||
catch(const cv::Exception& ex)
|
||||
else
|
||||
{
|
||||
qDebug()<<ex.what();
|
||||
QMessageBox::warning(this, "Invalid file", "File selected dose not contain a valid image");
|
||||
return;
|
||||
}
|
||||
cv::FileStorage matf(fileName.toStdString(), cv::FileStorage::READ);
|
||||
try
|
||||
{
|
||||
matf["image"]>>image;
|
||||
}
|
||||
catch(const cv::Exception& ex)
|
||||
{
|
||||
qDebug()<<ex.what();
|
||||
QMessageBox::warning(this, "Invalid file", "File selected dose not contain a valid image");
|
||||
return;
|
||||
}
|
||||
|
||||
if(matf.isOpened() && (!image.data || image.type() != CV_32FC1))
|
||||
{
|
||||
image.release();
|
||||
QMessageBox::warning(this, "Invalid file", "File selected dose not contain a valid image");
|
||||
if(matf.isOpened() && !image.data)
|
||||
{
|
||||
image.release();
|
||||
QMessageBox::warning(this, "Invalid file", "File selected dose not contain a valid image");
|
||||
}
|
||||
matf.release();
|
||||
}
|
||||
else if(!image.data)
|
||||
if(!image.data)
|
||||
{
|
||||
QMessageBox::warning(this, "Can no open", "Can not open file selected");
|
||||
}
|
||||
matf.release();
|
||||
ui->mainViewer->setImage(Camera::Image(image, 0));
|
||||
else
|
||||
{
|
||||
ui->mainViewer->setImage(Camera::Image(image, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -166,6 +199,7 @@ void MainWindow::refreshProfiles()
|
|||
QList<QString> profiles = Profile::avaiableProfiles();
|
||||
for(const QString& string : profiles)
|
||||
ui->comboBox->addItem(string);
|
||||
setProfile(tmp);
|
||||
}
|
||||
|
||||
void MainWindow::profileInconpatible(QString message)
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
/*UVOS*/
|
||||
|
||||
/* This file is part of MAClient copyright © 2021 Carl Philipp Klemm.
|
||||
*
|
||||
* MAClient is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License (GPL) version
|
||||
* 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* MAClient is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with MAClient. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
|
||||
|
@ -16,7 +32,8 @@ class MainWindow : public QMainWindow
|
|||
Q_OBJECT
|
||||
private:
|
||||
std::vector<CvImageViewer*> viewers_;
|
||||
AboutDiag about_;
|
||||
AboutDiag about_;
|
||||
inline static QString lastSavedPath_ = "./";
|
||||
|
||||
private slots:
|
||||
void setImageValue(size_t x, size_t y, double value);
|
||||
|
|
308
src/ui/plot.cpp
Normal file
308
src/ui/plot.cpp
Normal file
|
@ -0,0 +1,308 @@
|
|||
/*UVOS*/
|
||||
|
||||
/* This file is part of MAClient copyright © 2021 Carl Philipp Klemm.
|
||||
*
|
||||
* MAClient is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License (GPL) version
|
||||
* 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* MAClient is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with MAClient. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "plot.h"
|
||||
|
||||
#include <QKeySequence>
|
||||
#include <QFont>
|
||||
|
||||
#include "statisticsdialog.h"
|
||||
#include "regressiondiag.h"
|
||||
|
||||
Plot::Plot(QWidget* parent):
|
||||
QCustomPlot(parent),
|
||||
actionStatistics("Show statistics", nullptr),
|
||||
actionAdd_Regression("Add regression", nullptr),
|
||||
actionDelete_Regression("Delete regression", nullptr),
|
||||
actionExport_Selection("Export selection", nullptr),
|
||||
actionSetValueString("Set Y Axis Label", nullptr),
|
||||
savePdfAction("Save to pdf", nullptr)
|
||||
{
|
||||
xAxis->setLabel("Coordinate");
|
||||
yAxis->setLabel("Counts");
|
||||
xAxis->setRange(0, 10);
|
||||
yAxis->setRange(0, 65535);
|
||||
addMainGraph();
|
||||
setInteraction(QCP::iSelectPlottables, true);
|
||||
setInteraction(QCP::iRangeDrag, true);
|
||||
setInteraction(QCP::iRangeZoom);
|
||||
axisRect()->setRangeDrag(Qt::Horizontal);
|
||||
axisRect()->setRangeZoom(Qt::Horizontal);
|
||||
setSelectionRectMode(QCP::srmNone);
|
||||
|
||||
//setup actions
|
||||
actionStatistics.setShortcut(Qt::Key_S);
|
||||
actionStatistics.setShortcutVisibleInContextMenu(true);
|
||||
addAction(&actionStatistics);
|
||||
|
||||
actionAdd_Regression.setShortcut(Qt::Key_R);
|
||||
actionAdd_Regression.setShortcutVisibleInContextMenu(true);
|
||||
addAction(&actionAdd_Regression);
|
||||
|
||||
actionDelete_Regression.setShortcut(Qt::Key_Delete);
|
||||
actionDelete_Regression.setShortcutVisibleInContextMenu(true);
|
||||
addAction(&actionDelete_Regression);
|
||||
|
||||
actionExport_Selection.setShortcut(Qt::CTRL + Qt::Key_E);
|
||||
actionExport_Selection.setShortcutVisibleInContextMenu(true);
|
||||
addAction(&actionExport_Selection);
|
||||
|
||||
//graph context menu
|
||||
|
||||
connect(&actionStatistics, &QAction::triggered, this, &Plot::showStatistics);
|
||||
connect(&actionAdd_Regression, &QAction::triggered, this, &Plot::addRegression);
|
||||
connect(&actionDelete_Regression, &QAction::triggered, this, &Plot::deleteRegression);
|
||||
connect(&actionExport_Selection, &QAction::triggered, this, &Plot::saveCsvDiag);
|
||||
connect(&actionSetValueString, &QAction::triggered, this, &Plot::askForValueString);
|
||||
connect(&savePdfAction, &QAction::triggered, this, &Plot::savePdf);
|
||||
|
||||
graphContextMenu.addAction(&actionStatistics);
|
||||
graphContextMenu.addAction(&actionAdd_Regression);
|
||||
graphContextMenu.addAction(&actionDelete_Regression);
|
||||
graphContextMenu.addAction(&actionExport_Selection);
|
||||
graphContextMenu.addAction(&actionSetValueString);
|
||||
graphContextMenu.addAction(&savePdfAction);
|
||||
}
|
||||
|
||||
Plot::~Plot()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Plot::savePdf()
|
||||
{
|
||||
QString fileName = QFileDialog::getSaveFileName(this, "Save graph as PDF", "./", "*.pdf" );
|
||||
|
||||
if(!fileName.isEmpty())
|
||||
QCustomPlot::savePdf(fileName);
|
||||
}
|
||||
|
||||
bool Plot::event(QEvent *event)
|
||||
{
|
||||
if(event->type()==QEvent::Gesture) graphContextMenu.show();
|
||||
return QCustomPlot::event(event);
|
||||
}
|
||||
|
||||
void Plot::setLabel(QString label)
|
||||
{
|
||||
yAxis->setLabel(label);
|
||||
}
|
||||
|
||||
void Plot::addMainGraph()
|
||||
{
|
||||
addGraph();
|
||||
graph(graphCount()-1)->setSelectable(QCP::stDataRange);
|
||||
graph(graphCount()-1)->setPen(QPen(QBrush(QColor(0,0,255,255)),2,Qt::SolidLine));
|
||||
QPen selectionPen = graph(graphCount()-1)->pen();
|
||||
selectionPen.setColor(QColor(255,0,0));
|
||||
graph(graphCount()-1)->selectionDecorator()->setPen(selectionPen);
|
||||
|
||||
}
|
||||
|
||||
void Plot::clear()
|
||||
{
|
||||
clearGraphs();
|
||||
addMainGraph();
|
||||
xAxis->setRange(0, 10);
|
||||
replot();
|
||||
}
|
||||
|
||||
void Plot::askForValueString()
|
||||
{
|
||||
bool ok = false;
|
||||
QString label = QInputDialog::getText(this, "Y Axis Label", "New Label:", QLineEdit::Normal, yAxis->label(), &ok);
|
||||
if(ok)
|
||||
{
|
||||
setLabel(label);
|
||||
replot();
|
||||
}
|
||||
}
|
||||
|
||||
void Plot::setMaxValue(double maxVal)
|
||||
{
|
||||
yAxis->setRange(0, maxVal);
|
||||
}
|
||||
|
||||
void Plot::saveCsvDiag()
|
||||
{
|
||||
if(graphCount() > 0 && !graph(0)->selection().dataRanges().at(0).isEmpty())
|
||||
{
|
||||
QString fileName = QFileDialog::getSaveFileName(this, "Save selection as CSV", "./", "*.csv" );
|
||||
saveCsv(fileName);
|
||||
}
|
||||
else QMessageBox::warning(this, "Warning", "No selection has been made", QMessageBox::Ok);
|
||||
}
|
||||
|
||||
void Plot::saveCsv(QString fileName)
|
||||
{
|
||||
if(!fileName.isEmpty())
|
||||
{
|
||||
QCPDataRange range = graph(0)->selection().dataRanges().at(0);
|
||||
QCPGraphDataContainer::const_iterator begin = graph(0)->data()->at(range.begin());
|
||||
QCPGraphDataContainer::const_iterator end = graph(0)->data()->at(range.end());
|
||||
|
||||
std::vector<double> keys;
|
||||
keys.resize(end-begin);
|
||||
|
||||
std::vector<double> values;
|
||||
values.resize(end-begin);
|
||||
|
||||
for (QCPGraphDataContainer::const_iterator item=begin; item != end; ++item)
|
||||
{
|
||||
keys[item-begin]=item->key;
|
||||
values[item-begin]=item->value;
|
||||
}
|
||||
saveToCsv(fileName, keys, values, xAxis->label(), yAxis->label());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Plot::addRegression()
|
||||
{
|
||||
if(graphCount() > 0 && !graph(0)->selection().dataRanges().at(0).isEmpty())
|
||||
{
|
||||
QCPDataRange range = graph(0)->selection().dataRanges().at(0);
|
||||
QCPGraphDataContainer::const_iterator begin = graph(0)->data()->at(range.begin());
|
||||
QCPGraphDataContainer::const_iterator end = graph(0)->data()->at(range.end());
|
||||
|
||||
std::vector<double> values;
|
||||
std::vector<double> keys;
|
||||
|
||||
values.resize(end-begin);
|
||||
keys.resize(end-begin);
|
||||
|
||||
for (QCPGraphDataContainer::const_iterator item=begin; item != end; ++item)
|
||||
{
|
||||
values[item-begin] = item->value;
|
||||
keys[item-begin] = item->key;
|
||||
}
|
||||
|
||||
regressions.push_back(RegessionCalculator(keys, values));
|
||||
|
||||
QPen regressionPen =graph(0)->pen();
|
||||
regressionPen.setColor(QColor(0,255,0));
|
||||
|
||||
QPen selectionPen = graph(0)->pen();
|
||||
selectionPen.setColor(QColor(255,0,0));
|
||||
|
||||
QCPGraphDataContainer::const_iterator center = begin + (end - begin)/2;
|
||||
|
||||
addGraph();
|
||||
graph(graphCount()-1)->setPen(regressionPen);
|
||||
graph(graphCount()-1)->addData(100+center->key, regressions.back().slope*(100+center->key) + regressions.back().offset);
|
||||
graph(graphCount()-1)->addData(-100+center->key, regressions.back().slope*(-100+center->key) + regressions.back().offset);
|
||||
graph(graphCount()-1)->selectionDecorator()->setPen(selectionPen);
|
||||
replot();
|
||||
|
||||
}
|
||||
else QMessageBox::warning(this, "Warning", "No selection has been made", QMessageBox::Ok);
|
||||
}
|
||||
|
||||
void Plot::deleteRegression()
|
||||
{
|
||||
if(graphCount() > 0 && selectedGraphs().size() > 1 && selectedGraphs().at(1) != graph(0))
|
||||
{
|
||||
int i = 0;
|
||||
while(selectedGraphs().at(1) != graph(i) ) i++;
|
||||
regressions.erase(regressions.begin()+i-1);
|
||||
removeGraph(selectedGraphs().at(1));
|
||||
replot();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Plot::showStatistics()
|
||||
{
|
||||
if(graphCount() > 0 && !graph(0)->selection().dataRanges().isEmpty() && !graph(0)->selection().dataRanges().at(0).isEmpty())
|
||||
{
|
||||
QCPDataRange dataRange = graph(0)->selection().dataRanges().at(0);
|
||||
QCPGraphDataContainer::const_iterator begin = graph(0)->data()->at(dataRange.begin());
|
||||
QCPGraphDataContainer::const_iterator end = graph(0)->data()->at(dataRange.end());
|
||||
std::vector<double> dataVct;
|
||||
dataVct.reserve(dataRange.size());
|
||||
for (QCPGraphDataContainer::const_iterator item = begin; item != end; item++)
|
||||
dataVct.push_back(item->value);
|
||||
StatisticsDialog statDiag(dataVct, this);
|
||||
statDiag.show();
|
||||
statDiag.exec();
|
||||
}
|
||||
else if(graphCount() > 0 && selectedGraphs().size() > 0 && selectedGraphs().at(0) != graph(0))
|
||||
{
|
||||
unsigned i = 0;
|
||||
while(selectedGraphs().at(0) != graph(i)) i++;
|
||||
RegressionDiag regDiag(regressions.at(i-1), this);
|
||||
regDiag.show();
|
||||
regDiag.exec();
|
||||
}
|
||||
else QMessageBox::warning(this, "Warning", "No selection has been made", QMessageBox::Ok);
|
||||
}
|
||||
|
||||
void Plot::addData(QVector<double> keys, QVector<double> values, bool inOrder, bool ignoreLimit)
|
||||
{
|
||||
if(graphCount() > 0)
|
||||
{
|
||||
graph(0)->addData(keys, values, inOrder);
|
||||
if(!ignoreLimit)while(graph(0)->data()->size() > graphPointLimit) graph(0)->data()->remove(graph(0)->data()->begin()->key);
|
||||
xAxis->setRange( graph(0)->data()->begin()->key, keys.back() );
|
||||
replot();
|
||||
}
|
||||
}
|
||||
|
||||
void Plot::addData(double key, double value, bool ignoreLimit)
|
||||
{
|
||||
if(graphCount() > 0)
|
||||
{
|
||||
graph(0)->addData(key, value);
|
||||
if(!ignoreLimit)while(graph(0)->data()->size() > graphPointLimit) graph(0)->data()->remove(graph(0)->data()->begin()->key);
|
||||
xAxis->setRange( graph(0)->data()->begin()->key, key );
|
||||
}
|
||||
}
|
||||
|
||||
void Plot::setLimit(int graphPointLimit)
|
||||
{
|
||||
this->graphPointLimit = graphPointLimit;
|
||||
if(graphCount() > 0) while(graph(0)->data()->size() > graphPointLimit) graph(0)->data()->remove(graph(0)->data()->begin()->key);
|
||||
}
|
||||
|
||||
int Plot::getLimit()
|
||||
{
|
||||
return graphPointLimit;
|
||||
}
|
||||
|
||||
void Plot::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if(event->button() == Qt::MiddleButton || (event->button() == Qt::LeftButton && event->modifiers() == Qt::Modifier::SHIFT) )
|
||||
{
|
||||
setCursor(Qt::ClosedHandCursor);
|
||||
setSelectionRectMode(QCP::srmNone);
|
||||
}
|
||||
else if(event->button() == Qt::LeftButton)
|
||||
{
|
||||
setSelectionRectMode(QCP::srmSelect);
|
||||
}
|
||||
else if(event->button() == Qt::RightButton)
|
||||
{
|
||||
graphContextMenu.popup(event->globalPos());
|
||||
setSelectionRectMode(QCP::srmNone);
|
||||
}
|
||||
QCustomPlot::mousePressEvent(event);
|
||||
}
|
||||
|
||||
void Plot::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
setCursor(Qt::ArrowCursor);
|
||||
QCustomPlot::mouseReleaseEvent(event);
|
||||
}
|
84
src/ui/plot.h
Normal file
84
src/ui/plot.h
Normal file
|
@ -0,0 +1,84 @@
|
|||
/*UVOS*/
|
||||
|
||||
/* This file is part of MAClient copyright © 2021 Carl Philipp Klemm.
|
||||
*
|
||||
* MAClient is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License (GPL) version
|
||||
* 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* MAClient is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with MAClient. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef PLOT_H
|
||||
#define PLOT_H
|
||||
|
||||
#include<QVector>
|
||||
#include<QAction>
|
||||
#include<QWidget>
|
||||
|
||||
#include "qcustomplot/qcustomplot.h"
|
||||
#include "regessioncalculator.h"
|
||||
#include "statisticsdialog.h"
|
||||
#include "utilites.h"
|
||||
|
||||
class Plot : public QCustomPlot
|
||||
{
|
||||
private:
|
||||
std::vector<RegessionCalculator> regressions;
|
||||
|
||||
QMenu graphContextMenu;
|
||||
|
||||
int graphPointLimit = 10000;
|
||||
QAction actionStatistics;
|
||||
QAction actionAdd_Regression;
|
||||
QAction actionDelete_Regression;
|
||||
QAction actionExport_Selection;
|
||||
QAction actionSetValueString;
|
||||
QAction savePdfAction;
|
||||
|
||||
private slots:
|
||||
void savePdf();
|
||||
|
||||
public:
|
||||
Plot(QWidget* parent = nullptr);
|
||||
~Plot();
|
||||
|
||||
void setLabel(QString label);
|
||||
|
||||
void clear();
|
||||
void setLimit(int graphPointLimit);
|
||||
int getLimit();
|
||||
|
||||
void setMaxValue(double maxVal);
|
||||
|
||||
signals:
|
||||
void sigSaveCsv();
|
||||
|
||||
public slots:
|
||||
void addPoints(QVector<double> keys, QVector<double> values);
|
||||
void saveCsv(QString fileName);
|
||||
void saveCsvDiag();
|
||||
void showStatistics();
|
||||
void deleteRegression();
|
||||
void addRegression();
|
||||
void askForValueString();
|
||||
|
||||
void addData(QVector<double> keys, QVector<double> values, bool inOrder = false, bool ignoreLimit = false);
|
||||
void addData(double key, double value, bool ignoreLimit = false);
|
||||
|
||||
protected:
|
||||
virtual void mousePressEvent(QMouseEvent *event);
|
||||
virtual void mouseReleaseEvent(QMouseEvent *event);
|
||||
virtual bool event(QEvent *event);
|
||||
|
||||
private:
|
||||
void addMainGraph();
|
||||
};
|
||||
|
||||
#endif // PLOT_H
|
||||
|
|
@ -1,3 +1,19 @@
|
|||
/*UVOS*/
|
||||
|
||||
/* This file is part of MAClient copyright © 2021 Carl Philipp Klemm.
|
||||
*
|
||||
* MAClient is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License (GPL) version
|
||||
* 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* MAClient is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with MAClient. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "profiledialog.h"
|
||||
#include "ui_profiledialog.h"
|
||||
#include "editprofiledialog.h"
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
/*UVOS*/
|
||||
|
||||
/* This file is part of MAClient copyright © 2021 Carl Philipp Klemm.
|
||||
*
|
||||
* MAClient is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License (GPL) version
|
||||
* 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* MAClient is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with MAClient. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef PROFILEDIALOG_H
|
||||
#define PROFILEDIALOG_H
|
||||
|
||||
|
|
40
src/ui/regressiondiag.cpp
Normal file
40
src/ui/regressiondiag.cpp
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*UVOS*/
|
||||
|
||||
/* This file is part of MAClient copyright © 2021 Carl Philipp Klemm.
|
||||
*
|
||||
* MAClient is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License (GPL) version
|
||||
* 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* MAClient is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with MAClient. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "regressiondiag.h"
|
||||
#include "ui_regressiondiag.h"
|
||||
|
||||
RegressionDiag::RegressionDiag(const RegessionCalculator& reg, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::RegressionDiag)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
ui->lcdNumber_slope->display(reg.slope);
|
||||
ui->lcdNumber_offset->display(reg.offset);
|
||||
ui->lcdNumber_StdError->display(reg.stdError);
|
||||
ui->lcdNumbe_count->display((int)reg.xValues.size());
|
||||
|
||||
#ifdef Q_OS_ANDROID
|
||||
setWindowState(Qt::WindowMaximized);
|
||||
#endif
|
||||
}
|
||||
|
||||
RegressionDiag::~RegressionDiag()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
40
src/ui/regressiondiag.h
Normal file
40
src/ui/regressiondiag.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*UVOS*/
|
||||
|
||||
/* This file is part of MAClient copyright © 2021 Carl Philipp Klemm.
|
||||
*
|
||||
* MAClient is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License (GPL) version
|
||||
* 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* MAClient is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with MAClient. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef REGRESSIONDIAG_H
|
||||
#define REGRESSIONDIAG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#include "regessioncalculator.h"
|
||||
|
||||
namespace Ui {
|
||||
class RegressionDiag;
|
||||
}
|
||||
|
||||
class RegressionDiag : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit RegressionDiag(const RegessionCalculator& reg, QWidget *parent = 0);
|
||||
~RegressionDiag();
|
||||
|
||||
private:
|
||||
Ui::RegressionDiag *ui;
|
||||
};
|
||||
|
||||
#endif // REGRESSIONDIAG_H
|
160
src/ui/regressiondiag.ui
Normal file
160
src/ui/regressiondiag.ui
Normal file
|
@ -0,0 +1,160 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>RegressionDiag</class>
|
||||
<widget class="QDialog" name="RegressionDiag">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>377</width>
|
||||
<height>208</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Regression</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Slope:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLCDNumber" name="lcdNumber_slope">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="digitCount">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<property name="value" stdset="0">
|
||||
<double>99999999.000000000000000</double>
|
||||
</property>
|
||||
<property name="intValue" stdset="0">
|
||||
<number>99999999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLCDNumber" name="lcdNumber_offset">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="digitCount">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<property name="value" stdset="0">
|
||||
<double>99999999.000000000000000</double>
|
||||
</property>
|
||||
<property name="intValue" stdset="0">
|
||||
<number>99999999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Slope standard error:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLCDNumber" name="lcdNumber_StdError">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="smallDecimalPoint">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="digitCount">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<property name="value" stdset="0">
|
||||
<double>99999999.000000000000000</double>
|
||||
</property>
|
||||
<property name="intValue" stdset="0">
|
||||
<number>99999999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Offset:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Count:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLCDNumber" name="lcdNumbe_count">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="digitCount">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<property name="intValue" stdset="0">
|
||||
<number>99999999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>RegressionDiag</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>RegressionDiag</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
98
src/ui/statisticsdialog.cpp
Normal file
98
src/ui/statisticsdialog.cpp
Normal file
|
@ -0,0 +1,98 @@
|
|||
/*UVOS*/
|
||||
|
||||
/* This file is part of MAClient copyright © 2021 Carl Philipp Klemm.
|
||||
*
|
||||
* MAClient is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License (GPL) version
|
||||
* 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* MAClient is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with MAClient. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "statisticsdialog.h"
|
||||
#include "ui_statisticsdialog.h"
|
||||
|
||||
#include <QClipboard>
|
||||
#include <limits>
|
||||
#include <cmath>
|
||||
|
||||
StatisticsDialog::StatisticsDialog(const std::vector<double>& data, QWidget *parent):
|
||||
QDialog(parent),
|
||||
ui(new Ui::StatisticsDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
connect(ui->pushButton_1, &QPushButton::clicked, this, &StatisticsDialog::copyCount);
|
||||
connect(ui->pushButton_4, &QPushButton::clicked, this, &StatisticsDialog::copyMean);
|
||||
connect(ui->pushButton_5, &QPushButton::clicked, this, &StatisticsDialog::copyMinMax);
|
||||
connect(ui->pushButton_Sd, &QPushButton::clicked, this, &StatisticsDialog::copySd);
|
||||
|
||||
ui->lcdNumber_Count->display(static_cast<double>(data.size()));
|
||||
|
||||
double mean = 0;
|
||||
double max = std::numeric_limits<double>::min();
|
||||
double min = std::numeric_limits<double>::max();
|
||||
for(double point : data)
|
||||
{
|
||||
mean += point;
|
||||
if(point < min)
|
||||
min = point;
|
||||
if(point > max)
|
||||
max = point;
|
||||
}
|
||||
mean = mean / data.size();
|
||||
ui->lcdNumber_Mean->display(mean);
|
||||
|
||||
double sd = 0;
|
||||
for(double point : data)
|
||||
{
|
||||
sd += (point - mean)*(point - mean);
|
||||
}
|
||||
sd /= data.size();
|
||||
sd = sqrt(sd);
|
||||
ui->lcdNumber_Sd->display(sd);
|
||||
|
||||
ui->lcdNumber_Max->display(max);
|
||||
ui->lcdNumber_Min->display(min);
|
||||
}
|
||||
|
||||
void StatisticsDialog::copyCount()
|
||||
{
|
||||
QString buffer(QString::number(ui->lcdNumber_Count->value(), 'g', 10));
|
||||
QGuiApplication::clipboard()->setText(buffer, QClipboard::Clipboard);
|
||||
QGuiApplication::clipboard()->setText(buffer, QClipboard::Selection);
|
||||
}
|
||||
|
||||
void StatisticsDialog::copyMean()
|
||||
{
|
||||
QString buffer(QString::number(ui->lcdNumber_Mean->value(), 'g', 10));
|
||||
QGuiApplication::clipboard()->setText(buffer, QClipboard::Clipboard);
|
||||
QGuiApplication::clipboard()->setText(buffer, QClipboard::Selection);
|
||||
}
|
||||
|
||||
void StatisticsDialog::copyMinMax()
|
||||
{
|
||||
QString buffer(QString::number(ui->lcdNumber_Min->value(), 'g', 10));
|
||||
buffer.append(",");
|
||||
buffer.append(QString::number(ui->lcdNumber_Max->value(), 'g', 10));
|
||||
QGuiApplication::clipboard()->setText(buffer, QClipboard::Clipboard);
|
||||
QGuiApplication::clipboard()->setText(buffer, QClipboard::Selection);
|
||||
}
|
||||
|
||||
void StatisticsDialog::copySd()
|
||||
{
|
||||
QString buffer(QString::number(ui->lcdNumber_Sd->value(), 'g', 10));
|
||||
QGuiApplication::clipboard()->setText(buffer, QClipboard::Clipboard);
|
||||
QGuiApplication::clipboard()->setText(buffer, QClipboard::Selection);
|
||||
}
|
||||
|
||||
StatisticsDialog::~StatisticsDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
45
src/ui/statisticsdialog.h
Normal file
45
src/ui/statisticsdialog.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*UVOS*/
|
||||
|
||||
/* This file is part of MAClient copyright © 2021 Carl Philipp Klemm.
|
||||
*
|
||||
* MAClient is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License (GPL) version
|
||||
* 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* MAClient is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with MAClient. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef STATISTICSDIALOG_H
|
||||
#define STATISTICSDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <vector>
|
||||
|
||||
namespace Ui {
|
||||
class StatisticsDialog;
|
||||
}
|
||||
|
||||
class StatisticsDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit StatisticsDialog(const std::vector<double>& data, QWidget *parent = 0);
|
||||
~StatisticsDialog();
|
||||
|
||||
private slots:
|
||||
void copyCount();
|
||||
void copyMean();
|
||||
void copyMinMax();
|
||||
void copySd();
|
||||
|
||||
private:
|
||||
Ui::StatisticsDialog *ui;
|
||||
};
|
||||
|
||||
#endif // STATISTICSDIALOG_H
|
269
src/ui/statisticsdialog.ui
Normal file
269
src/ui/statisticsdialog.ui
Normal file
|
@ -0,0 +1,269 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>StatisticsDialog</class>
|
||||
<widget class="QDialog" name="StatisticsDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>491</width>
|
||||
<height>201</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Statistics</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Count:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLCDNumber" name="lcdNumber_Count">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="digitCount">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="segmentStyle">
|
||||
<enum>QLCDNumber::Flat</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_1">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Copy</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Geometric mean:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLCDNumber" name="lcdNumber_Mean">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="digitCount">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="segmentStyle">
|
||||
<enum>QLCDNumber::Flat</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_4">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Copy</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Standard deviation:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLCDNumber" name="lcdNumber_Sd">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="digitCount">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="segmentStyle">
|
||||
<enum>QLCDNumber::Flat</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_Sd">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Copy</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Maximum:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLCDNumber" name="lcdNumber_Max">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="digitCount">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="segmentStyle">
|
||||
<enum>QLCDNumber::Flat</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Minimum:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLCDNumber" name="lcdNumber_Min">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="digitCount">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="segmentStyle">
|
||||
<enum>QLCDNumber::Flat</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_5">
|
||||
<property name="text">
|
||||
<string>Copy</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>StatisticsDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>StatisticsDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
49
src/utilites.cpp
Normal file
49
src/utilites.cpp
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*UVOS*/
|
||||
|
||||
/* This file is part of MAClient copyright © 2021 Carl Philipp Klemm.
|
||||
*
|
||||
* MAClient is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License (GPL) version
|
||||
* 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* MAClient is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with MAClient. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "utilites.h"
|
||||
|
||||
#include <vector>
|
||||
#include <QTextStream>
|
||||
#include <QFile>
|
||||
#include <QDebug>
|
||||
#include <QStringList>
|
||||
#include <QMessageBox>
|
||||
#include <thread>
|
||||
#include <stdexcept>
|
||||
|
||||
bool saveToCsv(const QString& filename, const std::vector<double> &keys, const std::vector<double> &values, const QString& keyLable, const QString& valueLable )
|
||||
{
|
||||
if(keys.size() != values.size())
|
||||
{
|
||||
throw std::invalid_argument("keys and values need to be the same size");
|
||||
return false;
|
||||
}
|
||||
QFile file(filename);
|
||||
if(file.open(QIODevice::WriteOnly | QIODevice::Text))
|
||||
{
|
||||
QTextStream fileStream(&file);
|
||||
fileStream<<"id"<<','<<keyLable<<','<<valueLable<<'\n';
|
||||
for(size_t i = 0; i < keys.size(); i++)
|
||||
{
|
||||
fileStream<<i<<','<<(int64_t)keys[i]<<','<<values[i]<<'\n';
|
||||
}
|
||||
fileStream.flush();
|
||||
file.close();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
27
src/utilites.h
Normal file
27
src/utilites.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*UVOS*/
|
||||
|
||||
/* This file is part of MAClient copyright © 2021 Carl Philipp Klemm.
|
||||
*
|
||||
* MAClient is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License (GPL) version
|
||||
* 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* MAClient is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with MAClient. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef UTILITYS_H
|
||||
#define UTILITYS_H
|
||||
|
||||
#include <QString>
|
||||
#include <stdint.h>
|
||||
#include <array>
|
||||
|
||||
bool saveToCsv(const QString& filename, const std::vector<double> &keys, const std::vector<double> &values, const QString& keyLable, const QString& valueLable);
|
||||
|
||||
|
||||
#endif // UTILITYS_H
|
Loading…
Reference in a new issue