various bug fixes around free trigger mode, display strings and image pipe robustness
This commit is contained in:
		
							parent
							
								
									86ec50575b
								
							
						
					
					
						commit
						d5af9adec9
					
				
					 12 changed files with 85 additions and 25 deletions
				
			
		| 
						 | 
				
			
			@ -52,6 +52,6 @@ set(PROJECT_SOURCES
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
add_executable(MAClient ${PROJECT_SOURCES})
 | 
			
		||||
 | 
			
		||||
target_compile_options(MAClient PRIVATE "-std=gnu++17" "-Wall" "-O2" "-fno-strict-aliasing")
 | 
			
		||||
target_link_libraries(MAClient PRIVATE Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Concurrent ${OpenCV_LIBS} -luvoscam -luvosled -luvosunwrap)
 | 
			
		||||
target_include_directories(${PROJECT_NAME} PRIVATE ${OpenCV_INCLUDE_DIRS} src src/ui)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -111,7 +111,7 @@ bool Cameras::start()
 | 
			
		|||
			ret = false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(free_)
 | 
			
		||||
	if(free_ && led_)
 | 
			
		||||
		uvosled_set_current(led_, lighting_.mask, lighting_.brightness);
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
| 
						 | 
				
			
			@ -146,9 +146,11 @@ bool Cameras::setFree(bool free)
 | 
			
		|||
	{
 | 
			
		||||
		if(!camera->cam()->setAcquisitionMode(free ? cam::Camera::MODE_FREE : cam::Camera::MODE_SINGLE))
 | 
			
		||||
		{
 | 
			
		||||
			qDebug()<<"failed to set single on camera"<<camera->id();
 | 
			
		||||
			qDebug()<<"failed to set acquisition mode on camera"<<camera->id();
 | 
			
		||||
			ret = false;
 | 
			
		||||
		}
 | 
			
		||||
		if(ret)
 | 
			
		||||
			camera->cam()->setTriggerMode(free ? cam::Camera::TRIGGER_FREE : cam::Camera::TRIGGER_SOFTWARE);
 | 
			
		||||
	}
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -173,13 +175,14 @@ void Cameras::imageRecived(Camera::Image img)
 | 
			
		|||
{
 | 
			
		||||
	if(!disable_)
 | 
			
		||||
	{
 | 
			
		||||
		qDebug()<<"free"<<free_;
 | 
			
		||||
		bool allreadyUpdated = false;
 | 
			
		||||
		for(auto& image : images_)
 | 
			
		||||
		{
 | 
			
		||||
			if(image.cameraId == img.cameraId)
 | 
			
		||||
			{
 | 
			
		||||
				allreadyUpdated = true;
 | 
			
		||||
				break;;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,10 +1,11 @@
 | 
			
		|||
#include "imagepipeline.h"
 | 
			
		||||
#include "imagepipeline.h"
 | 
			
		||||
#include <uvosunwrap/unwrap.h>
 | 
			
		||||
#include <uvosunwrap/normalize.h>
 | 
			
		||||
#include <uvosunwrap/curve.h>
 | 
			
		||||
#include <QtConcurrent/QtConcurrentRun>
 | 
			
		||||
#include <QFuture>
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
 | 
			
		||||
ImagePipeline::ImagePipeline(Cameras* cameras, QObject *parent): QObject(parent), cameras_(cameras)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -46,6 +47,8 @@ cv::Mat ImagePipeline::process(const Profile profile, std::vector<Camera::Image>
 | 
			
		|||
				{
 | 
			
		||||
					if(camera.id == image.cameraId)
 | 
			
		||||
					{
 | 
			
		||||
						if(!camera.remapMap.xMat.data || !camera.remapMap.yMat.data)
 | 
			
		||||
							return cv::Mat();
 | 
			
		||||
						if(camera.darkmap.data)
 | 
			
		||||
						{
 | 
			
		||||
							cv::Mat subtracted;
 | 
			
		||||
| 
						 | 
				
			
			@ -67,7 +70,7 @@ cv::Mat ImagePipeline::process(const Profile profile, std::vector<Camera::Image>
 | 
			
		|||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	catch(cv::Exception ex)
 | 
			
		||||
	catch(cv::Exception& ex)
 | 
			
		||||
	{
 | 
			
		||||
		qDebug()<<ex.err.c_str();
 | 
			
		||||
		qDebug()<<"Image pipe failure";
 | 
			
		||||
| 
						 | 
				
			
			@ -76,11 +79,25 @@ cv::Mat ImagePipeline::process(const Profile profile, std::vector<Camera::Image>
 | 
			
		|||
 | 
			
		||||
	if(remapedImages.size() > 0)
 | 
			
		||||
	{
 | 
			
		||||
		std::sort(remapedImages.begin(), remapedImages.end(),  [](const RemapedImage& imgA, const RemapedImage& imgB) -> bool {return imgA.origin.x < imgB.origin.x;});
 | 
			
		||||
		cv::Mat output = simpleStich(remapedImages);
 | 
			
		||||
		output.convertTo(output, CV_32FC1, 1.0/255.0, 0);
 | 
			
		||||
 | 
			
		||||
		if(profile.lightmap.data)
 | 
			
		||||
			normalize(output, profile.lightmap);
 | 
			
		||||
		{
 | 
			
		||||
			qDebug()<<"output"<<output.type()<<output.cols<<output.rows;
 | 
			
		||||
			qDebug()<<"profile.lightmap"<<profile.lightmap.type()<<profile.lightmap.cols<<profile.lightmap.rows;
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				output = output.mul(profile.lightmap);
 | 
			
		||||
			}
 | 
			
		||||
			catch(cv::Exception& ex)
 | 
			
		||||
			{
 | 
			
		||||
				qDebug()<<ex.err.c_str();
 | 
			
		||||
				qDebug()<<"Image pipe failure";
 | 
			
		||||
				return cv::Mat();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if(profile.calcurve.data)
 | 
			
		||||
			applyCurve(output, profile.calcurve);
 | 
			
		||||
| 
						 | 
				
			
			@ -116,7 +133,7 @@ void ImagePipeline::setProfile(const Profile& profile)
 | 
			
		|||
	{
 | 
			
		||||
		qDebug()<<setup.id;
 | 
			
		||||
		//TODO: dehardcode this
 | 
			
		||||
		setup.remapMap.outputCellSize=200;
 | 
			
		||||
		setup.remapMap.outputCellSize=150;
 | 
			
		||||
	}
 | 
			
		||||
	invalid_ = false;
 | 
			
		||||
	if(!profile_.camerasSufficant(cameras_->getCameras()))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -90,6 +90,7 @@ int main(int argc, char *argv[])
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	Cameras cameras(uvosledRet < 0 ? nullptr : &led);
 | 
			
		||||
	cameras.setFree(false);
 | 
			
		||||
	ImagePipeline pipe(&cameras);
 | 
			
		||||
 | 
			
		||||
	MainWindow w;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -57,6 +57,7 @@ void LightingSetup::load(const QSettings& settings)
 | 
			
		|||
 | 
			
		||||
void Profile::store(QSettings& settings) const
 | 
			
		||||
{
 | 
			
		||||
	deleteProfile();
 | 
			
		||||
	qDebug()<<"storing to "<<settings.fileName();
 | 
			
		||||
	lighting.store(settings);
 | 
			
		||||
	settings.setValue(GROUP + QString("/id"), static_cast<unsigned long long>(id));
 | 
			
		||||
| 
						 | 
				
			
			@ -143,9 +144,12 @@ void Profile::store()
 | 
			
		|||
	store(name_);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Profile::deleteProfile()
 | 
			
		||||
void Profile::deleteProfile() const
 | 
			
		||||
{
 | 
			
		||||
	QFile::remove(profileLocation() + name_ + ".profile.ini");
 | 
			
		||||
	QFile::remove(profileLocation() + name_ + ".lightmap.mat");
 | 
			
		||||
	QFile::remove(profileLocation() + name_ + ".calcurve.mat");
 | 
			
		||||
	QFile::remove(profileLocation() + name_ + ".profile.mat");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QList<QString> Profile::avaiableProfiles()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -54,7 +54,7 @@ public:
 | 
			
		|||
	void load(QSettings& settings);
 | 
			
		||||
	void load(const QString& name);
 | 
			
		||||
	void load();
 | 
			
		||||
	void deleteProfile();
 | 
			
		||||
	void deleteProfile() const;
 | 
			
		||||
	void setName(const QString name){name_=name;}
 | 
			
		||||
	void setCamerasSetupsFromDescription(const std::vector<cam::Camera::Description>& desc);
 | 
			
		||||
	QString getName() const {return name_;}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,6 +35,8 @@ ConfigureCameraDialog::ConfigureCameraDialog(const CameraSetup& setup, std::shar
 | 
			
		|||
	connect(ui->pushButtonDarkImageCreate, &QPushButton::clicked, this, &ConfigureCameraDialog::captureDark);
 | 
			
		||||
	connect(ui->pushButtonCapture, &QPushButton::clicked, this, &ConfigureCameraDialog::takeImage);
 | 
			
		||||
	connect(camera_.get(), &Camera::newImage, this, &ConfigureCameraDialog::gotImage);
 | 
			
		||||
	connect(ui->pushButtonBgShow, &QPushButton::clicked, [this](){if(setup_.bgmask.data) ui->widget_4->setImage(Camera::Image(setup_.bgmask, 0));});
 | 
			
		||||
	connect(ui->pushButtonDarkImageShow, &QPushButton::clicked, [this](){if(setup_.darkmap.data) ui->widget_4->setImage(Camera::Image(setup_.darkmap, 0));});
 | 
			
		||||
 | 
			
		||||
	checkConfig();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -157,6 +159,8 @@ bool ConfigureCameraDialog::checkConfig()
 | 
			
		|||
	ui->pushButtonBgClear->setEnabled(bgOk);
 | 
			
		||||
	ui->pushButtonDarkImageClear->setEnabled(darkMapOK);
 | 
			
		||||
	ui->pushButtonRemapClear->setEnabled(remapMapOk);
 | 
			
		||||
	ui->pushButtonDarkImageShow->setEnabled(darkMapOK);
 | 
			
		||||
	ui->pushButtonBgShow->setEnabled(bgOk);
 | 
			
		||||
 | 
			
		||||
	ui->ledBg->setLit(bgOk);
 | 
			
		||||
	ui->ledDark->setLit(darkMapOK);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -97,6 +97,9 @@
 | 
			
		|||
     </item>
 | 
			
		||||
     <item row="2" column="2">
 | 
			
		||||
      <widget class="QPushButton" name="pushButtonDarkImageShow">
 | 
			
		||||
       <property name="enabled">
 | 
			
		||||
        <bool>false</bool>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="text">
 | 
			
		||||
        <string>Show</string>
 | 
			
		||||
       </property>
 | 
			
		||||
| 
						 | 
				
			
			@ -120,6 +123,9 @@
 | 
			
		|||
     </item>
 | 
			
		||||
     <item row="3" column="2">
 | 
			
		||||
      <widget class="QPushButton" name="pushButtonBgShow">
 | 
			
		||||
       <property name="enabled">
 | 
			
		||||
        <bool>false</bool>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="text">
 | 
			
		||||
        <string>Show</string>
 | 
			
		||||
       </property>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -65,7 +65,12 @@ void CvImageViewer::setImage(Camera::Image img)
 | 
			
		|||
	}
 | 
			
		||||
	else if(image_.type() == CV_32FC1 || image_.type() == CV_64FC1)
 | 
			
		||||
	{
 | 
			
		||||
		img.mat.convertTo(image_, CV_8UC1, 255, 0);
 | 
			
		||||
		double min, max;
 | 
			
		||||
		cv::minMaxIdx(img.mat, &min, &max);
 | 
			
		||||
		double a = 255.0/(max - min);
 | 
			
		||||
		double b = 0-(min*a);
 | 
			
		||||
		qDebug()<<min<<max<<a<<b;
 | 
			
		||||
		img.mat.convertTo(image_, CV_8UC1, a, b);
 | 
			
		||||
		qimage_ = QImage(image_.data, image_.cols, image_.rows, image_.step, QImage::Format_Grayscale8);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,6 +4,7 @@
 | 
			
		|||
#include <QDebug>
 | 
			
		||||
#include <QMessageBox>
 | 
			
		||||
#include <QFileDialog>
 | 
			
		||||
#include <opencv2/imgproc.hpp>
 | 
			
		||||
 | 
			
		||||
#include "configurecameradialog.h"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -44,6 +45,7 @@ EditProfileDialog::EditProfileDialog(Cameras* cameras, const Profile profile, QW
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	ui->calLed->setLit(profile_.calcurve.data);
 | 
			
		||||
	ui->ledLightmap->setLit(profile_.lightmap.data);
 | 
			
		||||
 | 
			
		||||
	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; invalidateCameras();});
 | 
			
		||||
| 
						 | 
				
			
			@ -53,9 +55,11 @@ EditProfileDialog::EditProfileDialog(Cameras* cameras, const Profile profile, QW
 | 
			
		|||
	connect(ui->checkBoxCh3, &QCheckBox::clicked, this, &EditProfileDialog::setMask);
 | 
			
		||||
	connect(ui->checkBoxCh4, &QCheckBox::clicked, this, &EditProfileDialog::setMask);
 | 
			
		||||
	connect(ui->pushButton, &QPushButton::clicked, this, &EditProfileDialog::configureCamera);
 | 
			
		||||
	connect(ui->checkBoxNodistort, &QCheckBox::stateChanged, [this](int state){profile_.nodistort = state == Qt::Checked ?: false; setConfigured();});
 | 
			
		||||
	connect(ui->checkBoxNodistort, &QCheckBox::stateChanged, [this](int state){profile_.nodistort = state == Qt::Checked; setConfigured();});
 | 
			
		||||
	connect(ui->pushButtonCalLoad, &QPushButton::clicked, this, &EditProfileDialog::loadCalcurve);
 | 
			
		||||
	connect(ui->pushButtonLightmapLoad, &QPushButton::clicked, this, &EditProfileDialog::loadCalcurve);
 | 
			
		||||
	connect(ui->pushButtonLightmapLoad, &QPushButton::clicked, this, &EditProfileDialog::loadLightmap);
 | 
			
		||||
	connect(ui->pushButtonCalClear,  &QPushButton::clicked, [this](){profile_.calcurve.release(); ui->calLed->setLit(profile_.calcurve.data);});
 | 
			
		||||
	connect(ui->pushButtonLightmapClear,  &QPushButton::clicked, [this](){profile_.lightmap.release(); ui->ledLightmap->setLit(profile_.lightmap.data);});
 | 
			
		||||
	ui->listView->setCameras(cameras_->getCameras());
 | 
			
		||||
	ui->listView->setSelectionMode(QAbstractItemView::SingleSelection);
 | 
			
		||||
	setConfigured();
 | 
			
		||||
| 
						 | 
				
			
			@ -66,20 +70,22 @@ void EditProfileDialog::loadLightmap()
 | 
			
		|||
	QString fileName = QFileDialog::getOpenFileName(this, "Open Lightmap", "./", "*.mat");
 | 
			
		||||
	if(!fileName.isEmpty())
 | 
			
		||||
	{
 | 
			
		||||
		profile_.calcurve.release();
 | 
			
		||||
		profile_.lightmap.release();
 | 
			
		||||
		cv::FileStorage matf(fileName.toStdString(), cv::FileStorage::READ);
 | 
			
		||||
		matf["image"]>>profile_.lightmap;
 | 
			
		||||
 | 
			
		||||
		if(matf.isOpened() && (!profile_.calcurve.data || profile_.calcurve.type() != CV_32FC1))
 | 
			
		||||
		matf.release();
 | 
			
		||||
		if(matf.isOpened() && (!profile_.lightmap.data || profile_.lightmap.type() != CV_32FC1))
 | 
			
		||||
		{
 | 
			
		||||
			profile_.lightmap.release();
 | 
			
		||||
			QMessageBox::warning(this, "Invalid file", "File selected dose not contain a valid lightmap");
 | 
			
		||||
		}
 | 
			
		||||
		else if(!profile_.calcurve.data)
 | 
			
		||||
		else if(!profile_.lightmap.data)
 | 
			
		||||
		{
 | 
			
		||||
			QMessageBox::warning(this, "Can no open", "Can not open file selected");
 | 
			
		||||
		}
 | 
			
		||||
		matf.release();
 | 
			
		||||
		profile_.lightmap = cv::mean(profile_.lightmap)/profile_.lightmap;
 | 
			
		||||
		cv::GaussianBlur(profile_.lightmap, profile_.lightmap, cv::Size(51,51), 8);
 | 
			
		||||
 | 
			
		||||
		ui->ledLightmap->setLit(profile_.lightmap.data);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -201,6 +201,13 @@
 | 
			
		|||
       </property>
 | 
			
		||||
      </widget>
 | 
			
		||||
     </item>
 | 
			
		||||
     <item row="1" column="0">
 | 
			
		||||
      <widget class="QLabel" name="label_8">
 | 
			
		||||
       <property name="text">
 | 
			
		||||
        <string>Lightmap:</string>
 | 
			
		||||
       </property>
 | 
			
		||||
      </widget>
 | 
			
		||||
     </item>
 | 
			
		||||
     <item row="0" column="1">
 | 
			
		||||
      <widget class="Led" name="calLed" native="true">
 | 
			
		||||
       <property name="sizePolicy">
 | 
			
		||||
| 
						 | 
				
			
			@ -230,10 +237,10 @@
 | 
			
		|||
       </property>
 | 
			
		||||
      </widget>
 | 
			
		||||
     </item>
 | 
			
		||||
     <item row="1" column="0">
 | 
			
		||||
      <widget class="QLabel" name="label_8">
 | 
			
		||||
     <item row="1" column="2">
 | 
			
		||||
      <widget class="QPushButton" name="pushButtonLightmapLoad">
 | 
			
		||||
       <property name="text">
 | 
			
		||||
        <string>Lightmap:</string>
 | 
			
		||||
        <string>Load</string>
 | 
			
		||||
       </property>
 | 
			
		||||
      </widget>
 | 
			
		||||
     </item>
 | 
			
		||||
| 
						 | 
				
			
			@ -253,10 +260,17 @@
 | 
			
		|||
       </property>
 | 
			
		||||
      </widget>
 | 
			
		||||
     </item>
 | 
			
		||||
     <item row="1" column="2">
 | 
			
		||||
      <widget class="QPushButton" name="pushButtonLightmapLoad">
 | 
			
		||||
     <item row="0" column="3">
 | 
			
		||||
      <widget class="QPushButton" name="pushButtonCalClear">
 | 
			
		||||
       <property name="text">
 | 
			
		||||
        <string>Load</string>
 | 
			
		||||
        <string>Clear</string>
 | 
			
		||||
       </property>
 | 
			
		||||
      </widget>
 | 
			
		||||
     </item>
 | 
			
		||||
     <item row="1" column="3">
 | 
			
		||||
      <widget class="QPushButton" name="pushButtonLightmapClear">
 | 
			
		||||
       <property name="text">
 | 
			
		||||
        <string>Clear</string>
 | 
			
		||||
       </property>
 | 
			
		||||
      </widget>
 | 
			
		||||
     </item>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -63,7 +63,7 @@ void MainWindow::openImage()
 | 
			
		|||
		if(matf.isOpened() && (!image.data || image.type() != CV_32FC1))
 | 
			
		||||
		{
 | 
			
		||||
			image.release();
 | 
			
		||||
			QMessageBox::warning(this, "Invalid file", "File selected dose not contain a valid lightmap");
 | 
			
		||||
			QMessageBox::warning(this, "Invalid file", "File selected dose not contain a valid image");
 | 
			
		||||
		}
 | 
			
		||||
		else if(!image.data)
 | 
			
		||||
		{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue