You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
269 lines
8.9 KiB
C++
269 lines
8.9 KiB
C++
//-----------------------------------------------------------------------------
|
|
#ifndef CaptureThreadH
|
|
#define CaptureThreadH CaptureThreadH
|
|
//-----------------------------------------------------------------------------
|
|
#include "balluffcamera.h"
|
|
#include <QThread>
|
|
#include <QMutex>
|
|
#include <QTimer>
|
|
#include <qdebug.h>
|
|
|
|
#include "SyncQueue.h"
|
|
#include "ASyncQueue.h"
|
|
|
|
#include "apps/Common/exampleHelper.h"
|
|
#include <apps/Common/qtIncludePrologue.h>
|
|
#include <apps/Common/qtIncludeEpilogue.h>
|
|
#include <opencv2/opencv.hpp>
|
|
|
|
#include "common.h"
|
|
|
|
extern SingleCamInfoStruct SingleCamInfo[NumberOfSupportedCameras];
|
|
extern int work_camera_nums;
|
|
|
|
class CaptureThread_Func
|
|
{
|
|
public:
|
|
Device* m_pMVCamera;
|
|
ASyncQueue<bool>* p_result_queue_;
|
|
ASyncQueue<bool>* p_double_queue_;
|
|
void SendFeedBack(int OpID)
|
|
{
|
|
bool send_ng = false;
|
|
bool send_ok = false;
|
|
if (OpID == EdgeEvent)
|
|
{
|
|
#if defined DOUBLE_FEED_BACK
|
|
if (p_double_queue_->count() > 0)
|
|
{
|
|
bool temp;
|
|
p_double_queue_->take(temp);
|
|
send_ng = true;
|
|
}
|
|
#endif
|
|
}
|
|
if (p_result_queue_->count() > 0)
|
|
{
|
|
bool result;
|
|
p_result_queue_->take(result);
|
|
if (!result)
|
|
{
|
|
#if defined DOUBLE_FEED_BACK
|
|
p_double_queue_->put(true);
|
|
#endif
|
|
send_ng = true;
|
|
}
|
|
else
|
|
{
|
|
send_ok = true;
|
|
}
|
|
}
|
|
try
|
|
{
|
|
mvIMPACT::acquire::GenICam::DigitalIOControl mvDIOC(m_pMVCamera);
|
|
if (send_ng) {
|
|
mvDIOC.userOutputSelector.writeS("UserOutput0");
|
|
mvIMPACT::acquire::TBoolean tb = mvDIOC.userOutputValue.read();
|
|
if (tb == bFalse)
|
|
mvDIOC.userOutputValue.write(bTrue);
|
|
else
|
|
mvDIOC.userOutputValue.write(bFalse);
|
|
}
|
|
else if (send_ok)
|
|
{
|
|
mvDIOC.userOutputSelector.writeS("UserOutput1");
|
|
mvIMPACT::acquire::TBoolean tb = mvDIOC.userOutputValue.read();
|
|
if (tb == bFalse)
|
|
mvDIOC.userOutputValue.write(bTrue);
|
|
else
|
|
mvDIOC.userOutputValue.write(bFalse);
|
|
}
|
|
}
|
|
catch (const ImpactAcquireException& e)
|
|
{
|
|
std::cout << "(error code: " << e.getErrorCodeAsString() << "). Press [ENTER] to end the application..." << std::endl;
|
|
}
|
|
}
|
|
};
|
|
|
|
class CaptureThread : public QObject
|
|
//-----------------------------------------------------------------------------
|
|
{
|
|
Q_OBJECT
|
|
|
|
public:
|
|
explicit CaptureThread(Device* pCurrDev, bool boTerminated, FunctionInterface* pFi, int Num);
|
|
CaptureThread::~CaptureThread(void);
|
|
void terminate(void)
|
|
{
|
|
boTerminated_ = true;
|
|
}
|
|
int getPendingRequestNr();
|
|
|
|
signals:
|
|
void error(QString err);
|
|
void finished(void);
|
|
void requestReady(void);
|
|
void updateStatistics(const QString& data, int Num);
|
|
|
|
private slots:
|
|
void process(void);
|
|
void fpsTimeout(void);
|
|
|
|
public:
|
|
int Local_Num;
|
|
QTimer* m_Timer;
|
|
uint64_t m_cntGrabbedImages = 0;
|
|
uint64_t m_cntLastGrabbedImages = 0;
|
|
#ifdef SYNC_CAMERA
|
|
ImageSyncArr* p_image_sync_arr;
|
|
SyncQueue<std::vector<std::pair<int, cv::Mat>>>* p_image_sync_queue;
|
|
#else
|
|
SyncQueue<std::pair<int, cv::Mat> >* p_image_queue;
|
|
#endif
|
|
ASyncQueue<cv::Mat>* p_unit_queue;
|
|
ASyncQueue<bool>* p_result_queue;
|
|
ASyncQueue<bool>* p_result_wait_queue;
|
|
ASyncQueue<bool>* p_double_queue;
|
|
ASyncQueue<bool>* p_shooted_queue;
|
|
SyncQueue<cv::Mat>* p_debug_queue;
|
|
bool Ready = false;
|
|
CaptureThread_Func m_threadFunc;
|
|
private:
|
|
Device* pDev_;
|
|
volatile bool boTerminated_;
|
|
int requestPendingForDisplay_;
|
|
FunctionInterface* pFI_;
|
|
QMutex lock_;
|
|
};
|
|
|
|
//=============================================================================
|
|
//================= Camera's property callback ================================
|
|
//=============================================================================
|
|
class EventCallback : public mvIMPACT::acquire::ComponentCallback
|
|
{
|
|
public:
|
|
ASyncQueue<cv::Mat>* p_unit_queue_;
|
|
#ifdef SYNC_CAMERA
|
|
ImageSyncArr* p_image_sync_arr_;
|
|
SyncQueue<std::vector<std::pair<int, cv::Mat>>>* p_image_sync_queue_;
|
|
#else
|
|
SyncQueue<std::pair<int, cv::Mat> >* p_image_queue_;
|
|
#endif
|
|
ASyncQueue<bool>* p_result_wait_queue_;
|
|
ASyncQueue<bool>* p_shooted_queue_;
|
|
ASyncQueue<bool>* p_double_queue_;
|
|
explicit EventCallback(void* pUserData = 0) : ComponentCallback(pUserData) {}
|
|
Device* m_pMVCamera;
|
|
CaptureThread* pCaptureThread = NULL;
|
|
int count = 0;
|
|
|
|
virtual void execute(Component& c, void* pUserData)
|
|
{
|
|
try
|
|
{
|
|
// re-generating the object/data previously attached to the callback object. This could now be used to call a certain member function e.g. to update a class instance about this event!
|
|
mvIMPACT::acquire::GenICam::EventControl* ec = reinterpret_cast<mvIMPACT::acquire::GenICam::EventControl*>(pUserData);
|
|
// Execute the followings if the component is a property.
|
|
if (c.isProp())
|
|
{
|
|
mvIMPACT::acquire::GenICam::DigitalIOControl mvDIOC(m_pMVCamera);
|
|
mvDIOC.lineSelector.writeS("Line5");
|
|
if (mvDIOC.lineStatus.read())
|
|
{
|
|
#ifdef IMM_FEED_BACK
|
|
if (p_shooted_queue_->count() > 0)
|
|
{
|
|
bool temp;
|
|
p_shooted_queue_->take(temp);
|
|
}
|
|
#elif defined ONE_TIME_SHIFT
|
|
if (
|
|
p_shooted_queue_->count() > 0
|
|
#if defined DOUBLE_FEED_BACK
|
|
|| p_double_queue_->count() > 0
|
|
#endif
|
|
)
|
|
{
|
|
if (p_shooted_queue_->count() > 0) {
|
|
bool temp;
|
|
p_shooted_queue_->take(temp);
|
|
}
|
|
pCaptureThread->m_threadFunc.SendFeedBack(EdgeEvent);
|
|
}
|
|
#else
|
|
if (p_result_wait_queue_->count() > 0)
|
|
{
|
|
bool temp;
|
|
p_result_wait_queue_->take(temp);
|
|
pCaptureThread->m_threadFunc.SendFeedBack(EdgeEvent);
|
|
}
|
|
if (p_shooted_queue_->count() > 0)
|
|
{
|
|
bool temp;
|
|
p_shooted_queue_->take(temp);
|
|
p_result_wait_queue_->put(true);
|
|
}
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
int unit_count = p_unit_queue_->count();
|
|
if (unit_count > 0)
|
|
{
|
|
cv::Mat long_image;
|
|
for (int i = 0; i < unit_count; i++)
|
|
{
|
|
cv::Mat image;
|
|
p_unit_queue_->take(image);
|
|
if (0 == i)
|
|
{
|
|
long_image = cv::Mat::zeros(image.rows * unit_count, image.cols, image.type());
|
|
}
|
|
cv::Rect r(0, i * image.rows, image.cols, image.rows);
|
|
cv::Mat roi = long_image(r);
|
|
image.copyTo(roi);
|
|
}
|
|
#ifdef SYNC_CAMERA
|
|
{
|
|
std::lock_guard<std::mutex> locker(p_image_sync_arr_->lock);
|
|
p_image_sync_arr_->image_sync_arr.at(pCaptureThread->Local_Num) = std::make_pair(unit_count, long_image);
|
|
p_image_sync_arr_->collect_cnt++;
|
|
if (p_image_sync_arr_->collect_cnt == work_camera_nums)
|
|
{
|
|
p_image_sync_queue_->put(p_image_sync_arr_->image_sync_arr);
|
|
p_image_sync_arr_->collect_cnt = 0;
|
|
}
|
|
}
|
|
#else
|
|
p_image_queue_->put(std::make_pair(unit_count, long_image));
|
|
#endif
|
|
p_shooted_queue_->put(true);
|
|
}
|
|
p_unit_queue_->clear();
|
|
}
|
|
}
|
|
}
|
|
catch (const ImpactAcquireException& e)
|
|
{
|
|
qDebug() << "Error";
|
|
}
|
|
}
|
|
};
|
|
|
|
class CIwtCameraLostCallbackMV : public mvIMPACT::acquire::ComponentCallback
|
|
{
|
|
public:
|
|
CIwtCameraLostCallbackMV() : ComponentCallback() {}
|
|
int channel_;
|
|
virtual void execute(mvIMPACT::acquire::Component& c, void* pDummy)
|
|
{
|
|
PropertyIDeviceState p(c);
|
|
std::cout << p.name() << " = " << p.readS() << endl;
|
|
SingleCamInfo[channel_].OffLine = true;
|
|
}
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
#endif // CaptureThreadH
|