From 0c466644cebeb49204f6978a418df1ca38395a7f Mon Sep 17 00:00:00 2001 From: uvos Date: Sat, 12 Jun 2021 15:17:35 +0200 Subject: [PATCH] Finish up --- CMakeLists.txt | 3 + src/cameras.cpp | 11 ++ src/cameras.h | 1 + src/imagepipeline.cpp | 1 + src/main.cpp | 45 +++++- src/profile.cpp | 73 ++++++++- src/profile.h | 8 +- src/ui/cameradialog.ui | 9 +- src/ui/cameralistwidget.cpp | 6 +- src/ui/configurecameradialog.cpp | 186 +++++++++++++++++++++ src/ui/configurecameradialog.h | 49 ++++++ src/ui/configurecameradialog.ui | 270 +++++++++++++++++++++++++++++++ src/ui/cvimageviewer.cpp | 23 ++- src/ui/editprofiledialog.cpp | 99 +++++++++++- src/ui/editprofiledialog.h | 13 +- src/ui/editprofiledialog.ui | 174 ++++++++++---------- src/ui/led.cpp | 9 +- src/ui/mainwindow.cpp | 29 +++- src/ui/mainwindow.h | 3 + src/ui/mainwindow.ui | 42 +---- src/ui/profiledialog.cpp | 50 +++++- src/ui/profiledialog.h | 1 + src/ui/profiledialog.ui | 7 + 23 files changed, 958 insertions(+), 154 deletions(-) create mode 100644 src/ui/configurecameradialog.cpp create mode 100644 src/ui/configurecameradialog.h create mode 100644 src/ui/configurecameradialog.ui diff --git a/CMakeLists.txt b/CMakeLists.txt index 6c8b95f..b738e7e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,6 +45,9 @@ set(PROJECT_SOURCES src/ui/led.h src/ui/cameralistwidget.h src/ui/cameralistwidget.cpp + src/ui/configurecameradialog.cpp + src/ui/configurecameradialog.h + src/ui/configurecameradialog.ui ) diff --git a/src/cameras.cpp b/src/cameras.cpp index 54ad345..1351ad3 100644 --- a/src/cameras.cpp +++ b/src/cameras.cpp @@ -41,6 +41,17 @@ std::vector Cameras::getCameras() return desc; } +std::shared_ptr Cameras::getCamera(size_t id) +{ + std::vector desc = getCameras(); + for(size_t i = 0; i < desc.size(); ++i) + { + if(desc[i].getHash() == id) + return cameras_[i]; + } + return std::shared_ptr(nullptr); +} + bool Cameras::addCamera(const cam::Camera::Description& desc) { cameras_.push_back(std::shared_ptr(new Camera(desc))); diff --git a/src/cameras.h b/src/cameras.h index 097b44b..44056fd 100644 --- a/src/cameras.h +++ b/src/cameras.h @@ -49,6 +49,7 @@ public: bool setCameras(const std::vector& descriptions); bool addCamera(const cam::Camera::Description& desc); std::vector getCameras(); + std::shared_ptr getCamera(size_t id); size_t numCameras(){return cameras_.size();} void clear(); Cameras(uvosled* led = nullptr); diff --git a/src/imagepipeline.cpp b/src/imagepipeline.cpp index 53fe1ed..469aca7 100644 --- a/src/imagepipeline.cpp +++ b/src/imagepipeline.cpp @@ -72,3 +72,4 @@ void ImagePipeline::imageFinished() } } } + diff --git a/src/main.cpp b/src/main.cpp index efbc8c5..430ea56 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -8,28 +8,47 @@ #include #include #include +#include #include "cameras.h" #include "./ui/cameradialog.h" #include "profile.h" #include "./ui/mainwindow.h" +#include "./ui/profiledialog.h" #include "imagepipeline.h" const char* organziation = "UVOS"; const char* application = "UVOS"; const char* version = "UVOS"; -std::vector showCameraSelectionDialog() +std::vector showCameraSelectionDialog(bool* accepted = nullptr) { std::vector ret; CameraDialog diag(cam::Camera::getAvailableCameras()); diag.show(); if(diag.exec() == QDialog::Accepted) + { ret = diag.getDescriptions(); + if(accepted) + *accepted = true; + } + else if(accepted) + { + *accepted = false; + } return ret; } +void showProfileDialog(Cameras* cameras) +{ + qDebug()<<__FUNCTION__; + cameras->stop(); + ProfileDialog diag(cameras); + diag.show(); + diag.exec(); +} + int main(int argc, char *argv[]) { QApplication a(argc, argv); @@ -53,6 +72,14 @@ int main(int argc, char *argv[]) uvosled led; int uvosledRet = uvosled_connect(&led); + if(uvosledRet >= 0) + { + uvosled_poweron(&led); + // Give cameras some time to power on + // TODO: figure out how to do this better + sleep(10); + } + Cameras cameras(uvosledRet < 0 ? nullptr : &led); ImagePipeline pipe(&cameras); @@ -61,7 +88,16 @@ int main(int argc, char *argv[]) QObject::connect(&cameras, &Cameras::cameraAdded, &w, &MainWindow::addCamera); QObject::connect(&cameras, &Cameras::cameraRemoved, &w, &MainWindow::removeCamera); QObject::connect(&w, &MainWindow::sigCapture, [&cameras](){cameras.start(); cameras.trigger();}); - QObject::connect(&w, &MainWindow::sigChooseCameras, [&cameras](){cameras.setCameras(showCameraSelectionDialog());}); + + QObject::connect(&w, &MainWindow::sigChooseCameras, [&cameras]() + { + bool accepted; + std::vector descs = showCameraSelectionDialog(&accepted); + if(accepted) + cameras.setCameras(descs); + }); + + QObject::connect(&w, &MainWindow::sigEditProfiles, [&cameras, &w](){showProfileDialog(&cameras); w.refreshProfiles();}); QObject::connect(&pipe, &ImagePipeline::sigResult, w.mainImageViewer(), &CvImageViewer::setImage, Qt::QueuedConnection); QObject::connect(&w, &MainWindow::sigProfile, [&pipe](QString name) @@ -85,9 +121,14 @@ int main(int argc, char *argv[]) cameras.setCameras(showCameraSelectionDialog()); } + pipe.setProfile(w.getProfileName()); + int ret = a.exec(); cameras.store(settings); + if(uvosledRet >= 0) + uvosled_poweroff(&led); + return ret; } diff --git a/src/profile.cpp b/src/profile.cpp index 0db67b5..971a656 100644 --- a/src/profile.cpp +++ b/src/profile.cpp @@ -3,16 +3,46 @@ #include #include #include +#include +#include void CameraSetup::store() const { - cv::imwrite((camerasLocation() + QString::number(id) + ".darkmap.png").toStdString(), darkmap); + if(darkmap.data) + cv::imwrite(darkmapLocation(id).toStdString(), darkmap); + if(remapMap.xMat.data) + saveRemapMap(remapMap, remapMapLocation(id).toStdString()); + if(bgmask.data) + { + cv::FileStorage matf(bgmaskLocation(id).toStdString(), cv::FileStorage::WRITE); + matf<<"bgmask"<>bgmask; + matf.release(); +} + +void CameraSetup::loadRemapMaps(const QString &filename) +{ + remapMap = loadRemapMap(filename.toStdString()); } void CameraSetup::load(size_t cameraId) { id = cameraId; - darkmap = cv::imread((camerasLocation() + QString::number(id) + ".darkmap.png").toStdString()); + loadDarkMap(darkmapLocation(id)); + loadRemapMaps(remapMapLocation(id)); + loadBgMask(bgmaskLocation(id)); } QString CameraSetup::camerasLocation() @@ -20,6 +50,21 @@ QString CameraSetup::camerasLocation() return QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/cameras/"; } +QString CameraSetup::darkmapLocation(size_t cameraId) +{ + return camerasLocation() + QString::number(cameraId) + ".darkmap.png"; +} + +QString CameraSetup::bgmaskLocation(size_t cameraId) +{ + return camerasLocation() + QString::number(cameraId) + "bgmask.mat"; +} + +QString CameraSetup::remapMapLocation(size_t cameraId) +{ + return camerasLocation() + QString::number(cameraId) + "remap.mat"; +} + void LightingSetup::store(QSettings& settings) const { settings.setValue(GROUP + QString("/brightness"), brightness); @@ -29,17 +74,19 @@ void LightingSetup::store(QSettings& settings) const void LightingSetup::load(const QSettings& settings) { brightness = settings.value(GROUP + QString("/brightness"), 0.25).toDouble(); - mask = settings.value(GROUP + QString("/maks"), 0).toUInt(); + mask = settings.value(GROUP + QString("/mask"), 0).toUInt(); } void Profile::store(QSettings& settings) const { + qDebug()<<"storing to "<(id)); settings.setValue(GROUP + QString("/exposureTime"), exposureTime); settings.setValue(GROUP + QString("/name"), name_); - cv::imwrite((profileLocation() + QString::number(id) + ".lightmap.png").toStdString(), lightmap); + if(lightmap.data) + cv::imwrite((profileLocation() + QString::number(id) + ".lightmap.png").toStdString(), lightmap); settings.beginWriteArray(GROUP + QString("/cameras"), cameras.size()); for(size_t i = 0; i < cameras.size(); ++i) @@ -73,16 +120,18 @@ void Profile::load(QSettings &settings) void Profile::load(const QString& name) { - QSettings settings(profileLocation() + name + ".profile.ini"); + qDebug()< Profile::avaiableProfiles() return ret; } +void Profile::setCamerasSetupsFromDescription(const std::vector& desc) +{ + cameras.clear(); + cameras.reserve(desc.size()); + for(size_t i = 0; i < desc.size(); ++i) + { + CameraSetup tmp; + tmp.load(desc[i].getHash()); + cameras.push_back(tmp); + } +} + bool Profile::camerasSufficant(const std::vector& desc) const { bool invalid = false; diff --git a/src/profile.h b/src/profile.h index 52d2634..561787d 100644 --- a/src/profile.h +++ b/src/profile.h @@ -18,6 +18,9 @@ public: cv::Mat bgmask; void store() const; void load(size_t cameraId); + void loadBgMask(const QString& filename); + void loadDarkMap(const QString& filename); + void loadRemapMaps(const QString& filename); static QString camerasLocation(); static QString remapMapLocation(size_t cameraId); static QString bgmaskLocation(size_t cameraId); @@ -40,7 +43,7 @@ class Profile { static constexpr const char* GROUP = "Profile"; - QString name_ = "NULL"; + QString name_; public: uint64_t id; @@ -49,7 +52,7 @@ public: cv::Mat lightmap; std::vector cameras; - Profile(const QString& name = "NULL"); + Profile(const QString& name = "Unamed"); void store(QSettings& settings) const; void store(const QString& name); void store(); @@ -58,6 +61,7 @@ public: void load(); void deleteProfile(); void setName(const QString name){name_=name;} + void setCamerasSetupsFromDescription(const std::vector& desc); QString getName() const {return name_;} bool camerasSufficant(const std::vector& desc) const; static QList avaiableProfiles(); diff --git a/src/ui/cameradialog.ui b/src/ui/cameradialog.ui index 96c452d..b01d46c 100644 --- a/src/ui/cameradialog.ui +++ b/src/ui/cameradialog.ui @@ -27,13 +27,6 @@ - - - - Configure Cameras - - - @@ -50,7 +43,7 @@ CameraListWidget QListView -
cameralistwidget.h
+
./src/ui/cameralistwidget.h
diff --git a/src/ui/cameralistwidget.cpp b/src/ui/cameralistwidget.cpp index 4eadda9..d7e1dc8 100644 --- a/src/ui/cameralistwidget.cpp +++ b/src/ui/cameralistwidget.cpp @@ -11,6 +11,7 @@ CameraListWidget::CameraListWidget(QWidget* parent): QTableWidget(parent) setHorizontalHeaderItem(0, new QTableWidgetItem("Camera")); setRowCount(desc_.size()); horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); + setEditTriggers(QAbstractItemView::NoEditTriggers); } void CameraListWidget::setConfigured(std::vector configured) @@ -18,7 +19,10 @@ void CameraListWidget::setConfigured(std::vector configured) setColumnCount(2); setHorizontalHeaderItem(1, new QTableWidgetItem("Configured")); for(size_t i = 0; i < desc_.size() && i < configured.size(); ++i) - setItem(static_cast(i), 0, new QTableWidgetItem("No")); + { + setItem(static_cast(i), 1, new QTableWidgetItem("No")); + qDebug()<<"Set item "<& desc) diff --git a/src/ui/configurecameradialog.cpp b/src/ui/configurecameradialog.cpp new file mode 100644 index 0000000..b7622c0 --- /dev/null +++ b/src/ui/configurecameradialog.cpp @@ -0,0 +1,186 @@ +#include "configurecameradialog.h" +#include "ui_configurecameradialog.h" + +#include +#include +#include +#include +#include +#include + +ConfigureCameraDialog::ConfigureCameraDialog(const CameraSetup& setup, std::shared_ptr camera, double exposureTime, QWidget *parent): + QDialog(parent), + setup_(setup), + camera_(camera), + ui(new Ui::ConfigureCameraDialog) +{ + ui->setupUi(this); + + ui->doubleSpinBox->setValue(exposureTime); + + connect(ui->pushButtonBgLoad, &QPushButton::clicked, this, &ConfigureCameraDialog::loadBg); + connect(ui->pushButtonRemapLoad, &QPushButton::clicked, this, &ConfigureCameraDialog::loadRemap); + connect(ui->pushButtonDarkImageLoad, &QPushButton::clicked, this, &ConfigureCameraDialog::loadDark); + connect(ui->pushButtonBgClear, &QPushButton::clicked, [this](){setup_.bgmask.release(); checkConfig();}); + connect(ui->pushButtonRemapClear, &QPushButton::clicked, [this](){setup_.remapMap = RemapMap(); checkConfig();}); + connect(ui->pushButtonDarkImageClear, &QPushButton::clicked, [this](){setup_.darkmap.release(); checkConfig();}); + connect(ui->pushButtonBgCreate, &QPushButton::clicked, this, &ConfigureCameraDialog::captureBg); + connect(ui->pushButtonRemapCreate, &QPushButton::clicked, this, &ConfigureCameraDialog::captureRemap); + connect(ui->pushButtonDarkImageCreate, &QPushButton::clicked, this, &ConfigureCameraDialog::captureDark); + connect(ui->pushButtonCapture, &QPushButton::clicked, this, &ConfigureCameraDialog::takeImage); + connect(camera_.get(), &Camera::newImage, this, &ConfigureCameraDialog::gotImage); + + checkConfig(); +} + +ConfigureCameraDialog::~ConfigureCameraDialog() +{ + delete ui; +} + + + +void ConfigureCameraDialog::loadBg() +{ + QString filename = QFileDialog::getOpenFileName(this, tr("Open Background Mask"), CameraSetup::camerasLocation(), "OpenCV Mat (*.mat)"); + if(!filename.isEmpty()) + { + setup_.loadBgMask(filename); + if(!setup_.bgmask.data) + QMessageBox::warning(this, "Warning", "Could not load " + filename); + checkConfig(); + } +} + +void ConfigureCameraDialog::loadRemap() +{ + QString filename = QFileDialog::getOpenFileName(this, tr("Open Background Mask"), CameraSetup::camerasLocation(), "OpenCV Mat (*.mat)"); + if(!filename.isEmpty()) + { + setup_.loadRemapMaps(filename); + if(!setup_.remapMap.xMat.data || !setup_.remapMap.yMat.data) + { + QMessageBox::warning(this, "Warning", "Could not load " + filename); + setup_.remapMap = RemapMap(); + } + checkConfig(); + } +} + +void ConfigureCameraDialog::loadDark() +{ + QString filename = QFileDialog::getOpenFileName(this, tr("Open Background Mask"), CameraSetup::camerasLocation(), "Image (*.png)"); + if(!filename.isEmpty()) + { + setup_.loadDarkMap(filename); + if(!setup_.darkmap.data) + QMessageBox::warning(this, "Warning", "Could not load " + filename); + checkConfig(); + } +} + +void ConfigureCameraDialog::gotImage(Camera::Image img) +{ + switch(mode_) + { + case MODE_IDLE: + ui->widget_4->setImage(img); + break; + case MODE_BG_GET: + if(!fgImage.data) + { + QMessageBox::information(this, "Remove object", "please remove the item from the sphere"); + fgImage = img.mat; + takeImage(); + } + else + { + if(!createMask(img.mat, setup_.bgmask, fgImage)) + QMessageBox::warning(this, "Failed", "Unable to create mask from captured images"); + else + ui->widget_4->setImage(Camera::Image(setup_.bgmask, camera_->id())); + fgImage.release(); + mode_ = MODE_IDLE; + } + break; + case MODE_DARK_GET: + setup_.darkmap = img.mat; + ui->widget_4->setImage(Camera::Image(setup_.darkmap, camera_->id())); + mode_ = MODE_IDLE; + break; + case MODE_REMAP_GET: + std::vector points = detectCharucoPoints(img.mat, false); + if(points.size() < 8) + { + QMessageBox::warning(this, "Failed", "Error creating map, insufficant points detected."); + mode_ = MODE_IDLE; + break; + } + RemapMap map; + if(createRemapMap(img.mat, map, points)) + setup_.remapMap = map; + else + QMessageBox::warning(this, "Failed", "Error creating map"); + for(size_t i = 0; i < points.size(); ++i) + cv::circle(img.mat, points[i].point, 5, cv::Scalar(0,255,0), 1); + ui->widget_4->setImage(Camera::Image(setup_.bgmask, camera_->id())); + mode_ = MODE_IDLE; + break; + } + checkConfig(); +} + +void ConfigureCameraDialog::takeImage() +{ + camera_->cam()->setExposureTime(ui->doubleSpinBox->value()); + camera_->cam()->setAcquisitionMode(cam::Camera::MODE_SINGLE); + camera_->cam()->setTriggerMode(cam::Camera::TRIGGER_SOFTWARE); + camera_->cam()->startAcquisition(); + camera_->cam()->trigger(); +} + +void ConfigureCameraDialog::captureBg() +{ + QMessageBox::information(this, "Insert object", "Please insert Test Article A"); + mode_ = MODE_BG_GET; + takeImage(); +} + +void ConfigureCameraDialog::captureRemap() +{ + QMessageBox::information(this, "Insert object", "Please insert Test Article A."); + mode_ = MODE_REMAP_GET; + takeImage(); +} + +void ConfigureCameraDialog::captureDark() +{ + QMessageBox::information(this, "Cover lense", "Please cover the lense of the camera."); + mode_ = MODE_DARK_GET; + takeImage(); +} + +void ConfigureCameraDialog::accept() +{ + if(checkConfig()) + QDialog::accept(); + else + QMessageBox::warning(this, "Unfinished", "Can not accept unfinished camera setup"); +} + +bool ConfigureCameraDialog::checkConfig() +{ + bool bgOk = setup_.bgmask.data; + bool remapMapOk = setup_.remapMap.xMat.data; + bool darkMapOK = setup_.darkmap.data; + + ui->pushButtonBgClear->setEnabled(bgOk); + ui->pushButtonDarkImageClear->setEnabled(darkMapOK); + ui->pushButtonRemapClear->setEnabled(remapMapOk); + + ui->ledBg->setLit(bgOk); + ui->ledDark->setLit(darkMapOK); + ui->ledRemap->setLit(remapMapOk); + + return bgOk && remapMapOk && darkMapOK; +} diff --git a/src/ui/configurecameradialog.h b/src/ui/configurecameradialog.h new file mode 100644 index 0000000..ec5d60f --- /dev/null +++ b/src/ui/configurecameradialog.h @@ -0,0 +1,49 @@ +#ifndef CONFIGURECAMERADIALOG_H +#define CONFIGURECAMERADIALOG_H + +#include +#include "cameras.h" +#include "profile.h" + +namespace Ui { +class ConfigureCameraDialog; +} + +class ConfigureCameraDialog : public QDialog +{ + Q_OBJECT + + static constexpr int MODE_IDLE = 0; + static constexpr int MODE_REMAP_GET = 1; + static constexpr int MODE_BG_GET = 2; + static constexpr int MODE_DARK_GET = 3; + + CameraSetup setup_; + std::shared_ptr camera_; + int mode_ = MODE_IDLE; + cv::Mat fgImage; + +private: + bool checkConfig(); + void gotImage(Camera::Image img); + +private slots: + void loadBg(); + void loadRemap(); + void loadDark(); + void captureBg(); + void captureRemap(); + void captureDark(); + void takeImage(); + +public: + explicit ConfigureCameraDialog(const CameraSetup& setup, const std::shared_ptr camera, double exposureTime = 1.0/60, QWidget *parent = nullptr); + ~ConfigureCameraDialog(); + CameraSetup getCameraSetup(){return setup_;} + void accept() override; + +private: + Ui::ConfigureCameraDialog *ui; +}; + +#endif // CONFIGURECAMERADIALOG_H diff --git a/src/ui/configurecameradialog.ui b/src/ui/configurecameradialog.ui new file mode 100644 index 0000000..4bf1a50 --- /dev/null +++ b/src/ui/configurecameradialog.ui @@ -0,0 +1,270 @@ + + + ConfigureCameraDialog + + + + 0 + 0 + 466 + 438 + + + + Configure Camera + + + + + + Camera output + + + + + + + + + + + + 6 + + + + + Dark image + + + + + + + false + + + Clear + + + + + + + Background image + + + + + + + Create + + + + + + + false + + + Clear + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + + + + false + + + Clear + + + + + + + Create + + + + + + + + + + Remap Map + + + + + + + Load + + + + + + + Load + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + + + + Load + + + + + + + Create + + + + + + + + + + + + + + + + 5 + + + + + Exposure Time for Map creation + + + + + + + 1.000000000000000 + + + 0.100000000000000 + + + + + + + s + + + + + + + Test Exposure + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + Led + QWidget +
./src/ui/led.h
+ 1 +
+ + CvImageViewer + QWidget +
./src/ui/cvimageviewer.h
+ 1 +
+
+ + + + buttonBox + accepted() + ConfigureCameraDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + ConfigureCameraDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + +
diff --git a/src/ui/cvimageviewer.cpp b/src/ui/cvimageviewer.cpp index 150161f..8d380c7 100644 --- a/src/ui/cvimageviewer.cpp +++ b/src/ui/cvimageviewer.cpp @@ -17,11 +17,23 @@ void CvImageViewer::setImage(Camera::Image img) { image_ = img.mat; if(image_.type() == CV_8UC3 || image_.type() == CV_8SC3) + { qimage_ = QImage(image_.data, image_.cols, image_.rows, image_.step, QImage::Format_RGB888); + } else if(image_.type() == CV_8UC1 || image_.type() == CV_8SC1) + { qimage_ = QImage(image_.data, image_.cols, image_.rows, image_.step, QImage::Format_Grayscale8); + } else if(image_.type() == CV_32FC1 || image_.type() == CV_64FC1) + { img.mat.convertTo(image_, CV_8UC1, 255, 0); + qimage_ = QImage(image_.data, image_.cols, image_.rows, image_.step, QImage::Format_Grayscale8); + } + else + { + img.mat.convertTo(image_, CV_8UC1, 255, 0); + qimage_ = QImage(image_.data, image_.cols, image_.rows, image_.step, QImage::Format_Grayscale8); + } update(); } @@ -29,8 +41,15 @@ void CvImageViewer::paintEvent(QPaintEvent* event) { Q_UNUSED(event) QPainter painter(this); + if(!fixedOnWidth_) - painter.drawImage(QRect((rect().width()-rect().height())/2, rect().y(), rect().height(), rect().height()), qimage_); + { + double ratio = qimage_.size().width() / qimage_.size().height(); + painter.drawImage(QRect((rect().width()-rect().height())/2, rect().y(), rect().height()*ratio, rect().height()), qimage_); + } else - painter.drawImage(QRect(rect().x(), (rect().height()-rect().width())/2, rect().width(), rect().width()), qimage_); + { + double ratio = qimage_.size().height() / qimage_.size().width(); + painter.drawImage(QRect(rect().x(), (rect().height()-rect().width())/2, rect().width(), rect().width()*ratio), qimage_); + } } diff --git a/src/ui/editprofiledialog.cpp b/src/ui/editprofiledialog.cpp index a1776ec..0bdaf99 100644 --- a/src/ui/editprofiledialog.cpp +++ b/src/ui/editprofiledialog.cpp @@ -1,13 +1,110 @@ #include "editprofiledialog.h" #include "ui_editprofiledialog.h" +#include +#include -EditProfileDialog::EditProfileDialog(Cameras* cameras, Profile* profile, QWidget *parent) : +#include "configurecameradialog.h" + +EditProfileDialog::EditProfileDialog(Cameras* cameras, const Profile profile, QWidget *parent) : QDialog(parent), profile_(profile), cameras_(cameras), ui(new Ui::EditProfileDialog) { ui->setupUi(this); + + ui->lineEditName->setText(profile_.getName()); + ui->doubleSpinBoxBrightness->setValue(profile_.lighting.brightness*100.0); + ui->doubleSpinBoxExposure->setValue(profile_.exposureTime); + + qDebug()<<"Mask: "<checkBoxCh1->setChecked(profile_.lighting.mask & CHANNEL_A); + ui->checkBoxCh2->setChecked(profile_.lighting.mask & CHANNEL_B); + ui->checkBoxCh3->setChecked(profile_.lighting.mask & CHANNEL_C); + ui->checkBoxCh4->setChecked(profile_.lighting.mask & CHANNEL_D); + + if(profile_.cameras.size() == 0) + profile_.setCamerasSetupsFromDescription(cameras_->getCameras()); + + connect(ui->doubleSpinBoxBrightness, QOverload::of(&QDoubleSpinBox::valueChanged), [this](double in){profile_.lighting.brightness = in/100.0;}); + connect(ui->doubleSpinBoxExposure, QOverload::of(&QDoubleSpinBox::valueChanged), [this](double in){profile_.exposureTime = 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); + connect(ui->checkBoxCh3, &QCheckBox::clicked, this, &EditProfileDialog::setMask); + connect(ui->checkBoxCh4, &QCheckBox::clicked, this, &EditProfileDialog::setMask); + connect(ui->pushButton, &QPushButton::clicked, this, &EditProfileDialog::configureCamera); + ui->listView->setCameras(cameras_->getCameras()); + ui->listView->setSelectionMode(QAbstractItemView::SingleSelection); + setConfigured(); +} + +void EditProfileDialog::setConfigured() +{ + std::vector descs = cameras_->getCameras(); + std::vector configured(descs.size(), false); + + for(size_t i = 0; i< profile_.cameras.size(); ++i) + { + auto& profileCamera = profile_.cameras[i]; + if(profileCamera.remapMap.xMat.data) + { + for(auto& camera : descs) + { + if(camera.getHash() == profileCamera.id) + configured[i] = true; + } + } + } + ui->listView->setConfigured(configured); +} + +void EditProfileDialog::invalidateCameras() +{ + for(size_t i = 0; i< profile_.cameras.size(); ++i) + { + profile_.cameras[i].bgmask.release(); + profile_.cameras[i].remapMap.xMat.release(); + profile_.cameras[i].remapMap.yMat.release(); + profile_.cameras[i].darkmap.release(); + } + setConfigured(); +} + +void EditProfileDialog::configureCamera() +{ + std::vector descs = ui->listView->getSelectedDescriptions(); + qDebug()<<"descs"< camera = cameras_->getCamera(profile_.cameras[i].id); + if(camera) + { + ConfigureCameraDialog diag(profile_.cameras[i], camera, profile_.exposureTime, this); + diag.show(); + int ret = diag.exec(); + if(ret == QDialog::Accepted) + profile_.cameras[i] = diag.getCameraSetup(); + } + } + } + } +} + +void EditProfileDialog::setMask() +{ + uint8_t mask = (ui->checkBoxCh1->isChecked() ? CHANNEL_A : 0) | + (ui->checkBoxCh2->isChecked() ? CHANNEL_B : 0) | + (ui->checkBoxCh3->isChecked() ? CHANNEL_C : 0) | + (ui->checkBoxCh4->isChecked() ? CHANNEL_D : 0); + profile_.lighting.mask = mask; + invalidateCameras(); } EditProfileDialog::~EditProfileDialog() diff --git a/src/ui/editprofiledialog.h b/src/ui/editprofiledialog.h index 3e4f858..5bfc50c 100644 --- a/src/ui/editprofiledialog.h +++ b/src/ui/editprofiledialog.h @@ -12,13 +12,20 @@ class EditProfileDialog; class EditProfileDialog : public QDialog { Q_OBJECT - Profile* profile_; + Profile profile_; Cameras* cameras_; + void setConfigured(); + void invalidateCameras(); + +private slots: + + void setMask(); + void configureCamera(); public: - explicit EditProfileDialog(Cameras* cameras, Profile* profile, QWidget *parent = nullptr); - Profile* getProfile(){return profile_;} + explicit EditProfileDialog(Cameras* cameras, const Profile profile = Profile(), QWidget *parent = nullptr); + Profile getProfile(){return profile_;} ~EditProfileDialog(); private: diff --git a/src/ui/editprofiledialog.ui b/src/ui/editprofiledialog.ui index 01d78d3..7e9783b 100644 --- a/src/ui/editprofiledialog.ui +++ b/src/ui/editprofiledialog.ui @@ -11,7 +11,7 @@
- Dialog + Profile @@ -24,10 +24,99 @@
- + + + Unamed + + + + + + Lights + + + + + + + + + 0 + 0 + + + + Brightness + + + + + + + 100.000000000000000 + + + + + + + + 0 + 0 + + + + % + + + + + + + + + Channels: + + + + + + + + + CH1 + + + + + + + CH2 + + + + + + + CH3 + + + + + + + CH4 + + + + + + + + @@ -90,87 +179,6 @@ - - - - Lights - - - - - - - - - 0 - 0 - - - - Brightness - - - - - - - - - - - 0 - 0 - - - - % - - - - - - - - - Channels: - - - - - - - - - CH1 - - - - - - - CH2 - - - - - - - CH3 - - - - - - - CH4 - - - - - - - - diff --git a/src/ui/led.cpp b/src/ui/led.cpp index 378a6de..b329698 100644 --- a/src/ui/led.cpp +++ b/src/ui/led.cpp @@ -3,6 +3,8 @@ Led::Led(QWidget* parent): QWidget(parent) { + setMinimumSize(QSize(40,40)); + setSizePolicy(QSizePolicy::Policy::Fixed, QSizePolicy::Policy::Fixed); } bool Led::lit() const @@ -24,8 +26,11 @@ void Led::paintEvent(QPaintEvent* event) { Q_UNUSED(event) QPainter ledPainter(this); + ledPainter.setRenderHint(QPainter::Antialiasing, true); ledPainter.setPen(Qt::black); - if(lit_) ledPainter.setBrush(Qt::red); - else ledPainter.setBrush(Qt::NoBrush); + if(lit_) + ledPainter.setBrush(Qt::green); + else + ledPainter.setBrush(Qt::red); ledPainter.drawEllipse(rect().adjusted(0, 0, -1, -1)); } diff --git a/src/ui/mainwindow.cpp b/src/ui/mainwindow.cpp index b02ff82..7782173 100644 --- a/src/ui/mainwindow.cpp +++ b/src/ui/mainwindow.cpp @@ -14,9 +14,9 @@ MainWindow::MainWindow(QWidget *parent) ui->statusbar->showMessage("idle"); connect(ui->actionQuit, &QAction::triggered, [this](bool checked){(void)checked; close();}); connect(ui->actionCameras, &QAction::triggered, [this](bool checked){(void)checked; sigChooseCameras();}); + connect(ui->actionProfile, &QAction::triggered, [this](bool checked){(void)checked; sigEditProfiles();}); connect(ui->comboBox, &QComboBox::currentTextChanged, this, &MainWindow::sigProfile); connect(ui->pushButtonCapture, &QPushButton::clicked, this, &MainWindow::sigCapture); - ui->widget->setLit(true); refreshProfiles(); } @@ -42,6 +42,33 @@ void MainWindow::removeCamera(std::shared_ptr camera) } } +bool MainWindow::setProfile(const QString& profileName) +{ + ui->comboBox->clear(); + QList profiles = Profile::avaiableProfiles(); + int selected = -1; + for(int i = 0; i < profiles.size(); ++i) + { + if(profileName == profiles[i]) + selected = i; + ui->comboBox->addItem(profiles[i]); + } + if(selected != -1) + { + ui->comboBox->setCurrentIndex(selected); + return true; + } + else + { + return false; + } +} + +QString MainWindow::getProfileName() +{ + return ui->comboBox->currentText(); +} + void MainWindow::refreshProfiles() { ui->comboBox->clear(); diff --git a/src/ui/mainwindow.h b/src/ui/mainwindow.h index 0fb0b3f..5fd0f33 100644 --- a/src/ui/mainwindow.h +++ b/src/ui/mainwindow.h @@ -20,6 +20,7 @@ signals: void sigCapture(); void sigProfile(QString profileName); void sigChooseCameras(); + void sigEditProfiles(); public slots: @@ -27,6 +28,8 @@ public slots: void refreshProfiles(); void profileInconpatible(QString message); void removeCamera(std::shared_ptr camera); + bool setProfile(const QString& profileName); + QString getProfileName(); public: MainWindow(QWidget *parent = nullptr); diff --git a/src/ui/mainwindow.ui b/src/ui/mainwindow.ui index f334112..3ae254c 100644 --- a/src/ui/mainwindow.ui +++ b/src/ui/mainwindow.ui @@ -68,7 +68,7 @@ 0 0 467 - 315 + 353 @@ -124,36 +124,6 @@ - - - - 0 - - - - - - 0 - 0 - - - - - 30 - 30 - - - - - - - - Uncal - - - - - @@ -184,7 +154,7 @@ Settings - + @@ -200,7 +170,7 @@ Cameras - + Profile @@ -212,12 +182,6 @@ - - Led - QWidget -
./src/ui/led.h
- 1 -
CvImageViewer QWidget diff --git a/src/ui/profiledialog.cpp b/src/ui/profiledialog.cpp index 7a29b77..c6fdaec 100644 --- a/src/ui/profiledialog.cpp +++ b/src/ui/profiledialog.cpp @@ -2,6 +2,8 @@ #include "ui_profiledialog.h" #include "editprofiledialog.h" +#include + ProfileDialog::ProfileDialog(Cameras* cameras, QWidget *parent) : QDialog(parent), cameras_(cameras), @@ -9,6 +11,9 @@ ProfileDialog::ProfileDialog(Cameras* cameras, QWidget *parent) : { ui->setupUi(this); ui->listWidget->addItems(Profile::avaiableProfiles()); + connect(ui->pushButtonAdd, &QPushButton::clicked, this, &ProfileDialog::addProfile); + connect(ui->pushButtonEdit, &QPushButton::clicked, this, &ProfileDialog::editProfile); + connect(ui->pushButtonDelete, &QPushButton::clicked, this, &ProfileDialog::deleteProfile); } @@ -19,19 +24,56 @@ ProfileDialog::~ProfileDialog() void ProfileDialog::editProfile() { - + QList items = ui->listWidget->selectedItems(); + if(items.size() > 0) + { + Profile profile; + profile.load(items[0]->text()); + if(!profile.camerasSufficant(cameras_->getCameras())) + { + QMessageBox::critical(this, "Profile Incompatible", "Not all cameras need for this profile are available"); + return; + } + EditProfileDialog dialog(cameras_, profile); + dialog.show(); + int ret = dialog.exec(); + if(ret == QDialog::Accepted) + { + dialog.getProfile().store(); + ui->listWidget->clear(); + ui->listWidget->addItems(Profile::avaiableProfiles()); + } + } } +void ProfileDialog::deleteProfile() +{ + QList items = ui->listWidget->selectedItems(); + if(items.size() > 0) + { + Profile profile(items[0]->text()); + profile.deleteProfile(); + ui->listWidget->clear(); + ui->listWidget->addItems(Profile::avaiableProfiles()); + } +} void ProfileDialog::addProfile() { - Profile newProfile; - EditProfileDialog dialog(cameras_, &newProfile); + if(cameras_->getCameras().size() == 0) + { + QMessageBox::critical(this, "No Cameras", "At least one camera is needed to create a profile"); + return; + } + + EditProfileDialog dialog(cameras_); dialog.show(); int ret = dialog.exec(); if(ret == QDialog::Accepted) { - + dialog.getProfile().store(); + ui->listWidget->clear(); + ui->listWidget->addItems(Profile::avaiableProfiles()); } } diff --git a/src/ui/profiledialog.h b/src/ui/profiledialog.h index 99be760..a4679c7 100644 --- a/src/ui/profiledialog.h +++ b/src/ui/profiledialog.h @@ -17,6 +17,7 @@ class ProfileDialog : public QDialog private slots: void addProfile(); void editProfile(); + void deleteProfile(); public: explicit ProfileDialog(Cameras* cameras, QWidget *parent = nullptr); diff --git a/src/ui/profiledialog.ui b/src/ui/profiledialog.ui index 173b04b..c2b3e9c 100644 --- a/src/ui/profiledialog.ui +++ b/src/ui/profiledialog.ui @@ -40,6 +40,13 @@ + + + + Delete + + +