change stiching method
add camera temperature readout
This commit is contained in:
@ -20,8 +20,8 @@ public:
|
||||
{
|
||||
public:
|
||||
cv::Mat mat;
|
||||
size_t cameraId;
|
||||
Image(cv::Mat mati, size_t cameraIdi): mat(mati), cameraId(cameraIdi){}
|
||||
uint64_t cameraId;
|
||||
Image(cv::Mat mati, uint64_t cameraIdi): mat(mati), cameraId(cameraIdi){}
|
||||
Image() = default;
|
||||
Image(const Image& img) = default;
|
||||
};
|
||||
@ -29,7 +29,7 @@ private:
|
||||
cam::Camera* camera_ = nullptr;
|
||||
|
||||
void callback(cv::Mat);
|
||||
size_t cameraId_;
|
||||
uint64_t cameraId_;
|
||||
|
||||
signals:
|
||||
void newImage(Image);
|
||||
@ -38,7 +38,7 @@ public:
|
||||
Camera(cam::Camera::Description);
|
||||
~Camera();
|
||||
cam::Camera* cam(){return camera_;}
|
||||
size_t id() const {return cameraId_;}
|
||||
uint64_t id() const {return cameraId_;}
|
||||
bool operator==(const Camera& cam){return cam.id() == id();}
|
||||
bool operator!=(const Camera& cam){return !operator==(cam);}
|
||||
};
|
||||
|
@ -9,7 +9,9 @@
|
||||
Cameras::Cameras(uvosled* led): led_(led)
|
||||
{
|
||||
ledTimer.setSingleShot(true);
|
||||
cameraFailureTimer.setSingleShot(true);
|
||||
connect(&ledTimer, &QTimer::timeout, this, &Cameras::lightOff);
|
||||
connect(&cameraFailureTimer, &QTimer::timeout, this, &Cameras::reloadCameras);
|
||||
}
|
||||
|
||||
Cameras::~Cameras()
|
||||
@ -29,6 +31,11 @@ bool Cameras::setCameras(const std::vector<cam::Camera::Description>& descriptio
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Cameras::reloadCameras()
|
||||
{
|
||||
setCameras(getCameras());
|
||||
}
|
||||
|
||||
|
||||
void Cameras::clear()
|
||||
{
|
||||
@ -70,6 +77,9 @@ bool Cameras::addCamera(const cam::Camera::Description& desc)
|
||||
return false;
|
||||
}
|
||||
|
||||
enableCapture(false);
|
||||
blockCaptureId_ = cameras_.back()->id();
|
||||
|
||||
cameras_.back()->cam()->setExposureTime(exposrueTime_);
|
||||
|
||||
if(desc.getVendor().find("Photonfocus") != std::string::npos)
|
||||
@ -80,11 +90,11 @@ bool Cameras::addCamera(const cam::Camera::Description& desc)
|
||||
camera->cam()->setAcquisitionMode(cam::Camera::MODE_FREE);
|
||||
camera->cam()->setFrameRate(10);
|
||||
camera->cam()->startAcquisition();
|
||||
struct timespec tv = {0, 200000000};
|
||||
nanosleep(&tv, nullptr);
|
||||
std::this_thread::sleep_for (std::chrono::milliseconds(200));
|
||||
camera->cam()->stopAcquisition();
|
||||
cameras_.pop_back();
|
||||
camera = nullptr;
|
||||
std::this_thread::sleep_for (std::chrono::milliseconds(200));
|
||||
cameras_.push_back(std::shared_ptr<Camera>(new Camera(desc)));
|
||||
if(!cameras_.back()->cam()->isOpen())
|
||||
{
|
||||
@ -112,6 +122,8 @@ void Cameras::finishAddCamera(std::shared_ptr<Camera> camera)
|
||||
camera->cam()->setTriggerMode(cam::Camera::TRIGGER_SOFTWARE);
|
||||
setFree(free_);
|
||||
connect(camera.get(), &Camera::newImage, this, &Cameras::imageRecived);
|
||||
if(blockCaptureId_ == camera->id())
|
||||
enableCapture(true);
|
||||
qDebug()<<"Using camera"<<camera->id();
|
||||
}
|
||||
|
||||
@ -229,8 +241,12 @@ void Cameras::imageRecived(Camera::Image img)
|
||||
|
||||
qDebug()<<"Recived"<<images_.size()<<"of"<<cameras_.size()<<"images";
|
||||
|
||||
if(images_.size() == 1)
|
||||
cameraFailureTimer.start(exposrueTime_*1000+1000);
|
||||
|
||||
if(images_.size() == cameras_.size())
|
||||
{
|
||||
cameraFailureTimer.stop();
|
||||
newImages(images_);
|
||||
images_.clear();
|
||||
}
|
||||
@ -238,6 +254,24 @@ void Cameras::imageRecived(Camera::Image img)
|
||||
}
|
||||
}
|
||||
|
||||
double Cameras::getMeanTemp()
|
||||
{
|
||||
double mean = 0;
|
||||
bool failure = false;
|
||||
for(auto& camera : cameras_)
|
||||
{
|
||||
double temp;
|
||||
if(camera->cam()->getTemperature(temp))
|
||||
mean+=temp;
|
||||
else
|
||||
failure = true;
|
||||
}
|
||||
if(!failure)
|
||||
return mean/cameras_.size();
|
||||
else
|
||||
return NAN;
|
||||
}
|
||||
|
||||
void Cameras::setSetup(const std::vector<CameraSetup>& setups)
|
||||
{
|
||||
for(auto& camera : cameras_)
|
||||
|
@ -26,10 +26,12 @@ private:
|
||||
bool free_ = false;
|
||||
bool disable_ = false;
|
||||
double exposrueTime_ = 1.0/60.0;
|
||||
uint64_t blockCaptureId_ = 0;
|
||||
LightingSetup lighting_;
|
||||
std::vector<std::shared_ptr<Camera>> cameras_;
|
||||
std::vector<Camera::Image> images_;
|
||||
QTimer ledTimer;
|
||||
QTimer cameraFailureTimer;
|
||||
|
||||
bool lightFor(const LightingSetup& lighting, double time);
|
||||
|
||||
@ -42,6 +44,7 @@ signals:
|
||||
void cameraRemoved(std::shared_ptr<Camera> camera);
|
||||
void cameraAdded(std::shared_ptr<Camera> camera);
|
||||
void newImages(std::vector<Camera::Image> images);
|
||||
void enableCapture(bool enable);
|
||||
|
||||
public slots:
|
||||
|
||||
@ -51,6 +54,7 @@ public slots:
|
||||
bool stop();
|
||||
bool setFree(bool free);
|
||||
void setLighting(const LightingSetup& lighting) {lighting_ = lighting;}
|
||||
void reloadCameras();
|
||||
|
||||
public:
|
||||
Cameras(uvosled* led = nullptr);
|
||||
@ -62,6 +66,7 @@ public:
|
||||
std::shared_ptr<Camera> getCamera(size_t id);
|
||||
size_t numCameras(){return cameras_.size();}
|
||||
void clear();
|
||||
double getMeanTemp();
|
||||
void load(QSettings& settings);
|
||||
void store(QSettings& settings);
|
||||
void disable(bool disable);
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <QFuture>
|
||||
#include <QDebug>
|
||||
#include <algorithm>
|
||||
#include <opencv2/highgui.hpp>
|
||||
|
||||
ImagePipeline::ImagePipeline(Cameras* cameras, QObject *parent): QObject(parent), cameras_(cameras)
|
||||
{
|
||||
@ -14,7 +15,7 @@ ImagePipeline::ImagePipeline(Cameras* cameras, QObject *parent): QObject(parent)
|
||||
|
||||
cv::Mat ImagePipeline::process(const Profile profile, std::vector<Camera::Image> images)
|
||||
{
|
||||
qDebug()<<__FUNCTION__<<"got"<<images.size()<<"images";
|
||||
qDebug()<<__func__<<"got"<<images.size()<<"images";
|
||||
std::vector<RemapedImage> remapedImages;
|
||||
remapedImages.reserve(images.size());
|
||||
|
||||
@ -80,7 +81,13 @@ 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);
|
||||
cv::Mat output = stich(remapedImages);
|
||||
|
||||
if(output.depth() != CV_8U)
|
||||
output.convertTo(output, CV_8U);
|
||||
if(output.channels() == 3)
|
||||
cv::cvtColor(output, output, cv::COLOR_BGR2GRAY);
|
||||
|
||||
output.convertTo(output, CV_32FC1, 1.0/255.0, 0);
|
||||
|
||||
if(profile.lightmap.data)
|
||||
|
22
src/main.cpp
22
src/main.cpp
@ -23,10 +23,10 @@ const char* organziation = "UVOS";
|
||||
const char* application = "UVOS";
|
||||
const char* version = "UVOS";
|
||||
|
||||
std::vector<cam::Camera::Description> showCameraSelectionDialog(bool* accepted = nullptr)
|
||||
std::vector<cam::Camera::Description> showCameraSelectionDialog(bool* accepted = nullptr, QWidget* w = nullptr)
|
||||
{
|
||||
std::vector<cam::Camera::Description> ret;
|
||||
CameraDialog diag(cam::Camera::getAvailableCameras());
|
||||
CameraDialog diag(cam::Camera::getAvailableCameras(), w);
|
||||
|
||||
diag.show();
|
||||
if(diag.exec() == QDialog::Accepted)
|
||||
@ -42,13 +42,13 @@ std::vector<cam::Camera::Description> showCameraSelectionDialog(bool* accepted =
|
||||
return ret;
|
||||
}
|
||||
|
||||
void showProfileDialog(Cameras* cameras)
|
||||
void showProfileDialog(Cameras* cameras, QWidget* w)
|
||||
{
|
||||
qDebug()<<__FUNCTION__;
|
||||
cameras->stop();
|
||||
cameras->disable(true);
|
||||
std::vector<cam::Camera::Description> descs = cameras->getCameras();
|
||||
ProfileDialog diag(cameras);
|
||||
ProfileDialog diag(cameras, w);
|
||||
diag.show();
|
||||
diag.exec();
|
||||
cameras->disable(false);
|
||||
@ -56,7 +56,7 @@ void showProfileDialog(Cameras* cameras)
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
Log::level = Log::WARN;
|
||||
Log::level = Log::DEBUG;
|
||||
|
||||
uvosled led;
|
||||
int uvosledRet = uvosled_connect(&led);
|
||||
@ -99,17 +99,23 @@ int main(int argc, char *argv[])
|
||||
|
||||
QObject::connect(&cameras, &Cameras::cameraAdded, &w, &MainWindow::addCamera);
|
||||
QObject::connect(&cameras, &Cameras::cameraRemoved, &w, &MainWindow::removeCamera);
|
||||
QObject::connect(&cameras, &Cameras::enableCapture, &w, &MainWindow::enableCapture);
|
||||
QObject::connect(&w, &MainWindow::sigCapture, [&cameras](){cameras.start(); cameras.trigger();});
|
||||
|
||||
QObject::connect(&w, &MainWindow::sigChooseCameras, [&cameras]()
|
||||
QTimer temperatureTimer;
|
||||
temperatureTimer.setSingleShot(false);
|
||||
QObject::connect(&temperatureTimer, &QTimer::timeout, [&cameras, &w](){w.setTemperature(cameras.getMeanTemp());});
|
||||
temperatureTimer.start(1000);
|
||||
|
||||
QObject::connect(&w, &MainWindow::sigChooseCameras, [&cameras, &w]()
|
||||
{
|
||||
bool accepted;
|
||||
std::vector<cam::Camera::Description> descs = showCameraSelectionDialog(&accepted);
|
||||
std::vector<cam::Camera::Description> descs = showCameraSelectionDialog(&accepted, &w);
|
||||
if(accepted)
|
||||
cameras.setCameras(descs);
|
||||
});
|
||||
|
||||
QObject::connect(&w, &MainWindow::sigEditProfiles, [&cameras, &w](){showProfileDialog(&cameras); w.refreshProfiles();});
|
||||
QObject::connect(&w, &MainWindow::sigEditProfiles, [&cameras, &w](){showProfileDialog(&cameras, &w); w.refreshProfiles();});
|
||||
QObject::connect(&pipe, &ImagePipeline::sigResult, w.mainImageViewer(), &CvImageViewer::setImage, Qt::QueuedConnection);
|
||||
QObject::connect(&pipe, &ImagePipeline::sigResult, [&w](){w.statusMsg("idle");});
|
||||
QObject::connect(&pipe, &ImagePipeline::sigInvalidProfile, &w, &MainWindow::profileInconpatible);
|
||||
|
@ -31,9 +31,7 @@ void CameraListWidget::setCameras(const std::vector<cam::Camera::Description>& d
|
||||
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].getVendor() + " " + desc_[i].getModel()).c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<cam::Camera::Description> CameraListWidget::getSelectedDescriptions()
|
||||
|
@ -100,7 +100,6 @@ void CvImageViewer::mousePressEvent(QMouseEvent *event)
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
sigValue(x, y, 0);
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ MainWindow::MainWindow(QWidget *parent)
|
||||
, ui(new Ui::MainWindow)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->statusbar->showMessage("idle");
|
||||
ui->statusbar->showMessage("no cameras");
|
||||
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();});
|
||||
@ -32,6 +32,11 @@ void MainWindow::setImageValue(size_t x, size_t y, double value)
|
||||
ui->lcdNumber->display(value);
|
||||
}
|
||||
|
||||
void MainWindow::setTemperature(double temp)
|
||||
{
|
||||
ui->lcdNumber_temp->display(temp);
|
||||
}
|
||||
|
||||
void MainWindow::saveImage()
|
||||
{
|
||||
if(!ui->mainViewer->getImage().data)
|
||||
@ -59,7 +64,16 @@ void MainWindow::openImage()
|
||||
{
|
||||
cv::Mat image;
|
||||
cv::FileStorage matf(fileName.toStdString(), cv::FileStorage::READ);
|
||||
matf["image"]>>image;
|
||||
try
|
||||
{
|
||||
matf["image"]>>image;
|
||||
}
|
||||
catch(const cv::Exception& ex)
|
||||
{
|
||||
qDebug()<<ex.what();
|
||||
QMessageBox::warning(this, "Invalid file", "File selected dose not contain a valid image");
|
||||
return;
|
||||
}
|
||||
|
||||
if(matf.isOpened() && (!image.data || image.type() != CV_32FC1))
|
||||
{
|
||||
@ -75,6 +89,12 @@ void MainWindow::openImage()
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::enableCapture(bool enable)
|
||||
{
|
||||
ui->statusbar->showMessage(enable ? "idle" : "cameras not ready" );
|
||||
ui->pushButtonCapture->setEnabled(enable);
|
||||
}
|
||||
|
||||
void MainWindow::addCamera(std::shared_ptr<Camera> camera)
|
||||
{
|
||||
viewers_.push_back(new CvImageViewer(this, camera->id()));
|
||||
|
@ -36,6 +36,8 @@ public slots:
|
||||
bool setProfile(const QString& profileName);
|
||||
QString getProfileName();
|
||||
void statusMsg(QString msg);
|
||||
void enableCapture(bool capture);
|
||||
void setTemperature(double temp);
|
||||
|
||||
public:
|
||||
MainWindow(QWidget *parent = nullptr);
|
||||
|
@ -42,7 +42,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>278</width>
|
||||
<width>182</width>
|
||||
<height>483</height>
|
||||
</rect>
|
||||
</property>
|
||||
@ -74,8 +74,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>467</width>
|
||||
<height>313</height>
|
||||
<width>563</width>
|
||||
<height>282</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
@ -152,6 +152,9 @@
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButtonCapture">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Capture</string>
|
||||
</property>
|
||||
@ -180,6 +183,36 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_temp">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Mean camera temperature [℃]</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLCDNumber" name="lcdNumber_temp">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="value" stdset="0">
|
||||
<double>0.000000000000000</double>
|
||||
</property>
|
||||
<property name="intValue" stdset="0">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
Reference in New Issue
Block a user