rework camera setup

This commit is contained in:
Jan Grewe 2023-11-24 15:29:05 +01:00
parent d7b64790e4
commit b322bfdb47
7 changed files with 201 additions and 92 deletions

View File

@ -2,9 +2,11 @@
#include "mylogger.h" #include "mylogger.h"
#include "util.h" #include "util.h"
CamConfigurator::CamConfigurator(Pylon::DeviceInfoList_t &deviceList, QWidget *parent) : CamConfigurator::CamConfigurator(Pylon::DeviceInfoList_t &deviceList, QWidget *parent) :
deviceList(deviceList), QDialog(parent) { deviceList(deviceList), QDialog(parent), preview(nullptr) {
mode_combo = new QComboBox(this); mode_combo = new QComboBox(this);
mode_combo->addItem("camera mode");
mode_combo->addItem("single camera"); mode_combo->addItem("single camera");
if (deviceList.size() > 1){ if (deviceList.size() > 1){
mode_combo->addItem("stereo camera"); mode_combo->addItem("stereo camera");
@ -17,10 +19,11 @@ CamConfigurator::CamConfigurator(Pylon::DeviceInfoList_t &deviceList, QWidget *p
} }
connect(device_combo, SIGNAL(currentIndexChanged(int)), SLOT(primaryDeviceChanged(int))); connect(device_combo, SIGNAL(currentIndexChanged(int)), SLOT(primaryDeviceChanged(int)));
orientation_combo = new QComboBox(this); // orientation_combo = new QComboBox(this);
orientation_combo->addItem("Vertical"); // orientation_combo->addItem("Vertical");
orientation_combo->addItem("Horizontal"); // orientation_combo->addItem("Horizontal");
orientation_combo->setEnabled(false); // orientation_combo->setEnabled(false);
// connect(orientation_combo, SIGNAL(currentIndexChanged(int)), SLOT(orientationChanged(int)));
QWidget *header = new QWidget(this); QWidget *header = new QWidget(this);
QGridLayout *grid = new QGridLayout(header); QGridLayout *grid = new QGridLayout(header);
@ -28,16 +31,12 @@ CamConfigurator::CamConfigurator(Pylon::DeviceInfoList_t &deviceList, QWidget *p
grid->addWidget(mode_combo, 0, 1); grid->addWidget(mode_combo, 0, 1);
grid->addWidget(new QLabel("Primary device:", this), 1, 0); grid->addWidget(new QLabel("Primary device:", this), 1, 0);
grid->addWidget(device_combo, 1, 1); grid->addWidget(device_combo, 1, 1);
grid->addWidget(new QLabel("Orientation:", this), 2, 0);
grid->addWidget(orientation_combo, 2, 1);
header->setLayout(grid); header->setLayout(grid);
QVBoxLayout *vbox = new QVBoxLayout(this); QVBoxLayout *vbox = new QVBoxLayout(this);
vbox->addWidget(header); vbox->addWidget(header);
stack = new QStackedWidget(this); stack = new QStackedWidget(this);
stack->addWidget(singleCameraView()); stack->addWidget(new QLabel("CameraSetup, select mode!"));
stack->addWidget(new QLabel("Stereo View"));
stack->setCurrentIndex(0); stack->setCurrentIndex(0);
vbox->addWidget(stack); vbox->addWidget(stack);
@ -50,58 +49,91 @@ CamConfigurator::CamConfigurator(Pylon::DeviceInfoList_t &deviceList, QWidget *p
// qInfo() << "Create Camera configuration!"; // qInfo() << "Create Camera configuration!";
} }
QWidget* CamConfigurator::singleCameraView() {
qInfo() << "Create Camera configuration!";
QWidget *w = new QWidget(this);
QVBoxLayout *l = new QVBoxLayout(w);
l->setParent(w);
w->setLayout(l);
QString cam_name = device_combo->currentText(); CameraSetup* CamConfigurator::singleCameraView() {
singleCamPreview = new CameraPreview(cam_name, this); qInfo() << "Create Single Camera configuration!";
l->addWidget(singleCamPreview); if (preview != nullptr) {
return w; delete preview;
preview = nullptr;
}
preview = new SingleCamera(this);
return preview;
} }
// void CamConfigurator::stereoCameraView() {
// QWidget *w = new QWidget(this); CameraSetup* CamConfigurator::stereoCameraView() {
// QVBoxLayout *l = new QVBoxLayout(); qInfo() << "Create stereoCameraConfiguration";
// w->setLayout(l); if (preview != nullptr) {
// l->addWidget(orientation_combo); delete preview;
// } preview = nullptr;
}
preview = new DualCamera(this);
return preview;
}
void CamConfigurator::modeChanged(int idx) { void CamConfigurator::modeChanged(int idx) {
stack->setCurrentIndex(idx); stack->setCurrentIndex(0);
orientation_combo->setEnabled(idx == 1); if (stack->count() > 1 && preview != nullptr) {
qDebug() << "removing previous widget from stack";
stack->removeWidget(preview);
delete preview;
preview == nullptr;
}
if (idx == 1) {
qDebug() << "Mode changed to single camera mode";
qDebug() << "add new single camera preview";
preview = singleCameraView();
stack->addWidget(preview);
stack->setCurrentIndex(1);
QString device = device_combo->currentText();
preview->setPrimaryCamera(device);
} else if (idx == 2) {
qDebug() << "Mode changed to dual camera mode";
preview = stereoCameraView();
stack->addWidget(preview);
stack->setCurrentIndex(1);
QString device1 = device_combo->currentText();
preview->setPrimaryCamera(device1);
int i = device_combo->currentIndex();
if (i > 1) {
i = 1;
}
QString device2 = device_combo->itemText(1 - i);
preview->setSecondaryCamera(device2);
} else {
qDebug() << "Mode changed mode selection";
stack->setCurrentIndex(0);
}
// stack->setCurrentIndex(idx);
// TODO release camera?
// orientation_combo->setEnabled(idx == 1);
} }
// void CamConfigurator::orientationChanged(int idx) {
// }
void CamConfigurator::primaryDeviceChanged(int idx) { void CamConfigurator::primaryDeviceChanged(int idx) {
std::cerr << idx << std::endl; if (mode_combo->currentText() == "single camera") { // single camera setting
if (stack->currentIndex() == 0) { // single camera setting
QString devicename = device_combo->currentText(); QString devicename = device_combo->currentText();
singleCamPreview->updateCamera(devicename); preview->setPrimaryCamera(devicename);
} else {
preview->switchArrangement();
} }
} }
CameraLayout CamConfigurator::layout(){ CameraLayout CamConfigurator::layout(){
CameraLayout l; CameraLayout l;
if (mode_combo->currentText() == "single camera") { qDebug() << "Request layout";
l.mode = CameraMode::single; return preview->cameraLayout();
l.layout = Layout::horizontal;
l.devices.push_back(device_combo->currentText().toStdString());
l.rois.push_back(singleCamPreview->getRoi());
} else {
qWarning() << "not implemented yet";
}
return l;
} }
CamConfigurator::~CamConfigurator() CamConfigurator::~CamConfigurator()
{ {
delete singleCamPreview; qDebug() << "CamConfig Destructor";
delete preview;
} }
// void OptionsDialog::file_opened(QString filename)
// {
// QObject::connect(this, SLOT(file_opened(QString)), ui->widget, SLOT(file_opened(QString)));
// }

View File

@ -8,7 +8,7 @@
#include <QStackedWidget> #include <QStackedWidget>
#include <QGridLayout> #include <QGridLayout>
#include <pylon/PylonIncludes.h> #include <pylon/PylonIncludes.h>
#include "camerapreview.h" #include "camerasetup.h"
class ROI; class ROI;
@ -29,6 +29,7 @@ public:
public slots: public slots:
void modeChanged(int idx); void modeChanged(int idx);
void primaryDeviceChanged(int idx); void primaryDeviceChanged(int idx);
// void orientationChanged(int idx);
// signals: // signals:
// void column_visibility_changed(QString who, QString column, bool state); // void column_visibility_changed(QString who, QString column, bool state);
@ -36,14 +37,13 @@ public slots:
private: private:
Pylon::DeviceInfoList_t deviceList; Pylon::DeviceInfoList_t deviceList;
QComboBox *mode_combo, *device_combo, *orientation_combo; QComboBox *mode_combo, *device_combo; //, *orientation_combo;
QStackedWidget *stack; QStackedWidget *stack;
QDialogButtonBox *buttonbox; QDialogButtonBox *buttonbox;
CameraSetup *preview;
CameraPreview *singleCamPreview; CameraSetup* singleCameraView();
CameraSetup* stereoCameraView();
QWidget* singleCameraView();
//void stereoCameraView();
}; };
#endif // CAMCONFIG_H #endif // CAMCONFIG_H

View File

@ -1,9 +1,11 @@
#include "camerapreview.h" #include "camerapreview.h"
#include <QMessageBox> #include <QMessageBox>
#include <math.h> #include <math.h>
#include "mylogger.h"
CameraPreview::CameraPreview(QString &devicename, QWidget *parent):cameraname(devicename), QWidget(parent), camera(nullptr) { CameraPreview::CameraPreview(QWidget *parent):cameraname(""), camera(nullptr), QWidget(parent) {
QLabel *label = new QLabel(cameraname); qDebug() << "Camera preview constructor";
label = new QLabel(cameraname);
this->setLayout(new QVBoxLayout(this)); this->setLayout(new QVBoxLayout(this));
this->layout()->addWidget(label); this->layout()->addWidget(label);
imgLabel = new QLabel(this); imgLabel = new QLabel(this);
@ -15,25 +17,25 @@ CameraPreview::CameraPreview(QString &devicename, QWidget *parent):cameraname(de
width->setMinimum(1); width->setMinimum(1);
width->setMaximum(2048); width->setMaximum(2048);
width->setValue(width->maximum()); width->setValue(width->maximum());
connect(width, SIGNAL(textChanged(QString)), SLOT(updateROI(QString))); connect(width, SIGNAL(textChanged(QString)), SLOT(updateWidth(QString)));
height = new QSpinBox(controls); height = new QSpinBox(controls);
height->setMinimum(1); height->setMinimum(1);
height->setMaximum(1536); height->setMaximum(1536);
height->setValue(height->maximum()); height->setValue(height->maximum());
connect(height, SIGNAL(textChanged(QString)), SLOT(updateROI(QString))); connect(height, SIGNAL(textChanged(QString)), SLOT(updateHeight(QString)));
xoffs = new QSpinBox(controls); xoffs = new QSpinBox(controls);
xoffs->setMinimum(0); xoffs->setMinimum(0);
xoffs->setMaximum(2047); xoffs->setMaximum(2047);
xoffs->setValue(0); xoffs->setValue(0);
connect(xoffs, SIGNAL(textChanged(QString)), SLOT(updateROI(QString))); connect(xoffs, SIGNAL(textChanged(QString)), SLOT(updateXoffs(QString)));
yoffs = new QSpinBox(controls); yoffs = new QSpinBox(controls);
yoffs->setMinimum(0); yoffs->setMinimum(0);
yoffs->setMaximum(1535); yoffs->setMaximum(1535);
yoffs->setValue(0); yoffs->setValue(0);
connect(yoffs, SIGNAL(textChanged(QString)), SLOT(updateROI(QString))); connect(yoffs, SIGNAL(textChanged(QString)), SLOT(updateYoffs(QString)));
QGridLayout *grid = new QGridLayout(controls); QGridLayout *grid = new QGridLayout(controls);
grid->addWidget(new QLabel("width", controls), 0, 0); grid->addWidget(new QLabel("width", controls), 0, 0);
@ -49,22 +51,26 @@ CameraPreview::CameraPreview(QString &devicename, QWidget *parent):cameraname(de
grid->addWidget(yoffs, 1, 3); grid->addWidget(yoffs, 1, 3);
controls->setLayout(grid); controls->setLayout(grid);
this->layout()->addWidget(controls); this->layout()->addWidget(controls);
updateCamera(devicename); //setPrimaryCamera(devicename);
qDebug() << "Camera preview constructor";
takeStill(); takeStill();
} }
void CameraPreview::updateCamera(QString &device){ void CameraPreview::setCamera(QString &device){
std::cerr << "update camera! " << device.toStdString() << std::endl; qDebug() << "update camera! ";// << device.toStdString();
cameraname = device; cameraname = device;
label->setText(device);
if (camera != NULL) { if (camera != NULL) {
std::cerr << "camera is not nullptr! " << std::endl; qDebug() << "camera is not nullptr! ";
delete camera; delete camera;
camera = nullptr;
} }
camera = new PylonWrapper(cameraname.toStdString()); camera = new PylonWrapper(cameraname.toStdString());
std::string message; std::string message;
bool success = camera->openCamera(message); bool success = camera->openCamera(message);
if (!success) { if (!success) {
qWarning() << "Could not open camera device!";
qWarning() << QString::fromStdString(message);
QMessageBox msgBox; QMessageBox msgBox;
QString msg = "<p><b>Could not open camera device!</b><p><p>" + QString::fromStdString(message) + "</p>"; QString msg = "<p><b>Could not open camera device!</b><p><p>" + QString::fromStdString(message) + "</p>";
msgBox.setText(msg); msgBox.setText(msg);
@ -75,33 +81,69 @@ void CameraPreview::updateCamera(QString &device){
void CameraPreview::takeStill() { void CameraPreview::takeStill() {
if (camera->isOpen()) { qDebug() << "Take Still image!";
if (camera != nullptr && camera->isOpen()) {
MyImage mimg; MyImage mimg;
bool valid = camera->grabFrame(mimg); bool valid = camera->grabFrame(mimg);
if (!valid) { if (!valid) {
std::cerr << "Grabbing from camera failed!" << std::endl; qWarning() << "Grabbing from camera failed!";
return; return;
} }
QImage img(static_cast<uchar *>(mimg.data()), mimg.width(), mimg.height(), QImage img(static_cast<uchar *>(mimg.data()), mimg.width(), mimg.height(),
QImage::Format::Format_Grayscale8); QImage::Format::Format_Grayscale8);
QPixmap mpm = QPixmap::fromImage(img);
// QPixmap img("/home/grewe/projects/programming/pylon-recorder/test.png"); this->pm = mpm;
QPixmap mpm = QPixmap::fromImage(img); mpm = mpm.scaledToWidth(1024);
this->pm = mpm; setImage(mpm);
mpm = mpm.scaledToWidth(1024); updateROI();
setImage(mpm);
updateROI("");
} else { } else {
std::cerr << "Camera is not open! Connect to camera first!" << std::endl; qDebug() << "Camera is not open! Connect to camera first!";
} }
} }
void CameraPreview::setImage(const QPixmap &img) { void CameraPreview::setImage(const QPixmap &img) {
imgLabel->setPixmap(img); imgLabel->setPixmap(img);
} }
void CameraPreview::updateROI(QString v){ void CameraPreview::updateWidth(QString s) {
// if (xoffs->value() + width->value() > 2048) {
// xoffs->setValue(2048 - width->value());
// }
validate(width, xoffs, 2048);
updateROI();
}
void CameraPreview::updateXoffs(QString s) {
// if (xoffs->value() + width->value() > 2048) {
// width->setValue(2048 - xoffs->value());
// }
validate(xoffs, width, 2048);
updateROI();
}
void CameraPreview::updateHeight(QString s) {
// if (height->value() + yoffs->value() > 1536) {
// yoffs->setValue(1536 - height->value());
// }
validate(height, yoffs, 1536);
updateROI();
}
void CameraPreview::updateYoffs(QString s) {
// if (height->value() + yoffs->value() > 1536) {
// height->setValue(1536 - yoffs->value());
// }
validate(yoffs, height, 1536);
updateROI();
}
void CameraPreview::validate(QSpinBox *origin, QSpinBox *dest, int limit){
if (origin->value() + dest->value() > limit) {
dest->setValue(limit - origin->value());
}
}
void CameraPreview::updateROI(bool emitSignal) {
QImage img = pm.toImage(); QImage img = pm.toImage();
double scaling = 1024.0 / img.width(); double scaling = 1024.0 / img.width();
img = img.scaledToWidth(1024); img = img.scaledToWidth(1024);
@ -121,10 +163,22 @@ void CameraPreview::updateROI(QString v){
QPixmap npm = QPixmap::fromImage(img); QPixmap npm = QPixmap::fromImage(img);
setImage(npm); setImage(npm);
if (emitSignal) {
emit roiUpdated(xoffs->value(), yoffs->value(), width->value(), height->value());
}
}
void CameraPreview::setSize(int w, int h) {
width->setValue(w);
height->setValue(h);
validate(width, xoffs, 2048);
validate(height, yoffs, 1536);
updateROI(false);
}
QString CameraPreview::device(){
return cameraname;
} }
// FIXME at some point i need to check that xoffset + width must not exceed image width
// FIXME same for y offset and height
// FIXME initialize the cameras
ROI CameraPreview::getRoi() { ROI CameraPreview::getRoi() {
ROI r; ROI r;
@ -138,14 +192,13 @@ ROI CameraPreview::getRoi() {
} }
CameraPreview::~CameraPreview(){ CameraPreview::~CameraPreview(){
std::cerr << "cameraPreview destructor" << std::endl; qDebug() << "cameraPreview destructor";
if (camera != nullptr){ if (camera != nullptr){
std::cerr << "close camera" << std::endl; qDebug() << "close camera";
// camera->closeCamera(); // camera->closeCamera();
std::cerr << "call terminate" << std::endl; delete camera;
// camera->terminate(); camera = nullptr;
} }
delete camera; qDebug() << "preview: deleted camera";
std::cerr << "preview: deleted camera" << std::endl;
} }

View File

@ -23,28 +23,36 @@ class CameraPreview : public QWidget
Q_OBJECT Q_OBJECT
public: public:
explicit CameraPreview(QString &devicename, QWidget *parent = 0); explicit CameraPreview(QWidget *parent = 0);
~CameraPreview(); ~CameraPreview();
ROI getRoi(); ROI getRoi();
void updateROI(bool emitSignal=true);
void setSize(int width, int height);
QString device();
public slots: public slots:
void updateCamera(QString &device); void setCamera(QString &device);
void updateROI(QString v); void updateWidth(QString s);
void updateHeight(QString s);
void updateXoffs(QString s);
void updateYoffs(QString s);
// signals: signals:
// void column_visibility_changed(QString who, QString column, bool state); void roiUpdated(int x, int y, int width, int height);
// void recent_file_changed(QStringList);
private: private:
QString cameraname; QString cameraname;
QSpinBox *width, *height, *xoffs, *yoffs; QSpinBox *width, *height, *xoffs, *yoffs;
QLabel *imgLabel; QLabel *imgLabel;
QLabel *label;
QPixmap pm; QPixmap pm;
void takeStill(); void takeStill();
void setImage(const QPixmap &img); void setImage(const QPixmap &img);
// void setImage(const QImage &img); void validate(QSpinBox *origin, QSpinBox *dest, int limit);
PylonWrapper *camera; PylonWrapper *camera;
}; };

View File

@ -42,7 +42,7 @@ int main(int argc, char *argv[])
settings.setValue("app/pos_x", pos.x()); settings.setValue("app/pos_x", pos.x());
settings.setValue("app/pos_y", pos.y()); settings.setValue("app/pos_y", pos.y());
qInfo() << "PylonRecorder stop"; qInfo() << "PylonRecorder stop";
Logger::clean(); //Logger::clean();
return ret; return ret;
} }

14
notes.md Normal file
View File

@ -0,0 +1,14 @@
# PylonRecorder
Recorder for up to two Basler cameras.
## TODOs
* implement grabbing from 2 joined cameras
* set the region of interest
* save properly
## FIXMEs & improvements
* make the max image sizes depend on camera

View File

@ -608,7 +608,9 @@ void PylonRecorder::cameraConfiguration(){
void PylonRecorder::camerasetup() { void PylonRecorder::camerasetup() {
std::cerr << "camera settings accepted" << std::endl; std::cerr << "camera settings accepted" << std::endl;
std::cerr << d->result() << std::endl; std::cerr << d->result() << std::endl;
std::cerr << "camera settings accepted" << std::endl;
CameraLayout l = d->layout(); CameraLayout l = d->layout();
std::cerr << "camera settings accepted" << std::endl;
delete d; delete d;
} }