Finish up
This commit is contained in:
		
							parent
							
								
									5efbdcbd6a
								
							
						
					
					
						commit
						0c466644ce
					
				
					 23 changed files with 958 additions and 154 deletions
				
			
		|  | @ -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 | ||||
| ) | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -41,6 +41,17 @@ std::vector<cam::Camera::Description> Cameras::getCameras() | |||
| 	return desc; | ||||
| } | ||||
| 
 | ||||
| std::shared_ptr<Camera> Cameras::getCamera(size_t id) | ||||
| { | ||||
| 	std::vector<cam::Camera::Description> desc = getCameras(); | ||||
| 	for(size_t i = 0; i < desc.size(); ++i) | ||||
| 	{ | ||||
| 		if(desc[i].getHash() == id) | ||||
| 			return cameras_[i]; | ||||
| 	} | ||||
| 	return std::shared_ptr<Camera>(nullptr); | ||||
| } | ||||
| 
 | ||||
| bool Cameras::addCamera(const cam::Camera::Description& desc) | ||||
| { | ||||
| 	cameras_.push_back(std::shared_ptr<Camera>(new Camera(desc))); | ||||
|  |  | |||
|  | @ -49,6 +49,7 @@ public: | |||
| 	bool setCameras(const std::vector<cam::Camera::Description>& descriptions); | ||||
| 	bool addCamera(const cam::Camera::Description& desc); | ||||
| 	std::vector<cam::Camera::Description> getCameras(); | ||||
| 	std::shared_ptr<Camera> getCamera(size_t id); | ||||
| 	size_t numCameras(){return cameras_.size();} | ||||
| 	void clear(); | ||||
| 	Cameras(uvosled* led = nullptr); | ||||
|  |  | |||
|  | @ -72,3 +72,4 @@ void ImagePipeline::imageFinished() | |||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										45
									
								
								src/main.cpp
									
										
									
									
									
								
							
							
						
						
									
										45
									
								
								src/main.cpp
									
										
									
									
									
								
							|  | @ -8,28 +8,47 @@ | |||
| #include <QDir> | ||||
| #include <QThread> | ||||
| #include <opencv2/core/mat.hpp> | ||||
| #include <unistd.h> | ||||
| 
 | ||||
| #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<cam::Camera::Description> showCameraSelectionDialog() | ||||
| std::vector<cam::Camera::Description> showCameraSelectionDialog(bool* accepted = nullptr) | ||||
| { | ||||
| 	std::vector<cam::Camera::Description> 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<cam::Camera::Description> 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; | ||||
| } | ||||
|  |  | |||
|  | @ -3,16 +3,46 @@ | |||
| #include <QStandardPaths> | ||||
| #include <QFile> | ||||
| #include <QDir> | ||||
| #include <QDebug> | ||||
| #include <uvosunwrap/unwrap.h> | ||||
| 
 | ||||
| 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::loadDarkMap(const QString &filename) | ||||
| { | ||||
| 	darkmap = cv::imread(filename.toStdString()); | ||||
| } | ||||
| 
 | ||||
| void CameraSetup::loadBgMask(const QString &filename) | ||||
| { | ||||
| 	cv::FileStorage matf(filename.toStdString(), cv::FileStorage::READ); | ||||
| 	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,16 +74,18 @@ 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 "<<settings.fileName(); | ||||
| 	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_); | ||||
| 
 | ||||
| 	if(lightmap.data) | ||||
| 		cv::imwrite((profileLocation() + QString::number(id) + ".lightmap.png").toStdString(), lightmap); | ||||
| 
 | ||||
| 	settings.beginWriteArray(GROUP + QString("/cameras"), cameras.size()); | ||||
|  | @ -73,16 +120,18 @@ void Profile::load(QSettings &settings) | |||
| 
 | ||||
| void Profile::load(const QString& name) | ||||
| { | ||||
| 	QSettings settings(profileLocation() + name + ".profile.ini"); | ||||
| 	qDebug()<<profileLocation(); | ||||
| 	QSettings settings(profileLocation() + name + ".profile.ini", QSettings::IniFormat); | ||||
| 	name_=name; | ||||
| 	load(settings); | ||||
| } | ||||
| 
 | ||||
| void Profile::store(const QString& name) | ||||
| { | ||||
| 	QSettings settings(profileLocation() + name + ".profile.ini"); | ||||
| 	QSettings settings(profileLocation() + name + ".profile.ini", QSettings::IniFormat); | ||||
| 	name_=name; | ||||
| 	store(settings); | ||||
| 	settings.sync(); | ||||
| } | ||||
| 
 | ||||
| void Profile::load() | ||||
|  | @ -115,6 +164,18 @@ QList<QString> Profile::avaiableProfiles() | |||
| 	return  ret; | ||||
| } | ||||
| 
 | ||||
| void Profile::setCamerasSetupsFromDescription(const std::vector<cam::Camera::Description>& 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<cam::Camera::Description>& desc) const | ||||
| { | ||||
| 	bool invalid = false; | ||||
|  |  | |||
|  | @ -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<CameraSetup> 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<cam::Camera::Description>& desc); | ||||
| 	QString getName() const {return name_;} | ||||
| 	bool camerasSufficant(const std::vector<cam::Camera::Description>& desc) const; | ||||
| 	static QList<QString> avaiableProfiles(); | ||||
|  |  | |||
|  | @ -27,13 +27,6 @@ | |||
|    <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"> | ||||
|  | @ -50,7 +43,7 @@ | |||
|   <customwidget> | ||||
|    <class>CameraListWidget</class> | ||||
|    <extends>QListView</extends> | ||||
|    <header location="global">cameralistwidget.h</header> | ||||
|    <header location="global">./src/ui/cameralistwidget.h</header> | ||||
|   </customwidget> | ||||
|  </customwidgets> | ||||
|  <resources/> | ||||
|  |  | |||
|  | @ -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<bool> configured) | ||||
|  | @ -18,7 +19,10 @@ 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")); | ||||
| 	{ | ||||
| 		setItem(static_cast<int>(i), 1, new QTableWidgetItem("No")); | ||||
| 		qDebug()<<"Set item "<<i<<1; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void CameraListWidget::setCameras(const std::vector<cam::Camera::Description>& desc) | ||||
|  |  | |||
							
								
								
									
										186
									
								
								src/ui/configurecameradialog.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										186
									
								
								src/ui/configurecameradialog.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,186 @@ | |||
| #include "configurecameradialog.h" | ||||
| #include "ui_configurecameradialog.h" | ||||
| 
 | ||||
| #include <QFileDialog> | ||||
| #include <QMessageBox> | ||||
| #include <uvosunwrap/bgremoval.h> | ||||
| #include <uvosunwrap/charuco.h> | ||||
| #include <uvosunwrap/unwrap.h> | ||||
| #include <opencv2/imgproc.hpp> | ||||
| 
 | ||||
| ConfigureCameraDialog::ConfigureCameraDialog(const CameraSetup& setup, std::shared_ptr<Camera> 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<DetectedPoint> 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; | ||||
| } | ||||
							
								
								
									
										49
									
								
								src/ui/configurecameradialog.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								src/ui/configurecameradialog.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,49 @@ | |||
| #ifndef CONFIGURECAMERADIALOG_H | ||||
| #define CONFIGURECAMERADIALOG_H | ||||
| 
 | ||||
| #include <QDialog> | ||||
| #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> 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> camera, double exposureTime = 1.0/60, QWidget *parent = nullptr); | ||||
| 	~ConfigureCameraDialog(); | ||||
| 	CameraSetup getCameraSetup(){return setup_;} | ||||
| 	void accept() override; | ||||
| 
 | ||||
| private: | ||||
| 	Ui::ConfigureCameraDialog *ui; | ||||
| }; | ||||
| 
 | ||||
| #endif // CONFIGURECAMERADIALOG_H
 | ||||
							
								
								
									
										270
									
								
								src/ui/configurecameradialog.ui
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										270
									
								
								src/ui/configurecameradialog.ui
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,270 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <ui version="4.0"> | ||||
|  <class>ConfigureCameraDialog</class> | ||||
|  <widget class="QDialog" name="ConfigureCameraDialog"> | ||||
|   <property name="geometry"> | ||||
|    <rect> | ||||
|     <x>0</x> | ||||
|     <y>0</y> | ||||
|     <width>466</width> | ||||
|     <height>438</height> | ||||
|    </rect> | ||||
|   </property> | ||||
|   <property name="windowTitle"> | ||||
|    <string>Configure Camera</string> | ||||
|   </property> | ||||
|   <layout class="QVBoxLayout" name="verticalLayout_2" stretch="1,0,0,0"> | ||||
|    <item> | ||||
|     <widget class="QGroupBox" name="groupBox"> | ||||
|      <property name="title"> | ||||
|       <string>Camera output</string> | ||||
|      </property> | ||||
|      <layout class="QVBoxLayout" name="verticalLayout"> | ||||
|       <item> | ||||
|        <widget class="CvImageViewer" name="widget_4" native="true"/> | ||||
|       </item> | ||||
|      </layout> | ||||
|     </widget> | ||||
|    </item> | ||||
|    <item> | ||||
|     <layout class="QGridLayout" name="gridLayout"> | ||||
|      <property name="horizontalSpacing"> | ||||
|       <number>6</number> | ||||
|      </property> | ||||
|      <item row="2" column="0"> | ||||
|       <widget class="QLabel" name="label"> | ||||
|        <property name="text"> | ||||
|         <string>Dark image</string> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item row="2" column="4"> | ||||
|       <widget class="QPushButton" name="pushButtonDarkImageClear"> | ||||
|        <property name="enabled"> | ||||
|         <bool>false</bool> | ||||
|        </property> | ||||
|        <property name="text"> | ||||
|         <string>Clear</string> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item row="3" column="0"> | ||||
|       <widget class="QLabel" name="label_3"> | ||||
|        <property name="text"> | ||||
|         <string>Background image</string> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item row="2" column="3"> | ||||
|       <widget class="QPushButton" name="pushButtonDarkImageCreate"> | ||||
|        <property name="text"> | ||||
|         <string>Create</string> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item row="3" column="4"> | ||||
|       <widget class="QPushButton" name="pushButtonBgClear"> | ||||
|        <property name="enabled"> | ||||
|         <bool>false</bool> | ||||
|        </property> | ||||
|        <property name="text"> | ||||
|         <string>Clear</string> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item row="1" column="1"> | ||||
|       <widget class="Led" name="ledRemap" native="true"> | ||||
|        <property name="sizePolicy"> | ||||
|         <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> | ||||
|          <horstretch>0</horstretch> | ||||
|          <verstretch>0</verstretch> | ||||
|         </sizepolicy> | ||||
|        </property> | ||||
|        <property name="minimumSize"> | ||||
|         <size> | ||||
|          <width>0</width> | ||||
|          <height>0</height> | ||||
|         </size> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item row="1" column="4"> | ||||
|       <widget class="QPushButton" name="pushButtonRemapClear"> | ||||
|        <property name="enabled"> | ||||
|         <bool>false</bool> | ||||
|        </property> | ||||
|        <property name="text"> | ||||
|         <string>Clear</string> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item row="3" column="3"> | ||||
|       <widget class="QPushButton" name="pushButtonBgCreate"> | ||||
|        <property name="text"> | ||||
|         <string>Create</string> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item row="3" column="1"> | ||||
|       <widget class="Led" name="ledBg" native="true"/> | ||||
|      </item> | ||||
|      <item row="1" column="0"> | ||||
|       <widget class="QLabel" name="label_2"> | ||||
|        <property name="text"> | ||||
|         <string>Remap Map</string> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item row="1" column="2"> | ||||
|       <widget class="QPushButton" name="pushButtonRemapLoad"> | ||||
|        <property name="text"> | ||||
|         <string>Load</string> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item row="3" column="2"> | ||||
|       <widget class="QPushButton" name="pushButtonBgLoad"> | ||||
|        <property name="text"> | ||||
|         <string>Load</string> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item row="2" column="1"> | ||||
|       <widget class="Led" name="ledDark" native="true"> | ||||
|        <property name="sizePolicy"> | ||||
|         <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> | ||||
|          <horstretch>0</horstretch> | ||||
|          <verstretch>0</verstretch> | ||||
|         </sizepolicy> | ||||
|        </property> | ||||
|        <property name="minimumSize"> | ||||
|         <size> | ||||
|          <width>0</width> | ||||
|          <height>0</height> | ||||
|         </size> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item row="2" column="2"> | ||||
|       <widget class="QPushButton" name="pushButtonDarkImageLoad"> | ||||
|        <property name="text"> | ||||
|         <string>Load</string> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item row="1" column="3"> | ||||
|       <widget class="QPushButton" name="pushButtonRemapCreate"> | ||||
|        <property name="text"> | ||||
|         <string>Create</string> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item row="4" column="0"> | ||||
|       <widget class="QLabel" name="label_4"> | ||||
|        <property name="text"> | ||||
|         <string/> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|     </layout> | ||||
|    </item> | ||||
|    <item> | ||||
|     <layout class="QHBoxLayout" name="horizontalLayout"> | ||||
|      <property name="topMargin"> | ||||
|       <number>5</number> | ||||
|      </property> | ||||
|      <item> | ||||
|       <widget class="QLabel" name="label_5"> | ||||
|        <property name="text"> | ||||
|         <string>Exposure Time for Map creation</string> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item> | ||||
|       <widget class="QDoubleSpinBox" name="doubleSpinBox"> | ||||
|        <property name="maximum"> | ||||
|         <double>1.000000000000000</double> | ||||
|        </property> | ||||
|        <property name="singleStep"> | ||||
|         <double>0.100000000000000</double> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item> | ||||
|       <widget class="QLabel" name="label_6"> | ||||
|        <property name="text"> | ||||
|         <string>s</string> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item> | ||||
|       <widget class="QPushButton" name="pushButtonCapture"> | ||||
|        <property name="text"> | ||||
|         <string>Test Exposure</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::Cancel|QDialogButtonBox::Ok</set> | ||||
|      </property> | ||||
|     </widget> | ||||
|    </item> | ||||
|   </layout> | ||||
|  </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> | ||||
|   <connection> | ||||
|    <sender>buttonBox</sender> | ||||
|    <signal>accepted()</signal> | ||||
|    <receiver>ConfigureCameraDialog</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>ConfigureCameraDialog</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> | ||||
|  | @ -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_); | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -1,13 +1,110 @@ | |||
| #include "editprofiledialog.h" | ||||
| #include "ui_editprofiledialog.h" | ||||
| #include <uvosled.h> | ||||
| #include <QDebug> | ||||
| 
 | ||||
| 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: "<<profile_.lighting.mask<<" & "<<(profile_.lighting.mask & CHANNEL_A); | ||||
| 
 | ||||
| 	ui->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<double>::of(&QDoubleSpinBox::valueChanged), [this](double in){profile_.lighting.brightness = in/100.0;}); | ||||
| 	connect(ui->doubleSpinBoxExposure, QOverload<double>::of(&QDoubleSpinBox::valueChanged), [this](double in){profile_.exposureTime = in;}); | ||||
| 	connect(ui->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<cam::Camera::Description> descs = cameras_->getCameras(); | ||||
| 	std::vector<bool> 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<cam::Camera::Description> descs = ui->listView->getSelectedDescriptions(); | ||||
| 	qDebug()<<"descs"<<descs.size(); | ||||
| 	if(!descs.empty()) | ||||
| 	{ | ||||
| 		size_t i = 0; | ||||
| 		for(; i < profile_.cameras.size(); ++i) | ||||
| 		{ | ||||
| 			if(profile_.cameras[i].id == descs[0].getHash()) | ||||
| 			{ | ||||
| 				std::shared_ptr<Camera> 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() | ||||
|  |  | |||
|  | @ -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: | ||||
|  |  | |||
|  | @ -11,7 +11,7 @@ | |||
|    </rect> | ||||
|   </property> | ||||
|   <property name="windowTitle"> | ||||
|    <string>Dialog</string> | ||||
|    <string>Profile</string> | ||||
|   </property> | ||||
|   <layout class="QVBoxLayout" name="verticalLayout_3"> | ||||
|    <item> | ||||
|  | @ -24,10 +24,99 @@ | |||
|       </widget> | ||||
|      </item> | ||||
|      <item> | ||||
|       <widget class="QLineEdit" name="lineEditName"/> | ||||
|       <widget class="QLineEdit" name="lineEditName"> | ||||
|        <property name="text"> | ||||
|         <string>Unamed</string> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|     </layout> | ||||
|    </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"> | ||||
|           <property name="maximum"> | ||||
|            <double>100.000000000000000</double> | ||||
|           </property> | ||||
|          </widget> | ||||
|         </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="QGroupBox" name="groupBox"> | ||||
|      <property name="title"> | ||||
|  | @ -90,87 +179,6 @@ | |||
|      </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"> | ||||
|  |  | |||
|  | @ -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)); | ||||
| } | ||||
|  |  | |||
|  | @ -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> camera) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| bool MainWindow::setProfile(const QString& profileName) | ||||
| { | ||||
| 	ui->comboBox->clear(); | ||||
| 	QList<QString> 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(); | ||||
|  |  | |||
|  | @ -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> camera); | ||||
| 	bool setProfile(const QString& profileName); | ||||
| 	QString getProfileName(); | ||||
| 
 | ||||
| public: | ||||
| 	MainWindow(QWidget *parent = nullptr); | ||||
|  |  | |||
|  | @ -68,7 +68,7 @@ | |||
|                 <x>0</x> | ||||
|                 <y>0</y> | ||||
|                 <width>467</width> | ||||
|                 <height>315</height> | ||||
|                 <height>353</height> | ||||
|                </rect> | ||||
|               </property> | ||||
|               <layout class="QVBoxLayout" name="verticalLayout_6"> | ||||
|  | @ -124,36 +124,6 @@ | |||
|              </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> | ||||
|  | @ -184,7 +154,7 @@ | |||
|      <string>Settings</string> | ||||
|     </property> | ||||
|     <addaction name="actionCameras"/> | ||||
|     <addaction name="actionCallibration"/> | ||||
|     <addaction name="actionProfile"/> | ||||
|    </widget> | ||||
|    <addaction name="menuFile"/> | ||||
|    <addaction name="menuSetup"/> | ||||
|  | @ -200,7 +170,7 @@ | |||
|     <string>Cameras</string> | ||||
|    </property> | ||||
|   </action> | ||||
|   <action name="actionCallibration"> | ||||
|   <action name="actionProfile"> | ||||
|    <property name="text"> | ||||
|     <string>Profile</string> | ||||
|    </property> | ||||
|  | @ -212,12 +182,6 @@ | |||
|   </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> | ||||
|  |  | |||
|  | @ -2,6 +2,8 @@ | |||
| #include "ui_profiledialog.h" | ||||
| #include "editprofiledialog.h" | ||||
| 
 | ||||
| #include <QMessageBox> | ||||
| 
 | ||||
| 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() | ||||
| { | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void ProfileDialog::addProfile() | ||||
| { | ||||
| 	Profile newProfile; | ||||
| 	EditProfileDialog dialog(cameras_, &newProfile); | ||||
| 	QList<QListWidgetItem *> 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<QListWidgetItem *> 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() | ||||
| { | ||||
| 	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()); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -17,6 +17,7 @@ class ProfileDialog : public QDialog | |||
| private slots: | ||||
| 	void addProfile(); | ||||
| 	void editProfile(); | ||||
| 	void deleteProfile(); | ||||
| 
 | ||||
| public: | ||||
| 	explicit ProfileDialog(Cameras* cameras, QWidget *parent = nullptr); | ||||
|  |  | |||
|  | @ -40,6 +40,13 @@ | |||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item> | ||||
|       <widget class="QPushButton" name="pushButtonDelete"> | ||||
|        <property name="text"> | ||||
|         <string>Delete</string> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|     </layout> | ||||
|    </item> | ||||
|    <item> | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue