Image Grabber as async image grabber for custom memory management.

This commit is contained in:
Hiro Protagonist 2017-03-23 15:55:49 +13:00
parent 56ebb20342
commit 3288a934a4
7 changed files with 100 additions and 31 deletions

View file

@ -26,11 +26,13 @@ DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += src/main.cpp\ SOURCES += src/main.cpp\
src/mainwindow.cpp\ src/mainwindow.cpp\
src/cameramanager.cpp\ src/cameramanager.cpp\
src/recorder.cpp src/recorder.cpp \
src/imagegrabber.cpp
HEADERS += src/mainwindow.h\ HEADERS += src/mainwindow.h\
src/cameramanager.h\ src/cameramanager.h\
src/recorder.h src/recorder.h \
src/imagegrabber.h
FORMS += src/forms/mainwindow.ui FORMS += src/forms/mainwindow.ui

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject> <!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.2.1, 2017-03-21T20:27:33. --> <!-- Written by QtCreator 4.2.1, 2017-03-23T15:54:31. -->
<qtcreator> <qtcreator>
<data> <data>
<variable>EnvironmentId</variable> <variable>EnvironmentId</variable>

View file

@ -5,3 +5,5 @@ Recorder:
Maybe Split Recorder and Manager UP -> DONE Maybe Split Recorder and Manager UP -> DONE
Flexible buffer size, options for serial Flexible buffer size, options for serial
Make image grabber nicer

View file

@ -5,14 +5,17 @@
using namespace FlyCapture2; using namespace FlyCapture2;
CameraManager::CameraManager(QObject *parent) : QObject(parent), num_cameras {0}, camera_index {-1}, is_capturing {false} { CameraManager::CameraManager(QObject *parent) : QObject(parent), num_cameras {0}, camera_index {-1}, is_capturing {false} {
image_buffer = new QVector<FlyCapture2::Image *>();
} }
CameraManager::~CameraManager() { CameraManager::~CameraManager() {
delete image_buffer;
stopCapture(); stopCapture();
camera.Disconnect(); camera.Disconnect();
} }
void CameraManager::connectCamera(unsigned int index) { void CameraManager::connectCamera(int index) {
// Don't connect twice. // Don't connect twice.
if(camera_index == index) if(camera_index == index)
return; return;
@ -46,22 +49,23 @@ void CameraManager::connectCamera(unsigned int index) {
// Do not drop frames! //TODO Flexible Buffer size // Do not drop frames! //TODO Flexible Buffer size
cam_config = FlyCapture2::FC2Config(); cam_config = FlyCapture2::FC2Config();
cam_config.grabMode = GrabMode::BUFFER_FRAMES; cam_config.grabMode = GrabMode::BUFFER_FRAMES;
cam_config.numBuffers= 50; cam_config.numBuffers = 10; // We gonna move them into our own data structure.
cam_config.highPerformanceRetrieveBuffer = true; cam_config.highPerformanceRetrieveBuffer = true;
camera_index = index;
camera.SetConfiguration(&cam_config); camera.SetConfiguration(&cam_config);
camera_index = index;
} }
// The capture callback is a wrapper to emit the frameCaptured signal. // The capture callback is a wrapper to emit the frameCaptured signal.
void CameraManager::captureCallback(FlyCapture2::Image* image, const void *camManager) { void CameraManager::imageGrabbed(FlyCapture2::Image *image) {
//thread Safe //thread Safe
static QMutex mutex; static QMutex mutex;
mutex.lock(); mutex.lock();
if(camManager) { image_buffer->append(image);
static_cast<const CameraManager*>(camManager)->frameCaptured(image); emit frameCaptured(image_buffer->front());
} delete image_buffer->front();
image_buffer->removeFirst();
mutex.unlock(); mutex.unlock();
return; return;
@ -71,13 +75,8 @@ void CameraManager::stopCapture() {
if(!is_capturing) if(!is_capturing)
return; return;
Error error; grabber->stopCapturing();
error = camera.StopCapture(); camera.StopCapture();
if(error != PGRERROR_OK) {
throw error;
return;
}
is_capturing = false; is_capturing = false;
} }
@ -85,17 +84,23 @@ void CameraManager::stopCapture() {
void CameraManager::startCapture() { void CameraManager::startCapture() {
// Don't capture twice! // Don't capture twice!
if(is_capturing) if(is_capturing)
return; return;
// Just a wrapper for the PTGrey method. Let all the errors be generated by the FlyCapture method. Error error;
// TODO: Evtl try to connect to first camera... error = camera.StartCapture();
Error error;
error = camera.StartCapture(captureCallback, this);
if(error != PGRERROR_OK) { if(error != PGRERROR_OK) {
throw error; throw error;
return; return;
} }
// Just my own async image grabbing!
// TODO: ERRORS!
grabber = new ImageGrabber(this);
grabber->setCamera(&camera);
connect(grabber, &ImageGrabber::imageCaptured, this, &CameraManager::imageGrabbed, Qt::QueuedConnection);
connect(grabber, &ImageGrabber::finished, grabber, &ImageGrabber::deleteLater);
grabber->start();
is_capturing = true; is_capturing = true;
} }

View file

@ -10,7 +10,10 @@
// TODO: Exclude inline Implementation // TODO: Exclude inline Implementation
// TODO: implement camera arrival removal // TODO: implement camera arrival removal
#include <QObject> #include <QObject>
#include <QVector>
#include <QThread>
#include "FlyCapture2.h" #include "FlyCapture2.h"
#include "imagegrabber.h"
class CameraManager : public QObject class CameraManager : public QObject
{ {
@ -43,7 +46,7 @@ public:
// Connect camera from index. Once successfull it emits the cameraConnected signal. // Connect camera from index. Once successfull it emits the cameraConnected signal.
// Emits Error signal in case of an error. // Emits Error signal in case of an error.
void connectCamera(unsigned int); void connectCamera(int);
bool isCapturing() { bool isCapturing() {
return is_capturing; return is_capturing;
@ -61,12 +64,17 @@ private:
// Index of the current camera // Index of the current camera
int camera_index; int camera_index;
// Just a littile wrapper function around the callback function for the camera capture to emit signals.
static inline void captureCallback(FlyCapture2::Image*, const void *);
// State Variable // State Variable
bool is_capturing; bool is_capturing;
QVector<FlyCapture2::Image *> *image_buffer;
// Capture Thread
ImageGrabber *grabber;
private slots:
void imageGrabbed(FlyCapture2::Image *image);
signals: signals:
void frameCaptured(FlyCapture2::Image* image) const; void frameCaptured(FlyCapture2::Image* image) const;
}; };

25
src/imagegrabber.cpp Normal file
View file

@ -0,0 +1,25 @@
#include "imagegrabber.h"
#include <QDebug>
void ImageGrabber::run() {
qDebug() << "Starting Capture.";
capture = true;
while(capture) {
FlyCapture2::Image* tmp = new FlyCapture2::Image();
FlyCapture2::Image* stored_img = new FlyCapture2::Image();
cam->RetrieveBuffer(tmp);
tmp->DeepCopy(stored_img);
emit imageCaptured(stored_img);
}
}
void ImageGrabber::setCamera(FlyCapture2::Camera *cam) {
this->cam = cam;
}
void ImageGrabber::stopCapturing() {
qDebug() << "Stopping Capture.";
capture = false;
}

27
src/imagegrabber.h Normal file
View file

@ -0,0 +1,27 @@
#ifndef IMAGEGRABBER_H
#define IMAGEGRABBER_H
#include <QThread>
#include "FlyCapture2.h"
class ImageGrabber : public QThread
{
Q_OBJECT
public:
ImageGrabber(QObject *parent = 0) : QThread(parent) {}
void run() Q_DECL_OVERRIDE;
void setCamera(FlyCapture2::Camera *cam);
private:
bool capture;
FlyCapture2::Camera *cam;
signals:
void imageCaptured(FlyCapture2::Image *image);
public slots:
void stopCapturing();
};
#endif // IMAGEGRABBER_H