Initial commit
This commit is contained in:
54
CMakeLists.txt
Normal file
54
CMakeLists.txt
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.5)
|
||||||
|
|
||||||
|
project(MAClient LANGUAGES CXX)
|
||||||
|
|
||||||
|
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||||
|
|
||||||
|
set(CMAKE_AUTOUIC ON)
|
||||||
|
set(CMAKE_AUTOMOC ON)
|
||||||
|
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(OpenCV REQUIRED)
|
||||||
|
|
||||||
|
set(PROJECT_SOURCES
|
||||||
|
res/resources.qrc
|
||||||
|
src/main.cpp
|
||||||
|
src/cameras.cpp
|
||||||
|
src/cameras.h
|
||||||
|
src/camera.cpp
|
||||||
|
src/camera.h
|
||||||
|
src/profile.cpp
|
||||||
|
src/profile.h
|
||||||
|
src/imagepipeline.cpp
|
||||||
|
src/imagepipeline.h
|
||||||
|
src/ui/cameradialog.cpp
|
||||||
|
src/ui/cameradialog.h
|
||||||
|
src/ui/cameradialog.ui
|
||||||
|
src/ui/profiledialog.cpp
|
||||||
|
src/ui/profiledialog.h
|
||||||
|
src/ui/profiledialog.ui
|
||||||
|
src/ui/editprofiledialog.h
|
||||||
|
src/ui/editprofiledialog.cpp
|
||||||
|
src/ui/editprofiledialog.ui
|
||||||
|
src/ui/mainwindow.cpp
|
||||||
|
src/ui/mainwindow.h
|
||||||
|
src/ui/mainwindow.ui
|
||||||
|
src/ui/cvimageviewer.cpp
|
||||||
|
src/ui/cvimageviewer.h
|
||||||
|
src/ui/cvimageviewer.ui
|
||||||
|
src/ui/led.cpp
|
||||||
|
src/ui/led.h
|
||||||
|
src/ui/cameralistwidget.h
|
||||||
|
src/ui/cameralistwidget.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
add_executable(MAClient ${PROJECT_SOURCES})
|
||||||
|
|
||||||
|
target_link_libraries(MAClient PRIVATE Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Concurrent ${OpenCV_LIBS} -luvoscam -luvosled -luvosunwrap)
|
||||||
|
target_include_directories(${PROJECT_NAME} PRIVATE ${OpenCV_INCLUDE_DIRS} src src/ui)
|
BIN
res/noimage.png
Normal file
BIN
res/noimage.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 616 KiB |
6
res/resources.qrc
Normal file
6
res/resources.qrc
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<RCC>
|
||||||
|
<qresource prefix="/images">
|
||||||
|
<file>noimage.png</file>
|
||||||
|
<file>splash.png</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
BIN
res/splash.png
Normal file
BIN
res/splash.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 186 KiB |
18
src/camera.cpp
Normal file
18
src/camera.cpp
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#include "camera.h"
|
||||||
|
#include <QRandomGenerator>
|
||||||
|
#include <string>
|
||||||
|
#include <functional>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
Camera::Camera(cam::Camera::Description desc)
|
||||||
|
{
|
||||||
|
cameraId_ = desc.getHash();
|
||||||
|
std::function<void(cv::Mat)> cb = [this](cv::Mat image){newImage(Image(image, cameraId_));};
|
||||||
|
camera_ = new cam::Camera(cb);
|
||||||
|
camera_->openCamera(desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
Camera::~Camera()
|
||||||
|
{
|
||||||
|
delete camera_;
|
||||||
|
}
|
46
src/camera.h
Normal file
46
src/camera.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#ifndef CAMERA_H
|
||||||
|
#define CAMERA_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <vector>
|
||||||
|
#include <uvoscam.h>
|
||||||
|
#include <uvosled.h>
|
||||||
|
#include <memory.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <QSettings>
|
||||||
|
#include <opencv2/core/mat.hpp>
|
||||||
|
|
||||||
|
#include "profile.h"
|
||||||
|
|
||||||
|
class Camera : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
class Image
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
cv::Mat mat;
|
||||||
|
size_t cameraId;
|
||||||
|
Image(cv::Mat mati, size_t cameraIdi): mat(mati), cameraId(cameraIdi){}
|
||||||
|
Image() = default;
|
||||||
|
Image(const Image& img) = default;
|
||||||
|
};
|
||||||
|
private:
|
||||||
|
cam::Camera* camera_ = nullptr;
|
||||||
|
|
||||||
|
void callback(cv::Mat);
|
||||||
|
size_t cameraId_;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void newImage(Image);
|
||||||
|
|
||||||
|
public:
|
||||||
|
Camera(cam::Camera::Description);
|
||||||
|
~Camera();
|
||||||
|
cam::Camera* cam(){return camera_;}
|
||||||
|
size_t id() const {return cameraId_;}
|
||||||
|
bool operator==(const Camera& cam){return cam.id() == id();}
|
||||||
|
bool operator!=(const Camera& cam){return !operator==(cam);}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CAMERA_H
|
181
src/cameras.cpp
Normal file
181
src/cameras.cpp
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
#include "cameras.h"
|
||||||
|
#include <QRandomGenerator>
|
||||||
|
#include <string>
|
||||||
|
#include <functional>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
Cameras::Cameras(uvosled* led): led_(led)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Cameras::setCameras(const std::vector<cam::Camera::Description>& descriptions)
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
bool ret = true;
|
||||||
|
for(auto& camera : descriptions)
|
||||||
|
{
|
||||||
|
if(!addCamera(camera))
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Cameras::clear()
|
||||||
|
{
|
||||||
|
free_ = false;
|
||||||
|
for(auto& camera : cameras_)
|
||||||
|
cameraRemoved(camera);
|
||||||
|
cameras_.clear();
|
||||||
|
if(led_)
|
||||||
|
uvosled_set_current(led_, 0xFF, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<cam::Camera::Description> Cameras::getCameras()
|
||||||
|
{
|
||||||
|
std::vector<cam::Camera::Description> desc;
|
||||||
|
desc.reserve(cameras_.size());
|
||||||
|
for(std::shared_ptr<Camera> camera : cameras_)
|
||||||
|
desc.push_back(camera->cam()->getDescription());
|
||||||
|
return desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Cameras::addCamera(const cam::Camera::Description& desc)
|
||||||
|
{
|
||||||
|
cameras_.push_back(std::shared_ptr<Camera>(new Camera(desc)));
|
||||||
|
|
||||||
|
if(!cameras_.back()->cam()->isOpen())
|
||||||
|
{
|
||||||
|
cameras_.pop_back();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
cameras_.back()->cam()->setTriggerMode(cam::Camera::TRIGGER_SOFTWARE);
|
||||||
|
cameras_.back()->cam()->setExposureTime(exposrueTime_*1000000);
|
||||||
|
setFree(false);
|
||||||
|
cameraAdded(cameras_.back());
|
||||||
|
qDebug()<<"Using camera"<<cameras_.back()->id();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cameras::trigger()
|
||||||
|
{
|
||||||
|
for(auto& camera : cameras_)
|
||||||
|
camera->cam()->trigger();
|
||||||
|
|
||||||
|
if(led_ && !free_)
|
||||||
|
uvosled_capture(led_, lighting_.mask, lighting_.brightness, exposrueTime_*1.5, exposrueTime_*0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Cameras::start()
|
||||||
|
{
|
||||||
|
bool ret = true;
|
||||||
|
for(auto& camera : cameras_)
|
||||||
|
{
|
||||||
|
if(!camera->cam()->startAcquisition())
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(free_)
|
||||||
|
uvosled_set_current(led_, lighting_.mask, lighting_.brightness);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Cameras::stop()
|
||||||
|
{
|
||||||
|
bool ret = true;
|
||||||
|
for(auto& camera : cameras_)
|
||||||
|
{
|
||||||
|
if(!camera->cam()->stopAcquisition())
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(led_)
|
||||||
|
uvosled_set_current(led_, 0xFF, 0);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Cameras::setFree(bool free)
|
||||||
|
{
|
||||||
|
stop();
|
||||||
|
free_ = free;
|
||||||
|
bool ret = true;
|
||||||
|
|
||||||
|
for(auto& camera : cameras_)
|
||||||
|
{
|
||||||
|
if(!camera->cam()->setAcquisitionMode(free ? cam::Camera::MODE_FREE : cam::Camera::MODE_SINGLE))
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Cameras::setExposureTime(double exposureTime)
|
||||||
|
{
|
||||||
|
stop();
|
||||||
|
exposrueTime_ = exposureTime;
|
||||||
|
bool ret = true;
|
||||||
|
for(auto& camera : cameras_)
|
||||||
|
{
|
||||||
|
if(!camera->cam()->setExposureTime(exposrueTime_*1000000))
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cameras::imageRecived(Camera::Image img)
|
||||||
|
{
|
||||||
|
bool allreadyUpdated = false;
|
||||||
|
for(auto& camera : cameras_)
|
||||||
|
{
|
||||||
|
for(auto& image : images_)
|
||||||
|
{
|
||||||
|
if(image.cameraId == camera->id())
|
||||||
|
{
|
||||||
|
allreadyUpdated = true;
|
||||||
|
goto FOUND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FOUND:
|
||||||
|
|
||||||
|
if(!allreadyUpdated)
|
||||||
|
images_.push_back(img);
|
||||||
|
|
||||||
|
if(images_.size() == cameras_.size())
|
||||||
|
newImages(images_);
|
||||||
|
|
||||||
|
images_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cameras::store(QSettings &settings)
|
||||||
|
{
|
||||||
|
std::vector<cam::Camera::Description> available = cam::Camera::getAvailableCameras();
|
||||||
|
|
||||||
|
settings.beginWriteArray(GROUP, cameras_.size());
|
||||||
|
for(size_t i = 0; i < cameras_.size(); ++i)
|
||||||
|
{
|
||||||
|
settings.setArrayIndex(i);
|
||||||
|
settings.setValue("id", static_cast<unsigned long long>(cameras_[i]->id()));
|
||||||
|
}
|
||||||
|
settings.endArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cameras::load(QSettings &settings)
|
||||||
|
{
|
||||||
|
std::vector<cam::Camera::Description> available = cam::Camera::getAvailableCameras();
|
||||||
|
|
||||||
|
int size = settings.beginReadArray(GROUP);
|
||||||
|
for(int i = 0; i < size; ++i)
|
||||||
|
{
|
||||||
|
settings.setArrayIndex(i);
|
||||||
|
size_t hash = settings.value("id", 0).toULongLong();
|
||||||
|
for(auto& camera : available)
|
||||||
|
{
|
||||||
|
if(camera.getHash() == hash)
|
||||||
|
addCamera(camera);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
settings.endArray();
|
||||||
|
}
|
59
src/cameras.h
Normal file
59
src/cameras.h
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
#ifndef CAMERAS_H
|
||||||
|
#define CAMERAS_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <vector>
|
||||||
|
#include <uvoscam.h>
|
||||||
|
#include <uvosled.h>
|
||||||
|
#include <memory.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <QSettings>
|
||||||
|
#include <opencv2/core/mat.hpp>
|
||||||
|
|
||||||
|
#include "profile.h"
|
||||||
|
#include "camera.h"
|
||||||
|
|
||||||
|
class Cameras : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
static constexpr const char* GROUP = "Cameras";
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
uvosled* led_;
|
||||||
|
bool free_ = false;
|
||||||
|
double exposrueTime_ = 1.0/60.0;
|
||||||
|
LightingSetup lighting_;
|
||||||
|
std::vector<std::shared_ptr<Camera>> cameras_;
|
||||||
|
std::vector<Camera::Image> images_;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void imageRecived(Camera::Image img);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void cameraRemoved(std::shared_ptr<Camera> camera);
|
||||||
|
void cameraAdded(std::shared_ptr<Camera> camera);
|
||||||
|
void newImages(std::vector<Camera::Image> images_);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
bool setExposureTime(double exposureTime);
|
||||||
|
void trigger();
|
||||||
|
bool start();
|
||||||
|
bool stop();
|
||||||
|
bool setFree(bool free);
|
||||||
|
void setLighting(const LightingSetup& lighting) {lighting_ = lighting;}
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool setCameras(const std::vector<cam::Camera::Description>& descriptions);
|
||||||
|
bool addCamera(const cam::Camera::Description& desc);
|
||||||
|
std::vector<cam::Camera::Description> getCameras();
|
||||||
|
size_t numCameras(){return cameras_.size();}
|
||||||
|
void clear();
|
||||||
|
Cameras(uvosled* led = nullptr);
|
||||||
|
void load(QSettings& settings);
|
||||||
|
void store(QSettings& settings);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CAMERAS_H
|
74
src/imagepipeline.cpp
Normal file
74
src/imagepipeline.cpp
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
#include "imagepipeline.h"
|
||||||
|
#include <uvosunwrap/unwrap.h>
|
||||||
|
#include <QtConcurrent/QtConcurrentRun>
|
||||||
|
#include <QFuture>
|
||||||
|
|
||||||
|
ImagePipeline::ImagePipeline(Cameras* cameras, QObject *parent): QObject(parent), cameras_(cameras)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::Mat ImagePipeline::process(const Profile profile, std::vector<Camera::Image> images)
|
||||||
|
{
|
||||||
|
std::vector<RemapedImage> remapedImages;
|
||||||
|
remapedImages.reserve(images.size());
|
||||||
|
|
||||||
|
for(Camera::Image& image : images)
|
||||||
|
{
|
||||||
|
for(auto& camera : profile.cameras)
|
||||||
|
{
|
||||||
|
if(camera.id == image.cameraId)
|
||||||
|
{
|
||||||
|
if(camera.darkmap.data)
|
||||||
|
image.mat = image.mat - camera.darkmap;
|
||||||
|
remapedImages.push_back(applyRemap(image.mat, camera.remapMap));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::Mat output = simpleStich(remapedImages);
|
||||||
|
output.convertTo(output, CV_32FC1, 1.0/255.0, 0);
|
||||||
|
|
||||||
|
if(profile.lightmap.data)
|
||||||
|
normalize(output, profile.lightmap);
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImagePipeline::apply(std::vector<Camera::Image> images)
|
||||||
|
{
|
||||||
|
if(!invalid_)
|
||||||
|
{
|
||||||
|
futureImageWatchers_.push_back(new QFutureWatcher<cv::Mat>());
|
||||||
|
connect(futureImageWatchers_.back(), &QFutureWatcher<cv::Mat>::finished, this, &ImagePipeline::imageFinished);
|
||||||
|
|
||||||
|
QFuture<cv::Mat> futureImage = QtConcurrent::run(&ImagePipeline::process, profile_, images);
|
||||||
|
futureImageWatchers_.back()->setFuture(futureImage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImagePipeline::setProfile(const Profile& profile)
|
||||||
|
{
|
||||||
|
profile_ = profile;
|
||||||
|
cameras_->setExposureTime(profile_.exposureTime);
|
||||||
|
cameras_->setLighting(profile_.lighting);
|
||||||
|
if(!profile_.camerasSufficant(cameras_->getCameras()))
|
||||||
|
{
|
||||||
|
invalid_ = true;
|
||||||
|
sigInvalidProfile("A camera required for this profile is not available");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImagePipeline::imageFinished()
|
||||||
|
{
|
||||||
|
for(size_t i = 0; i < futureImageWatchers_.size(); ++i)
|
||||||
|
{
|
||||||
|
if(futureImageWatchers_[i]->isFinished())
|
||||||
|
{
|
||||||
|
cv::Mat result = futureImageWatchers_[i]->result();
|
||||||
|
sigResult(Camera::Image(result, 0));
|
||||||
|
delete futureImageWatchers_[i];
|
||||||
|
futureImageWatchers_.erase(futureImageWatchers_.begin()+i);
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
41
src/imagepipeline.h
Normal file
41
src/imagepipeline.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#ifndef IMAGEPIPELINE_H
|
||||||
|
#define IMAGEPIPELINE_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <QFutureWatcher>
|
||||||
|
|
||||||
|
#include "profile.h"
|
||||||
|
#include "cameras.h"
|
||||||
|
|
||||||
|
class ImagePipeline: public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Cameras* cameras_;
|
||||||
|
Profile profile_;
|
||||||
|
bool invalid_ = true;
|
||||||
|
std::vector<QFutureWatcher<cv::Mat>*> futureImageWatchers_;
|
||||||
|
|
||||||
|
static cv::Mat process(const Profile profile, std::vector<Camera::Image> images);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void apply(std::vector<Camera::Image> images);
|
||||||
|
void imageFinished();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void sigInvalidProfile(QString message);
|
||||||
|
void sigResult(Camera::Image image);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void setProfile(const Profile& profile);
|
||||||
|
|
||||||
|
public:
|
||||||
|
ImagePipeline(Cameras* cameras, QObject* parent = nullptr);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // IMAGEPIPELINE_H
|
93
src/main.cpp
Normal file
93
src/main.cpp
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
#include <QApplication>
|
||||||
|
#include <uvoscam.h>
|
||||||
|
#include <QSettings>
|
||||||
|
#include <QString>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QSplashScreen>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QThread>
|
||||||
|
#include <opencv2/core/mat.hpp>
|
||||||
|
|
||||||
|
#include "cameras.h"
|
||||||
|
#include "./ui/cameradialog.h"
|
||||||
|
#include "profile.h"
|
||||||
|
#include "./ui/mainwindow.h"
|
||||||
|
#include "imagepipeline.h"
|
||||||
|
|
||||||
|
const char* organziation = "UVOS";
|
||||||
|
const char* application = "UVOS";
|
||||||
|
const char* version = "UVOS";
|
||||||
|
|
||||||
|
std::vector<cam::Camera::Description> showCameraSelectionDialog()
|
||||||
|
{
|
||||||
|
std::vector<cam::Camera::Description> ret;
|
||||||
|
CameraDialog diag(cam::Camera::getAvailableCameras());
|
||||||
|
|
||||||
|
diag.show();
|
||||||
|
if(diag.exec() == QDialog::Accepted)
|
||||||
|
ret = diag.getDescriptions();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
QApplication a(argc, argv);
|
||||||
|
QCoreApplication::setOrganizationName("UVOS");
|
||||||
|
QCoreApplication::setOrganizationDomain("uvos.xyz");
|
||||||
|
QCoreApplication::setApplicationName("LubircantThiknessMapperUi");
|
||||||
|
QCoreApplication::setApplicationVersion("0.1");
|
||||||
|
|
||||||
|
QSplashScreen splash(QPixmap(":/images/splash.png"));
|
||||||
|
splash.show();
|
||||||
|
|
||||||
|
QDir().mkpath(Profile::profileLocation());
|
||||||
|
QDir().mkpath(CameraSetup::camerasLocation());
|
||||||
|
|
||||||
|
qRegisterMetaType<cv::Mat>("cv::Mat");
|
||||||
|
qRegisterMetaType<size_t>("size_t");
|
||||||
|
qRegisterMetaType<Camera::Image>("Image");
|
||||||
|
|
||||||
|
QSettings settings(QSettings::IniFormat, QSettings::UserScope, QCoreApplication::organizationName(), QCoreApplication::applicationName());
|
||||||
|
|
||||||
|
uvosled led;
|
||||||
|
int uvosledRet = uvosled_connect(&led);
|
||||||
|
|
||||||
|
Cameras cameras(uvosledRet < 0 ? nullptr : &led);
|
||||||
|
ImagePipeline pipe(&cameras);
|
||||||
|
|
||||||
|
MainWindow w;
|
||||||
|
|
||||||
|
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(&pipe, &ImagePipeline::sigResult, w.mainImageViewer(), &CvImageViewer::setImage, Qt::QueuedConnection);
|
||||||
|
|
||||||
|
QObject::connect(&w, &MainWindow::sigProfile, [&pipe](QString name)
|
||||||
|
{
|
||||||
|
Profile profile;
|
||||||
|
profile.load(name);
|
||||||
|
pipe.setProfile(profile);
|
||||||
|
});
|
||||||
|
|
||||||
|
cameras.load(settings);
|
||||||
|
|
||||||
|
splash.hide();
|
||||||
|
w.show();
|
||||||
|
|
||||||
|
if(uvosledRet < 0)
|
||||||
|
QMessageBox::warning(&w, "UVOS LED", "Can not connect to the UVOS LED device");
|
||||||
|
|
||||||
|
if(cameras.getCameras().empty())
|
||||||
|
{
|
||||||
|
QMessageBox::information(&w, "Cameras", "No cameras configured, please choose at least one camera.");
|
||||||
|
cameras.setCameras(showCameraSelectionDialog());
|
||||||
|
}
|
||||||
|
|
||||||
|
int ret = a.exec();
|
||||||
|
|
||||||
|
cameras.store(settings);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
151
src/profile.cpp
Normal file
151
src/profile.cpp
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
#include "profile.h"
|
||||||
|
#include <opencv2/imgcodecs.hpp>
|
||||||
|
#include <QStandardPaths>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QDir>
|
||||||
|
|
||||||
|
void CameraSetup::store() const
|
||||||
|
{
|
||||||
|
cv::imwrite((camerasLocation() + QString::number(id) + ".darkmap.png").toStdString(), darkmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraSetup::load(size_t cameraId)
|
||||||
|
{
|
||||||
|
id = cameraId;
|
||||||
|
darkmap = cv::imread((camerasLocation() + QString::number(id) + ".darkmap.png").toStdString());
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CameraSetup::camerasLocation()
|
||||||
|
{
|
||||||
|
return QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/cameras/";
|
||||||
|
}
|
||||||
|
|
||||||
|
void LightingSetup::store(QSettings& settings) const
|
||||||
|
{
|
||||||
|
settings.setValue(GROUP + QString("/brightness"), brightness);
|
||||||
|
settings.setValue(GROUP + QString("/mask"), mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LightingSetup::load(const QSettings& settings)
|
||||||
|
{
|
||||||
|
brightness = settings.value(GROUP + QString("/brightness"), 0.25).toDouble();
|
||||||
|
mask = settings.value(GROUP + QString("/maks"), 0).toUInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Profile::store(QSettings& settings) const
|
||||||
|
{
|
||||||
|
lighting.store(settings);
|
||||||
|
settings.setValue(GROUP + QString("/id"), static_cast<unsigned long long>(id));
|
||||||
|
settings.setValue(GROUP + QString("/exposureTime"), exposureTime);
|
||||||
|
settings.setValue(GROUP + QString("/name"), name_);
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
const CameraSetup& camera = cameras[i];
|
||||||
|
settings.setArrayIndex(i);
|
||||||
|
camera.store();
|
||||||
|
settings.setValue("id", static_cast<unsigned long long>(camera.id));
|
||||||
|
}
|
||||||
|
settings.endArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Profile::load(QSettings &settings)
|
||||||
|
{
|
||||||
|
lighting.load(settings);
|
||||||
|
id = settings.value(GROUP + QString("/id")).toULongLong();
|
||||||
|
exposureTime = settings.value(GROUP + QString("/exposureTime"), 1.0/60.0).toDouble();
|
||||||
|
name_ = settings.value(GROUP + QString("/name"), "NULL").toString();
|
||||||
|
|
||||||
|
lightmap = cv::imread((profileLocation() + QString::number(id) + ".lightmap.png").toStdString());
|
||||||
|
|
||||||
|
int size = settings.beginReadArray(GROUP + QString("/cameras"));
|
||||||
|
for(int i = 0; i < size; ++i)
|
||||||
|
{
|
||||||
|
settings.setArrayIndex(i);
|
||||||
|
cameras.push_back(CameraSetup());
|
||||||
|
cameras.back().load(settings.value("id", 0).toULongLong());
|
||||||
|
}
|
||||||
|
settings.endArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Profile::load(const QString& name)
|
||||||
|
{
|
||||||
|
QSettings settings(profileLocation() + name + ".profile.ini");
|
||||||
|
name_=name;
|
||||||
|
load(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Profile::store(const QString& name)
|
||||||
|
{
|
||||||
|
QSettings settings(profileLocation() + name + ".profile.ini");
|
||||||
|
name_=name;
|
||||||
|
store(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Profile::load()
|
||||||
|
{
|
||||||
|
load(name_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Profile::store()
|
||||||
|
{
|
||||||
|
store(name_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Profile::deleteProfile()
|
||||||
|
{
|
||||||
|
QFile::remove(profileLocation() + name_ + ".profile.ini");
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QString> Profile::avaiableProfiles()
|
||||||
|
{
|
||||||
|
QDir dir(profileLocation());
|
||||||
|
dir.setFilter(QDir::Files);
|
||||||
|
QStringList filters;
|
||||||
|
filters<<"*.ini";
|
||||||
|
dir.setNameFilters(filters);
|
||||||
|
QList<QString> ret;
|
||||||
|
QStringList list = dir.entryList();
|
||||||
|
|
||||||
|
for(QString string : list)
|
||||||
|
ret.push_back(string.split(".")[0]);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Profile::camerasSufficant(const std::vector<cam::Camera::Description>& desc) const
|
||||||
|
{
|
||||||
|
bool invalid = false;
|
||||||
|
for(auto& cameraProfile : cameras)
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
for(auto& camera : desc)
|
||||||
|
{
|
||||||
|
if(camera.getHash() == cameraProfile.id)
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!found)
|
||||||
|
{
|
||||||
|
invalid = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return !invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QString Profile::profileLocation()
|
||||||
|
{
|
||||||
|
return QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/profiles/";
|
||||||
|
}
|
||||||
|
|
||||||
|
Profile::Profile(const QString& name): name_(name)
|
||||||
|
{
|
||||||
|
id = QRandomGenerator::system()->generate64();
|
||||||
|
}
|
67
src/profile.h
Normal file
67
src/profile.h
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
#ifndef PROFILE_H
|
||||||
|
#define PROFILE_H
|
||||||
|
#include <QSettings>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <QRandomGenerator>
|
||||||
|
#include <opencv2/core/mat.hpp>
|
||||||
|
#include <uvosunwrap/unwrap.h>
|
||||||
|
|
||||||
|
#include "camera.h"
|
||||||
|
|
||||||
|
class CameraSetup
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
size_t id;
|
||||||
|
RemapMap remapMap;
|
||||||
|
cv::Mat darkmap;
|
||||||
|
cv::Mat bgmask;
|
||||||
|
void store() const;
|
||||||
|
void load(size_t cameraId);
|
||||||
|
static QString camerasLocation();
|
||||||
|
static QString remapMapLocation(size_t cameraId);
|
||||||
|
static QString bgmaskLocation(size_t cameraId);
|
||||||
|
static QString darkmapLocation(size_t cameraId);
|
||||||
|
};
|
||||||
|
|
||||||
|
class LightingSetup
|
||||||
|
{
|
||||||
|
static constexpr const char* GROUP = "Lighting";
|
||||||
|
|
||||||
|
public:
|
||||||
|
double brightness = 0.25;
|
||||||
|
uint8_t mask = 0;
|
||||||
|
|
||||||
|
void store(QSettings& settings) const;
|
||||||
|
void load(const QSettings& settings);
|
||||||
|
};
|
||||||
|
|
||||||
|
class Profile
|
||||||
|
{
|
||||||
|
static constexpr const char* GROUP = "Profile";
|
||||||
|
|
||||||
|
QString name_ = "NULL";
|
||||||
|
|
||||||
|
public:
|
||||||
|
uint64_t id;
|
||||||
|
LightingSetup lighting;
|
||||||
|
double exposureTime = 1.0/60.0;
|
||||||
|
cv::Mat lightmap;
|
||||||
|
std::vector<CameraSetup> cameras;
|
||||||
|
|
||||||
|
Profile(const QString& name = "NULL");
|
||||||
|
void store(QSettings& settings) const;
|
||||||
|
void store(const QString& name);
|
||||||
|
void store();
|
||||||
|
void load(QSettings& settings);
|
||||||
|
void load(const QString& name);
|
||||||
|
void load();
|
||||||
|
void deleteProfile();
|
||||||
|
void setName(const QString name){name_=name;}
|
||||||
|
QString getName() const {return name_;}
|
||||||
|
bool camerasSufficant(const std::vector<cam::Camera::Description>& desc) const;
|
||||||
|
static QList<QString> avaiableProfiles();
|
||||||
|
static QString profileLocation();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PROFILE_H
|
21
src/ui/cameradialog.cpp
Normal file
21
src/ui/cameradialog.cpp
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#include "cameradialog.h"
|
||||||
|
#include "ui_cameradialog.h"
|
||||||
|
#include "../cameras.h"
|
||||||
|
|
||||||
|
CameraDialog::CameraDialog(const std::vector<cam::Camera::Description>& desc, QWidget *parent) :
|
||||||
|
QDialog(parent),
|
||||||
|
ui(new Ui::CameraDialog)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
ui->listView->setCameras(desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
CameraDialog::~CameraDialog()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<cam::Camera::Description> CameraDialog::getDescriptions()
|
||||||
|
{
|
||||||
|
return ui->listView->getSelectedDescriptions();
|
||||||
|
}
|
26
src/ui/cameradialog.h
Normal file
26
src/ui/cameradialog.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#ifndef CAMERADIALOG_H
|
||||||
|
#define CAMERADIALOG_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include <vector>
|
||||||
|
#include <uvoscam.h>
|
||||||
|
#include <QSettings>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class CameraDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
class CameraDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit CameraDialog(const std::vector<cam::Camera::Description>& desc, QWidget *parent = nullptr);
|
||||||
|
~CameraDialog();
|
||||||
|
std::vector<cam::Camera::Description> getDescriptions();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::CameraDialog *ui;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CAMERADIALOG_H
|
91
src/ui/cameradialog.ui
Normal file
91
src/ui/cameradialog.ui
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>CameraDialog</class>
|
||||||
|
<widget class="QDialog" name="CameraDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>400</width>
|
||||||
|
<height>300</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="acceptDrops">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Select Cameras</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Select Cameras:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="CameraListWidget" name="listView"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="pushButtonConfigure">
|
||||||
|
<property name="text">
|
||||||
|
<string>Configure Cameras</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>CameraListWidget</class>
|
||||||
|
<extends>QListView</extends>
|
||||||
|
<header location="global">cameralistwidget.h</header>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>CameraDialog</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>CameraDialog</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>
|
45
src/ui/cameralistwidget.cpp
Normal file
45
src/ui/cameralistwidget.cpp
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#include "cameralistwidget.h"
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QHeaderView>
|
||||||
|
#include "../cameras.h"
|
||||||
|
|
||||||
|
CameraListWidget::CameraListWidget(QWidget* parent): QTableWidget(parent)
|
||||||
|
{
|
||||||
|
setColumnCount(1);
|
||||||
|
setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||||
|
setSelectionMode(QAbstractItemView::MultiSelection);
|
||||||
|
setHorizontalHeaderItem(0, new QTableWidgetItem("Camera"));
|
||||||
|
setRowCount(desc_.size());
|
||||||
|
horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraListWidget::setConfigured(std::vector<bool> configured)
|
||||||
|
{
|
||||||
|
setColumnCount(2);
|
||||||
|
setHorizontalHeaderItem(1, new QTableWidgetItem("Configured"));
|
||||||
|
for(size_t i = 0; i < desc_.size() && i < configured.size(); ++i)
|
||||||
|
setItem(static_cast<int>(i), 0, new QTableWidgetItem("No"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraListWidget::setCameras(const std::vector<cam::Camera::Description>& desc)
|
||||||
|
{
|
||||||
|
desc_ = desc;
|
||||||
|
qDebug()<<"cameras: "<<desc_.size();
|
||||||
|
setRowCount(static_cast<int>(desc_.size()));
|
||||||
|
for(size_t i = 0; i < desc_.size(); ++i)
|
||||||
|
{
|
||||||
|
setItem(static_cast<int>(i), 0, new QTableWidgetItem((desc_[i].vendor + " " + desc_[i].model).c_str()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<cam::Camera::Description> CameraListWidget::getSelectedDescriptions()
|
||||||
|
{
|
||||||
|
QList<QModelIndex> selected = selectedIndexes();
|
||||||
|
std::vector<cam::Camera::Description> cameras;
|
||||||
|
for(auto& selection : selected)
|
||||||
|
{
|
||||||
|
if(selection.column() == 0)
|
||||||
|
cameras.push_back(desc_[selection.row()]);
|
||||||
|
}
|
||||||
|
return cameras;
|
||||||
|
}
|
19
src/ui/cameralistwidget.h
Normal file
19
src/ui/cameralistwidget.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#ifndef CAMERALISTWIDGET_H
|
||||||
|
#define CAMERALISTWIDGET_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <uvoscam.h>
|
||||||
|
#include <QTableWidget>
|
||||||
|
|
||||||
|
class CameraListWidget : public QTableWidget
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::vector<cam::Camera::Description> desc_;
|
||||||
|
public:
|
||||||
|
CameraListWidget(QWidget* parent);
|
||||||
|
void setCameras(const std::vector<cam::Camera::Description>& desc);
|
||||||
|
void setConfigured(std::vector<bool> configured);
|
||||||
|
std::vector<cam::Camera::Description> getSelectedDescriptions();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CAMERALISTWIDGET_H
|
36
src/ui/cvimageviewer.cpp
Normal file
36
src/ui/cvimageviewer.cpp
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#include "cvimageviewer.h"
|
||||||
|
#include <QPicture>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
CvImageViewer::CvImageViewer(QWidget *parent, size_t lastId) :
|
||||||
|
QWidget(parent),
|
||||||
|
lastId_(lastId)
|
||||||
|
{
|
||||||
|
qimage_.load(":/images/noimage.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
CvImageViewer::~CvImageViewer()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
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_);
|
||||||
|
else
|
||||||
|
painter.drawImage(QRect(rect().x(), (rect().height()-rect().width())/2, rect().width(), rect().width()), qimage_);
|
||||||
|
}
|
30
src/ui/cvimageviewer.h
Normal file
30
src/ui/cvimageviewer.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#ifndef CVIMAGEVIEWER_H
|
||||||
|
#define CVIMAGEVIEWER_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QPainter>
|
||||||
|
#include "../cameras.h"
|
||||||
|
|
||||||
|
class CvImageViewer : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
cv::Mat image_;
|
||||||
|
QImage qimage_;
|
||||||
|
bool fixedOnWidth_ = false;
|
||||||
|
size_t lastId_;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void paintEvent(QPaintEvent* event) override;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void setImage(Camera::Image img);
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit CvImageViewer(QWidget *parent = nullptr, size_t lastId = 0);
|
||||||
|
void setFixedOnWidth(bool in){fixedOnWidth_ = in;}
|
||||||
|
size_t lastId(){return lastId_;}
|
||||||
|
~CvImageViewer();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CVIMAGEVIEWER_H
|
28
src/ui/cvimageviewer.ui
Normal file
28
src/ui/cvimageviewer.ui
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>CvImageViewer</class>
|
||||||
|
<widget class="QWidget" name="CvImageViewer">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>400</width>
|
||||||
|
<height>300</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
16
src/ui/editprofiledialog.cpp
Normal file
16
src/ui/editprofiledialog.cpp
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#include "editprofiledialog.h"
|
||||||
|
#include "ui_editprofiledialog.h"
|
||||||
|
|
||||||
|
EditProfileDialog::EditProfileDialog(Cameras* cameras, Profile* profile, QWidget *parent) :
|
||||||
|
QDialog(parent),
|
||||||
|
profile_(profile),
|
||||||
|
cameras_(cameras),
|
||||||
|
ui(new Ui::EditProfileDialog)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
EditProfileDialog::~EditProfileDialog()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
28
src/ui/editprofiledialog.h
Normal file
28
src/ui/editprofiledialog.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#ifndef EDDITPROFILEDIALOG_H
|
||||||
|
#define EDDITPROFILEDIALOG_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include <profile.h>
|
||||||
|
#include "../cameras.h"
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class EditProfileDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
class EditProfileDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Profile* profile_;
|
||||||
|
Cameras* cameras_;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit EditProfileDialog(Cameras* cameras, Profile* profile, QWidget *parent = nullptr);
|
||||||
|
Profile* getProfile(){return profile_;}
|
||||||
|
~EditProfileDialog();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::EditProfileDialog *ui;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // EDDITPROFILEDIALOG_H
|
228
src/ui/editprofiledialog.ui
Normal file
228
src/ui/editprofiledialog.ui
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>EditProfileDialog</class>
|
||||||
|
<widget class="QDialog" name="EditProfileDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>539</width>
|
||||||
|
<height>485</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Dialog</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Profile Name</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="lineEditName"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>Cameras</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="CameraListWidget" name="listView"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="pushButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Configure</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Exposure Time</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDoubleSpinBox" name="doubleSpinBoxExposure">
|
||||||
|
<property name="maximum">
|
||||||
|
<double>1.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<double>0.010000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_5">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>s</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox_2">
|
||||||
|
<property name="title">
|
||||||
|
<string>Lights</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Brightness</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDoubleSpinBox" name="doubleSpinBoxBrightness"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>%</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_6">
|
||||||
|
<property name="text">
|
||||||
|
<string>Channels:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="checkBoxCh1">
|
||||||
|
<property name="text">
|
||||||
|
<string>CH1</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="checkBoxCh2">
|
||||||
|
<property name="text">
|
||||||
|
<string>CH2</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="checkBoxCh3">
|
||||||
|
<property name="text">
|
||||||
|
<string>CH3</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="checkBoxCh4">
|
||||||
|
<property name="text">
|
||||||
|
<string>CH4</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Save</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>CameraListWidget</class>
|
||||||
|
<extends>QListView</extends>
|
||||||
|
<header location="global">./src/ui/cameralistwidget.h</header>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>EditProfileDialog</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>EditProfileDialog</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>
|
31
src/ui/led.cpp
Normal file
31
src/ui/led.cpp
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#include "led.h"
|
||||||
|
#include <QPainter>
|
||||||
|
|
||||||
|
Led::Led(QWidget* parent): QWidget(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Led::lit() const
|
||||||
|
{
|
||||||
|
return lit_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Led::setLit(bool lit)
|
||||||
|
{
|
||||||
|
if(lit != lit_)
|
||||||
|
{
|
||||||
|
lit_ = lit;
|
||||||
|
stateChanged(lit_);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Led::paintEvent(QPaintEvent* event)
|
||||||
|
{
|
||||||
|
Q_UNUSED(event)
|
||||||
|
QPainter ledPainter(this);
|
||||||
|
ledPainter.setPen(Qt::black);
|
||||||
|
if(lit_) ledPainter.setBrush(Qt::red);
|
||||||
|
else ledPainter.setBrush(Qt::NoBrush);
|
||||||
|
ledPainter.drawEllipse(rect().adjusted(0, 0, -1, -1));
|
||||||
|
}
|
29
src/ui/led.h
Normal file
29
src/ui/led.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#ifndef LED_H
|
||||||
|
#define LED_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
class Led : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
bool lit_ = false;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Led(QWidget* parent = nullptr);
|
||||||
|
bool lit() const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
void setLit(bool lit);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
void stateChanged(bool lit);
|
||||||
|
protected:
|
||||||
|
virtual void paintEvent(QPaintEvent* event) override;
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
#endif // LED_H
|
69
src/ui/mainwindow.cpp
Normal file
69
src/ui/mainwindow.cpp
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
#include "mainwindow.h"
|
||||||
|
#include "./ui_mainwindow.h"
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <uvosled.h>
|
||||||
|
|
||||||
|
#include "../profile.h"
|
||||||
|
|
||||||
|
MainWindow::MainWindow(QWidget *parent)
|
||||||
|
: QMainWindow(parent)
|
||||||
|
, ui(new Ui::MainWindow)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
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->comboBox, &QComboBox::currentTextChanged, this, &MainWindow::sigProfile);
|
||||||
|
connect(ui->pushButtonCapture, &QPushButton::clicked, this, &MainWindow::sigCapture);
|
||||||
|
ui->widget->setLit(true);
|
||||||
|
refreshProfiles();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::addCamera(std::shared_ptr<Camera> camera)
|
||||||
|
{
|
||||||
|
viewers_.push_back(new CvImageViewer(this, camera->id()));
|
||||||
|
viewers_.back()->setFixedOnWidth(true);
|
||||||
|
connect(camera.get(), &Camera::newImage, viewers_.back(), &CvImageViewer::setImage, Qt::QueuedConnection);
|
||||||
|
ui->viewerLayout->addWidget(viewers_.back());
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::removeCamera(std::shared_ptr<Camera> camera)
|
||||||
|
{
|
||||||
|
for(size_t i = 0; i < viewers_.size(); ++i)
|
||||||
|
{
|
||||||
|
if(viewers_[i]->lastId() == camera->id())
|
||||||
|
{
|
||||||
|
ui->viewerLayout->removeWidget(viewers_[i]);
|
||||||
|
delete viewers_[i];
|
||||||
|
viewers_.erase(viewers_.begin()+i);
|
||||||
|
--i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::refreshProfiles()
|
||||||
|
{
|
||||||
|
ui->comboBox->clear();
|
||||||
|
QList<QString> profiles = Profile::avaiableProfiles();
|
||||||
|
for(const QString& string : profiles)
|
||||||
|
ui->comboBox->addItem(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::profileInconpatible(QString message)
|
||||||
|
{
|
||||||
|
QMessageBox::warning(this, "Profile Incompatible", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
CvImageViewer* MainWindow::mainImageViewer()
|
||||||
|
{
|
||||||
|
return ui->mainViewer;
|
||||||
|
}
|
||||||
|
|
||||||
|
MainWindow::~MainWindow()
|
||||||
|
{
|
||||||
|
for(CvImageViewer* viewer : viewers_)
|
||||||
|
delete viewer;
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
39
src/ui/mainwindow.h
Normal file
39
src/ui/mainwindow.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#ifndef MAINWINDOW_H
|
||||||
|
#define MAINWINDOW_H
|
||||||
|
|
||||||
|
#include <QMainWindow>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "../cameras.h"
|
||||||
|
#include "cvimageviewer.h"
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
namespace Ui { class MainWindow; }
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
class MainWindow : public QMainWindow
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
private:
|
||||||
|
std::vector<CvImageViewer*> viewers_;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void sigCapture();
|
||||||
|
void sigProfile(QString profileName);
|
||||||
|
void sigChooseCameras();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
void addCamera(std::shared_ptr<Camera> camera);
|
||||||
|
void refreshProfiles();
|
||||||
|
void profileInconpatible(QString message);
|
||||||
|
void removeCamera(std::shared_ptr<Camera> camera);
|
||||||
|
|
||||||
|
public:
|
||||||
|
MainWindow(QWidget *parent = nullptr);
|
||||||
|
~MainWindow();
|
||||||
|
CvImageViewer* mainImageViewer();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::MainWindow *ui;
|
||||||
|
};
|
||||||
|
#endif // MAINWINDOW_H
|
230
src/ui/mainwindow.ui
Normal file
230
src/ui/mainwindow.ui
Normal file
@ -0,0 +1,230 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>MainWindow</class>
|
||||||
|
<widget class="QMainWindow" name="MainWindow">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>800</width>
|
||||||
|
<height>600</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>MainWindow</string>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="centralwidget">
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||||
|
<item>
|
||||||
|
<widget class="QSplitter" name="splitter">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<widget class="QGroupBox" name="groupBoxCameras">
|
||||||
|
<property name="title">
|
||||||
|
<string>Cameras</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
|
<item>
|
||||||
|
<widget class="QScrollArea" name="scrollArea">
|
||||||
|
<property name="widgetResizable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="scrollAreaWidgetContents">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>278</width>
|
||||||
|
<height>483</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_7">
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="viewerLayout"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="verticalLayoutWidget">
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBoxResult">
|
||||||
|
<property name="title">
|
||||||
|
<string>Result</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||||
|
<item>
|
||||||
|
<widget class="QScrollArea" name="scrollArea_2">
|
||||||
|
<property name="widgetResizable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="scrollAreaWidgetContents_2">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>467</width>
|
||||||
|
<height>315</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||||
|
<item>
|
||||||
|
<widget class="CvImageViewer" name="mainViewer" native="true"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox_3">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string>Controles</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="pushButtonCapture">
|
||||||
|
<property name="text">
|
||||||
|
<string>Capture</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Profile:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="comboBox"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="Led" name="widget" native="true">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>30</width>
|
||||||
|
<height>30</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Uncal</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QMenuBar" name="menubar">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>800</width>
|
||||||
|
<height>32</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<widget class="QMenu" name="menuFile">
|
||||||
|
<property name="title">
|
||||||
|
<string>File</string>
|
||||||
|
</property>
|
||||||
|
<addaction name="actionSave"/>
|
||||||
|
<addaction name="actionQuit"/>
|
||||||
|
</widget>
|
||||||
|
<widget class="QMenu" name="menuSetup">
|
||||||
|
<property name="title">
|
||||||
|
<string>Settings</string>
|
||||||
|
</property>
|
||||||
|
<addaction name="actionCameras"/>
|
||||||
|
<addaction name="actionCallibration"/>
|
||||||
|
</widget>
|
||||||
|
<addaction name="menuFile"/>
|
||||||
|
<addaction name="menuSetup"/>
|
||||||
|
</widget>
|
||||||
|
<widget class="QStatusBar" name="statusbar"/>
|
||||||
|
<action name="actionQuit">
|
||||||
|
<property name="text">
|
||||||
|
<string>Quit</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionCameras">
|
||||||
|
<property name="text">
|
||||||
|
<string>Cameras</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionCallibration">
|
||||||
|
<property name="text">
|
||||||
|
<string>Profile</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionSave">
|
||||||
|
<property name="text">
|
||||||
|
<string>Save</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>Led</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header location="global">./src/ui/led.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>CvImageViewer</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header location="global">./src/ui/cvimageviewer.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
37
src/ui/profiledialog.cpp
Normal file
37
src/ui/profiledialog.cpp
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#include "profiledialog.h"
|
||||||
|
#include "ui_profiledialog.h"
|
||||||
|
#include "editprofiledialog.h"
|
||||||
|
|
||||||
|
ProfileDialog::ProfileDialog(Cameras* cameras, QWidget *parent) :
|
||||||
|
QDialog(parent),
|
||||||
|
cameras_(cameras),
|
||||||
|
ui(new Ui::ProfileDialog)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
ui->listWidget->addItems(Profile::avaiableProfiles());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ProfileDialog::~ProfileDialog()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProfileDialog::editProfile()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ProfileDialog::addProfile()
|
||||||
|
{
|
||||||
|
Profile newProfile;
|
||||||
|
EditProfileDialog dialog(cameras_, &newProfile);
|
||||||
|
dialog.show();
|
||||||
|
int ret = dialog.exec();
|
||||||
|
if(ret == QDialog::Accepted)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
29
src/ui/profiledialog.h
Normal file
29
src/ui/profiledialog.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#ifndef PROFILEDIALOG_H
|
||||||
|
#define PROFILEDIALOG_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include "../cameras.h"
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class ProfileDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ProfileDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
Cameras* cameras_;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void addProfile();
|
||||||
|
void editProfile();
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit ProfileDialog(Cameras* cameras, QWidget *parent = nullptr);
|
||||||
|
~ProfileDialog();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::ProfileDialog *ui;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PROFILEDIALOG_H
|
92
src/ui/profiledialog.ui
Normal file
92
src/ui/profiledialog.ui
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>ProfileDialog</class>
|
||||||
|
<widget class="QDialog" name="ProfileDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>400</width>
|
||||||
|
<height>300</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Profiles</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Profiles:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QListWidget" name="listWidget"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="pushButtonEdit">
|
||||||
|
<property name="text">
|
||||||
|
<string>Edit</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="pushButtonAdd">
|
||||||
|
<property name="text">
|
||||||
|
<string>Add</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>ProfileDialog</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>ProfileDialog</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>
|
Reference in New Issue
Block a user