fixes and using pointer in imagebuffer

This commit is contained in:
Jan Grewe 2023-10-26 11:51:29 +02:00
parent b56a6a39d6
commit af29f526f2
5 changed files with 88 additions and 51 deletions

View File

@ -1,6 +1,8 @@
#include "grabber.h" #include "grabber.h"
#include <iostream> #include <iostream>
#include <pylon/PylonIncludes.h> #include <pylon/PylonIncludes.h>
#include <chrono>
using namespace std::chrono;
void Grabber::run() { void Grabber::run() {
stop_request = false; stop_request = false;
@ -13,10 +15,15 @@ void Grabber::run() {
Pylon::CInstantCamera *cam = camera->getCamera(); Pylon::CInstantCamera *cam = camera->getCamera();
cam->StartGrabbing(); cam->StartGrabbing();
while (camera->isOpen() && !stop_request) { while (camera->isOpen() && !stop_request) {
MyImage img; MyImage *img = new MyImage();
auto start = high_resolution_clock::now();
cam->RetrieveResult( 5000, frame, Pylon::TimeoutHandling_ThrowException); cam->RetrieveResult( 5000, frame, Pylon::TimeoutHandling_ThrowException);
img.setFrame(frame); auto stop1 = high_resolution_clock::now();
img->setFrame(frame);
auto stop2 = high_resolution_clock::now();
buffer->push(img); buffer->push(img);
auto duration1 = duration_cast<microseconds>(stop1 - start);
auto duration2 = duration_cast<microseconds>(stop2 - stop1);
count += 1; count += 1;
} }
cam->StopGrabbing(); cam->StopGrabbing();

View File

@ -1,10 +1,16 @@
#include "imagebuffer.h" #include "imagebuffer.h"
#include <chrono>
using namespace std::chrono;
ImageBuffer::ImageBuffer(size_t buffer_size, QObject *parent) : QObject(parent), buffer_size(buffer_size) { ImageBuffer::ImageBuffer(size_t buffer_size, QObject *parent) : QObject(parent), buffer_size(buffer_size) {
buffer.resize(buffer_size); buffer.resize(buffer_size);
} }
void ImageBuffer::clear() { void ImageBuffer::clear() {
for (auto & img: buffer) {
if (img != nullptr)
delete(img);
}
resize(buffer_size); resize(buffer_size);
} }
@ -20,8 +26,8 @@ double ImageBuffer::bufferPreassure() {
return preassure * 100; return preassure * 100;
} }
int64_t ImageBuffer::bufferLoad() { size_t ImageBuffer::bufferLoad() {
int64_t l; size_t l;
mutex.lock(); mutex.lock();
l = load; l = load;
mutex.unlock(); mutex.unlock();
@ -34,17 +40,32 @@ void ImageBuffer::resize(size_t new_size) {
buffer.clear(); buffer.clear();
buffer.resize(new_size); buffer.resize(new_size);
current_read_index = 0; current_read_index = 0;
current_write_index = -1; current_write_index = 0;
load = 0; load = 0;
mutex.unlock(); mutex.unlock();
} }
void ImageBuffer::push(const MyImage &img) { void ImageBuffer::push(MyImage *img) {
mutex.lock(); mutex.lock();
static_cast<size_t>(current_write_index) < (buffer.size() - 1) ? current_write_index += 1 : current_write_index = 0; if (buffer[current_write_index] != nullptr) {
buffer[static_cast<size_t>(current_write_index)] = img; std::cerr << "possible frame drop detected!!" << std::endl;
if (load < static_cast<int64_t>(buffer.capacity())) std::cerr << "buffer.push write: " << current_write_index << " read: " << current_read_index << " load: " << load << std::endl;
load += 1;
delete(buffer[current_write_index]);
}
buffer[current_write_index] = img;
current_write_index += 1;
load += 1;
if (current_write_index >= buffer_size){
current_write_index = 0;
}
if (load >= buffer_size){
load = buffer_size;
if (current_read_index == current_write_index)
current_read_index = current_write_index < buffer_size - 1 ? current_write_index + 1 : 0;
}
// std::cout << "Buffer.afterpush: load = " << load << " write index =" << current_write_index << " read index = " << current_read_index << std::endl;
mutex.unlock(); mutex.unlock();
} }
@ -56,33 +77,38 @@ bool ImageBuffer::bufferNotEmpty() {
return res; return res;
} }
bool ImageBuffer::pop(MyImage &img) { MyImage* ImageBuffer::pop() {
bool ret = false; bool ret = false;
MyImage * img;
mutex.lock(); mutex.lock();
if (load > 0) { if (load > 0) {
// std::cerr << "Buffer.pop, load: " << load << " read_idx: " << current_read_index << " write_idx: " << current_write_index << std::endl; img = buffer[current_read_index];
img = buffer[static_cast<size_t>(current_read_index)]; current_read_index < (buffer_size - 1) ? current_read_index += 1 : current_read_index = 0;
static_cast<size_t>(current_read_index) < (buffer.capacity() - 1) ? current_read_index += 1 : current_read_index = 0;
load -= 1; load -= 1;
ret = true;
} }
mutex.unlock(); mutex.unlock();
return ret; std::cerr << "buffer.pop write: " << current_write_index << " read: " << current_read_index << " load: " << load << std::endl;
return img;
} }
bool ImageBuffer::readLast(MyImage &img) { MyImage* ImageBuffer::readLast() {
bool ret = false; MyImage *img;
mutex.lock(); mutex.lock();
if (load > 0) { if (load > 0) {
size_t idx; size_t idx = current_write_index - 1;
if (current_write_index != 0) {
idx = static_cast<size_t>(current_write_index) - 1; if (idx < 0) {
} else { std::cerr << "Bank" << std::endl;
idx = buffer.capacity() -1; idx = buffer_size - 1;
} }
img = buffer[idx]; img = buffer[idx];
ret = true;
} }
mutex.unlock(); mutex.unlock();
return ret; return img;
}
ImageBuffer::~ImageBuffer(){
std::cerr << "Image buffer destructor" << std::endl;
clear();
} }

View File

@ -12,25 +12,26 @@ class ImageBuffer : public QObject
Q_OBJECT Q_OBJECT
public: public:
explicit ImageBuffer(size_t buffer_size=100, QObject *parent = nullptr); explicit ImageBuffer(size_t buffer_size=100, QObject *parent = nullptr);
~ImageBuffer();
void clear(); void clear();
void resize(size_t new_size); void resize(size_t new_size);
void push(const MyImage &img); void push(MyImage *img);
bool pop(MyImage &img); MyImage* pop();
bool readLast(MyImage &img); MyImage* readLast();
size_t capacity(); size_t capacity();
double bufferPreassure(); double bufferPreassure();
int64_t bufferLoad(); size_t bufferLoad();
bool bufferNotEmpty(); bool bufferNotEmpty();
private: private:
QMutex mutex; QMutex mutex;
int numUsedBytes = 0; int numUsedBytes = 0;
std::vector<MyImage> buffer; std::vector<MyImage*> buffer;
int64_t current_write_index = -1; size_t current_write_index = 0;
int64_t current_read_index = 0; size_t current_read_index = 0;
int64_t load = 0; size_t load = 0;
size_t buffer_size; size_t buffer_size;
signals: signals:

View File

@ -9,7 +9,7 @@ MyImage::MyImage(Pylon::CGrabResultPtr ptr) {
} }
bool MyImage::setFrame(Pylon::CGrabResultPtr ptr) { bool MyImage::setFrame(Pylon::CGrabResultPtr ptr) {
bool valid = ptr.IsValid() && ptr->GetWidth() <= max_width && ptr->GetHeight() <= max_height; bool valid = ptr.IsValid() && ptr->GetWidth() <= max_width && ptr->GetHeight() <= max_height;
if (valid) { if (valid) {
img_index = ptr->GetID(); img_index = ptr->GetID();
img_width = ptr->GetWidth(); img_width = ptr->GetWidth();

View File

@ -251,19 +251,20 @@ void PylonRecorder::saveAs() {
void PylonRecorder::print() { void PylonRecorder::print() {
Q_ASSERT(imageLabel->pixmap()); QPixmap map = imageLabel->pixmap(Qt::ReturnByValue);
#if defined(QT_PRINTSUPPORT_LIB) && QT_CONFIG(printdialog) Q_ASSERT(!map.isNull());
#if defined(QT_PRINTSUPPORT_LIB) && QT_CONFIG(printdialog)
QPrintDialog dialog(&printer, this); QPrintDialog dialog(&printer, this);
if (dialog.exec()) { if (dialog.exec()) {
QPainter painter(&printer); QPainter painter(&printer);
QRect rect = painter.viewport(); QRect rect = painter.viewport();
QSize size = imageLabel->pixmap()->size(); QSize size = map.size();
size.scale(rect.size(), Qt::KeepAspectRatio); size.scale(rect.size(), Qt::KeepAspectRatio);
painter.setViewport(rect.x(), rect.y(), size.width(), size.height()); painter.setViewport(rect.x(), rect.y(), size.width(), size.height());
painter.setWindow(imageLabel->pixmap()->rect()); painter.setWindow(map.rect());
painter.drawPixmap(0, 0, *imageLabel->pixmap()); painter.drawPixmap(0, 0, map);
} }
#endif #endif
} }
@ -512,9 +513,10 @@ void PylonRecorder::updateActions() {
void PylonRecorder::scaleImage(double factor) { void PylonRecorder::scaleImage(double factor) {
Q_ASSERT(imageLabel->pixmap()); QPixmap map = imageLabel->pixmap(Qt::ReturnByValue);
Q_ASSERT(!map.isNull());
scaleFactor *= factor; scaleFactor *= factor;
imageLabel->resize(scaleFactor * imageLabel->pixmap()->size()); imageLabel->resize(scaleFactor * map.size());
adjustScrollBar(scrollArea->horizontalScrollBar(), factor); adjustScrollBar(scrollArea->horizontalScrollBar(), factor);
adjustScrollBar(scrollArea->verticalScrollBar(), factor); adjustScrollBar(scrollArea->verticalScrollBar(), factor);
@ -525,14 +527,16 @@ void PylonRecorder::scaleImage(double factor) {
void PylonRecorder::applyScaling(){ void PylonRecorder::applyScaling(){
imageLabel->resize(scaleFactor * imageLabel->pixmap()->size()); imageLabel->resize(scaleFactor * imageLabel->pixmap(Qt::ReturnByValue).size());
} }
void PylonRecorder::quitApplication() { void PylonRecorder::quitApplication() {
std::cerr << "Quit Application!" << std::endl;
if (pylon->isOpen()) { if (pylon->isOpen()) {
if (grabbing) { if (grabbing) {
stopRecording(); stopRecording();
buffer->clear();
} }
pylon->closeCamera(); pylon->closeCamera();
} }
@ -604,12 +608,12 @@ void PylonRecorder::startRecording() {
writer->setProjectMetadata(mdata); writer->setProjectMetadata(mdata);
buffer->clear(); buffer->clear();
grabber->start();
if (!dryRunCheckBox->isChecked()) { if (!dryRunCheckBox->isChecked()) {
writer->start(); writer->start();
writing = true; writing = true;
} }
dryRun = dryRunCheckBox->isChecked(); dryRun = dryRunCheckBox->isChecked();
grabber->start();
grabbing = true; grabbing = true;
stopRequest = false; stopRequest = false;
@ -658,15 +662,14 @@ void PylonRecorder::displayActivity() {
void PylonRecorder::displaySingleFrame() { void PylonRecorder::displaySingleFrame() {
MyImage img; MyImage *img = buffer->readLast();
bool valid = buffer->readLast(img); if (img != nullptr){
if (valid) { QImage qimg(static_cast<uchar *>(img->data()), img->width(), img->height(),
QImage qimg(static_cast<uchar *>(img.data()), img.width(), img.height(),
QImage::Format::Format_Grayscale8); QImage::Format::Format_Grayscale8);
setImage(qimg); setImage(qimg);
}/* else { }/* else {
std::cerr << "Error reading last image" << std::endl; std::cerr << "Error reading last image" << std::endl;
}*/ }*/
} }
@ -686,7 +689,7 @@ std::string PylonRecorder::createFilename() {
QDateTime dt(QDateTime::currentDateTimeUtc()); QDateTime dt(QDateTime::currentDateTimeUtc());
QDate date = dt.date(); QDate date = dt.date();
std::string base = (date.toString("yyyy.MM.dd") + "_").toStdString(); std::string base = (date.toString("yyyy.MM.dd") + "_").toStdString();
std::string extension = ".mp4"; std::string extension = ".avi";
QString idx = QString::number(movieCount); QString idx = QString::number(movieCount);
std::string fname = base + idx.toStdString() + extension; std::string fname = base + idx.toStdString() + extension;
while (QFile::exists(QString::fromStdString(fname))) { while (QFile::exists(QString::fromStdString(fname))) {