12 Commits
Author SHA1 Message Date
Grant Terris c6a7588fd7 Add Socket Support 2019-11-02 15:43:33 -07:00
Grant Terris c6bd616951 Add Device Start Commands 2019-10-20 13:12:33 -07:00
Grant Terris 36ef0dc541 Add Throttle Value 2019-10-19 16:58:24 -07:00
Grant Terris 3fdd065fc2 Improve I/O Efficiency 2019-09-17 19:02:05 -07:00
Grant Terris 6b0c05f541 Add Test Mode and Viewfinder 2019-09-16 20:57:05 -07:00
Grant Terris 1da6d9de31 Add Qt Libs to CMake 2019-09-14 16:03:45 -07:00
Grant Terris 8c7d4c0b43 Add ImageManager 2019-09-02 18:01:06 -07:00
Grant Terris 5ea03a6a0c Add Image Analyzer Class 2019-08-10 18:33:14 -07:00
Grant Terris 7155fce24f Add Simple Image Processor 2019-08-10 18:31:06 -07:00
Grant Terris 99b5733710 Switch to CMake 2019-08-10 16:31:12 -07:00
Grant Terris 9a99aa4835 Add TODO 2019-08-10 14:49:02 -07:00
Grant Terris c2f29509d1 Initial Commit 2019-08-04 21:46:51 -07:00
20 changed files with 295 additions and 638 deletions
-5
View File
@@ -38,11 +38,6 @@ install_manifest.txt
compile_commands.json compile_commands.json
CTestTestfile.cmake CTestTestfile.cmake
_deps _deps
*_autogen
# Qt
*.xml
*adaptor*
# Executables # Executables
FaultFinder FaultFinder
+1 -1
View File
@@ -5,7 +5,7 @@
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{ {
"name": "Debug", "name": "Build and Debug",
"type": "cppdbg", "type": "cppdbg",
"request": "launch", "request": "launch",
"program": "${workspaceFolder}/FaultFinder", "program": "${workspaceFolder}/FaultFinder",
+1 -2
View File
@@ -55,7 +55,6 @@
"streambuf": "cpp", "streambuf": "cpp",
"thread": "cpp", "thread": "cpp",
"cinttypes": "cpp", "cinttypes": "cpp",
"typeinfo": "cpp", "typeinfo": "cpp"
"qdbusconnection": "cpp"
} }
} }
-1
View File
@@ -6,7 +6,6 @@
"type": "shell", "type": "shell",
"command": "cmake", "command": "cmake",
"args": [ "args": [
"-DCMAKE_BUILD_TYPE=Debug",
"." "."
], ],
"group": { "group": {
+3 -27
View File
@@ -5,41 +5,20 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
find_package( OpenCV REQUIRED ) find_package( OpenCV REQUIRED )
find_package( Ebus REQUIRED ) find_package( Ebus REQUIRED )
find_package( Qt5 COMPONENTS Widgets Network DBus Sql Positioning SerialPort REQUIRED ) find_package( Qt5 COMPONENTS Widgets Network REQUIRED )
set(CMAKE_AUTOMOC ON)
set(prog_SRCS DBus.xml)
qt5_generate_dbus_interface(ConfigManager.hpp
DBus.xml
OPTIONS -A
)
qt5_add_dbus_adaptor(prog_SRCS
${CMAKE_CURRENT_BINARY_DIR}/DBus.xml
ConfigManager.hpp
ConfigManager
)
include_directories( include_directories(
${OpenCV_INCLUDE_DIRS} ${OpenCV_INCLUDE_DIRS}
${Ebus_INCLUDE_DIRS} ${Ebus_INCLUDE_DIRS}
${Qt5Widgets_INCLUDE_DIRS} ${Qt5Widgets_INCLUDE_DIRS}
${Qt5Network_INCLUDE_DIRS} ${Qt5Network_INCLUDE_DIRS}
${Qt5DBus_INCLUDE_DIRS}
${Qt5Sql_INCLUDE_DIRS}
${Qt5Positioning_INCLUDE_DIRS}
${Qt5SerialPort_INCLUDE_DIRS}
) )
add_executable( FaultFinder add_executable( FaultFinder
FaultFinder.cpp FaultFinder.cpp
StreamManager.cpp StreamManager.cpp
ImageManager.cpp ImageManager.cpp
ConfigManager.cpp
FaultManager.cpp FaultManager.cpp
StreamReader.cpp
main.cpp
${prog_SRCS}
) )
target_link_libraries( FaultFinder target_link_libraries( FaultFinder
@@ -47,8 +26,5 @@ target_link_libraries( FaultFinder
${Ebus_LIBRARIES} ${Ebus_LIBRARIES}
${Qt5Widgets_LIBRARIES} ${Qt5Widgets_LIBRARIES}
${Qt5Network_LIBRARIES} ${Qt5Network_LIBRARIES}
${Qt5DBus_LIBRARIES} )
${Qt5Sql_LIBRARIES} message( ${Qt5Network_INCLUDE_DIRS} )
${Qt5Positioning_LIBRARIES}
${Qt5SerialPort_LIBRARIES}
)
-93
View File
@@ -1,93 +0,0 @@
#include <QDBusConnection>
#include <QDebug>
#include "ConfigManager.hpp"
#include "dbusadaptor.h"
ConfigManager::ConfigManager(QObject *parent) : QObject(parent)
{
new ConfigManagerAdaptor(this);
QDBusConnection dbus = QDBusConnection::sessionBus();
dbus.registerObject("/configuration", this);
dbus.registerService("com.infraredinspectionsystems.FaultFinder");
}
ConfigManager::~ConfigManager()
{
}
bool ConfigManager::GetRecordingState()
{
qDebug() << "ConfigManager::GetRecordingState";
return this->recording;
}
void ConfigManager::SetRecordingState(bool enable)
{
// if sensor is cold
qDebug() << "ConfigManager::SetRecordingState";
if (this->recording != enable) {
this->recording = enable;
emit NewRecordingState(this->recording);
}
}
int ConfigManager::GetFrameRate()
{
qDebug() << "ConfigManager::GetFrameRate";
return this->frame_rate;
}
void ConfigManager::SetFrameRate(int frame_rate)
{
qDebug() << "ConfigManager::SetFrameRate";
if (this->frame_rate != frame_rate) {
this->frame_rate = frame_rate;
emit NewFrameRate(this->frame_rate);
}
}
double ConfigManager::GetEmissivity()
{
qDebug() << "ConfigManager::GetEmissivity";
return this->emissivity;
}
void ConfigManager::SetEmissivity(double emissivity)
{
qDebug() << "ConfigManager::SetEmissivity";
if (this->emissivity != emissivity) {
this->emissivity = emissivity;
emit NewEmissivity(this->emissivity);
}
}
QString ConfigManager::GetViewfinderConfig()
{
qDebug() << "ConfigManager::GetViewfinderConfig";
QJsonDocument doc(this->viewfinder_config);
return doc.toJson();
}
void ConfigManager::SetViewfinderConfig(QString config)
{
qDebug() << "ConfigManager::SetViewfinderConfig";
QJsonDocument doc = QJsonDocument::fromJson(config.toUtf8());
this->viewfinder_config = doc.object();
}
QString ConfigManager::GetTriggerConfig()
{
qDebug() << "ConfigManager::GetTriggerConfig";
QJsonDocument doc(this->trigger_config);
return doc.toJson();
}
void ConfigManager::SetTriggerConfig(QString config)
{
qDebug() << "ConfigManager::SetTriggerConfig";
QJsonDocument doc = QJsonDocument::fromJson(config.toUtf8());
this->trigger_config = doc.object();
}
-55
View File
@@ -1,55 +0,0 @@
#ifndef CONFIG_MANAGER_H
#define CONFIG_MANAGER_H
#include <QObject>
#include <QJsonObject>
class ConfigManager: public QObject
{
Q_OBJECT;
Q_PROPERTY(bool recording READ GetRecordingState WRITE SetRecordingState)
Q_PROPERTY(int frame_rate READ GetFrameRate WRITE SetFrameRate)
Q_PROPERTY(double emissivity READ GetEmissivity WRITE SetEmissivity)
Q_PROPERTY(QString viewfinder_config READ GetViewfinderConfig WRITE SetViewfinderConfig)
Q_PROPERTY(QString trigger_config READ GetTriggerConfig WRITE SetTriggerConfig)
public:
ConfigManager(QObject *parent);
virtual ~ConfigManager();
public slots:
bool GetRecordingState();
void SetRecordingState(bool enable);
int GetFrameRate();
void SetFrameRate(int frame_rate);
double GetEmissivity();
void SetEmissivity(double emissivity);
QString GetViewfinderConfig();
void SetViewfinderConfig(QString config);
QString GetTriggerConfig();
void SetTriggerConfig(QString config);
signals:
void NewRecordingState(bool enable);
void NewFrameRate(int frame_rate);
void NewEmissivity(double emissivity);
private:
bool recording = false;
int frame_rate = 5;
double emissivity = 0.95;
QJsonObject viewfinder_config = QJsonObject(
{
qMakePair(QString("palette"), QJsonValue("rainbow")),
qMakePair(QString("low_temp"), QJsonValue(0)),
qMakePair(QString("high_temp"), QJsonValue(100))
});
QJsonObject trigger_config = QJsonObject(
{
qMakePair(QString("method"), QJsonValue("threshold")),
qMakePair(QString("min"), QJsonValue(50)),
qMakePair(QString("max"), QJsonValue(100))
});
};
#endif
+40 -9
View File
@@ -1,14 +1,45 @@
#include "FaultFinder.hpp" #include <iostream>
FaultFinder::FaultFinder(QObject *parent) : QObject(parent) #include "StreamManager.hpp"
#include "ImageManager.hpp"
#include "FaultManager.hpp"
using namespace std;
int main(int argc, char **argv)
{ {
fault_mgr = new FaultManager(this); StreamManager stream_mgr;
image_mgr = new ImageManager(this); ImageManager image_mgr;
config_mgr = new ConfigManager(this); FaultManager fault_mgr;
stream_mgr = new StreamManager(this); PvString lConnectionID;
}
FaultFinder::~FaultFinder() // If running in test mode
{ if (argc > 1 && !strcmp(argv[1], "test"))
{
while(1)
{
if (!image_mgr.ProcessImage(0, 0, 0, fault_mgr, true))
break;
}
return 0;
}
// If no devies are found, exit.
if (stream_mgr.FindDevice(&lConnectionID).IsFailure())
{
return -1;
}
if (stream_mgr.ConnectToDevice(lConnectionID).IsFailure())
{
return -1;
}
stream_mgr.OpenStream(lConnectionID);
stream_mgr.AcquireImages(image_mgr, fault_mgr);
stream_mgr.Disconnect();
return 0;
} }
-27
View File
@@ -1,27 +0,0 @@
#ifndef FAULT_FINDER_H
#define FAULT_FINDER_H
#include <QObject>
#include "StreamManager.hpp"
#include "ImageManager.hpp"
#include "FaultManager.hpp"
#include "ConfigManager.hpp"
class FaultFinder : public QObject
{
Q_OBJECT;
public:
FaultFinder(QObject *parent);
virtual ~FaultFinder();
FaultManager *fault_mgr;
ImageManager *image_mgr;
ConfigManager *config_mgr;
StreamManager *stream_mgr;
bool test_mode = false;
};
#endif
+7 -77
View File
@@ -1,81 +1,11 @@
#include <opencv2/opencv.hpp>
#include "FaultManager.hpp" #include "FaultManager.hpp"
FaultManager::FaultManager(QObject *parent) : QObject(parent) using namespace cv;
void FaultManager::SaveImage(Mat image)
{ {
bool res; // Tag date, time, gps in file meta data
//imwrite( "/tmp/uniquetime.png", image);
res = OpenDatabase();
if (!res) {
qCritical() << "Failed to open database connection.";
exit(15);
}
res = OpenSerial();
if (!res) {
qCritical() << "Failure to open GPS serial device.";
exit(16);
}
StartGPS();
}
FaultManager::~FaultManager()
{
db.close();
gps->stopUpdates();
serial->close();
}
bool FaultManager::OpenDatabase()
{
db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("localhost");
db.setDatabaseName("FaultDatabase");
db.setUserName("user");
db.setPassword("faultfinder");
return db.open();
}
bool FaultManager::OpenSerial()
{
serial = new QSerialPort();
serial->setPortName("ttyUSB0");
serial->setBaudRate(QSerialPort::Baud4800);
serial->setDataBits(QSerialPort::Data8);
serial->setParity(QSerialPort::NoParity);
serial->setStopBits(QSerialPort::OneStop);
serial->setFlowControl(QSerialPort::NoFlowControl);
return serial->open(QIODevice::ReadOnly);
}
void FaultManager::StartGPS()
{
gps = new QNmeaPositionInfoSource(QNmeaPositionInfoSource::RealTimeMode);
gps->setDevice((QIODevice *)serial);
gps->startUpdates();
}
void FaultManager::SaveImage(QByteArray *imageBuffer)
{
QSqlQuery query;
// Get GPS Location
QGeoPositionInfo position = gps->lastKnownPosition(true);
QGeoCoordinate coorinate = position.coordinate();
query.prepare("INSERT INTO Faults (latitude, longitude, altitude, image) "
"VALUES (:latitude, :longitude, :altitude, :image)");
if (coorinate.isValid())
{
// This probably wont work without proper converstions
query.bindValue(":latitude", coorinate.latitude());
query.bindValue(":longitude", coorinate.longitude());
query.bindValue(":altitude", coorinate.altitude());
}
query.bindValue(":image", *imageBuffer);
// Save to Database
query.exec();
} }
+5 -21
View File
@@ -1,30 +1,14 @@
#ifndef FAULT_MANAGER_H #ifndef FAULTMANAGER_H
#define FAULT_MANAGER_H #define FAULTMANAGER_H
#include <QObject> #include <opencv2/core.hpp>
#include <QDebug>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSaveFile>
#include <QNmeaPositionInfoSource>
#include <QSerialPort>
class FaultManager: public QObject class FaultManager
{ {
Q_OBJECT;
public: public:
FaultManager(QObject *parent);
virtual ~FaultManager();
void SaveImage(QByteArray *imageBuffer);
private: void SaveImage(cv::Mat image);
bool OpenDatabase();
bool OpenSerial();
void StartGPS();
QSqlDatabase db;
QSerialPort *serial;
QNmeaPositionInfoSource *gps;
}; };
+28 -29
View File
@@ -3,8 +3,8 @@
#include <opencv2/imgcodecs.hpp> #include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc.hpp> #include <opencv2/imgproc.hpp>
#include "FaultFinder.hpp"
#include "ImageManager.hpp" #include "ImageManager.hpp"
#include "FaultManager.hpp"
#define ZERO 0 #define ZERO 0
#define BITS8 0xff #define BITS8 0xff
@@ -13,20 +13,9 @@
using namespace cv; using namespace cv;
//Mat testFrame = imread("/home/midstate/Documents/flirTest.tif", CV_16UC1); Mat testFrame = imread("/home/midstate/Documents/flirTest.tif", CV_16UC1);
ImageManager::ImageManager(QObject *parent) : QObject(parent) bool ImageManager::ProcessImage(uint32_t width, uint32_t height, uint8_t *imgPointer, FaultManager fault_mgr, bool test = false)
{
socket = new QUdpSocket();
socket->connectToHost(QHostAddress::LocalHost, 40000, QIODevice::ReadWrite);
}
ImageManager::~ImageManager()
{
}
void ImageManager::ProcessImage(int width, int height, uint8_t *imgPointer)
{ {
Mat frame, mask, viewfinder; Mat frame, mask, viewfinder;
std::vector<std::vector<Point>> contours; std::vector<std::vector<Point>> contours;
@@ -43,16 +32,14 @@ void ImageManager::ProcessImage(int width, int height, uint8_t *imgPointer)
else else
{ {
throttle_count++; throttle_count++;
return; return true;
} }
// Read in frame // Read in frame
//if (!test) if (!test)
// frame = Mat(height, width, CV_16UC1, imgPointer, Mat::AUTO_STEP); frame = Mat(height, width, CV_16UC1, imgPointer, Mat::AUTO_STEP);
//else else
// frame = testFrame; frame = testFrame;
frame = Mat(height, width, CV_16UC1, imgPointer, Mat::AUTO_STEP);
// Create mask and then flatten // Create mask and then flatten
GaussianBlur(frame, mask, cv::Size(0, 0), 1); GaussianBlur(frame, mask, cv::Size(0, 0), 1);
@@ -76,19 +63,31 @@ void ImageManager::ProcessImage(int width, int height, uint8_t *imgPointer)
if (area > fault_area) if (area > fault_area)
{ {
// Fault Detected, Draw on Screen and Save to Database drawContours(viewfinder, contours, i, Scalar(ZERO, BITS8, ZERO), 2);
drawContours(viewfinder, contours, i, Scalar(ZERO, BITS8, ZERO), 2); fault_mgr.SaveImage(viewfinder);
std::vector<uchar> imageBuffer;
imencode(".pgm", frame, imageBuffer);
QByteArray* imageBytes = new QByteArray(reinterpret_cast<const char*>(imageBuffer.data()), imageBuffer.size());
((FaultFinder*)(parent()))->fault_mgr->SaveImage(imageBytes);
} }
} }
// Create Viewfinder Window
createTrackbar("Lower Bound", "FLIR Viewfinder", &lower_bound, BITS14, NULL);
createTrackbar("Upper Bound", "FLIR Viewfinder", &upper_bound, BITS14, NULL);
createTrackbar("Temperature Threshold", "FLIR Viewfinder", &temp_threshold, BITS14, NULL);
createTrackbar("Fault Area", "FLIR Viewfinder", &fault_area, 0x50280, NULL);
// Make clicking a pixel display the temp value
//setMouseCallback("FLIR Viewfinder", NULL);
namedWindow("FLIR Viewfinder", WINDOW_AUTOSIZE);
imshow("FLIR Viewfinder", viewfinder);
if (waitKey(1) == 27 || getWindowProperty("FLIR Viewfinder", WND_PROP_FULLSCREEN) == -1)
{
destroyAllWindows();
return false;
}
// Send image to other servers // Send image to other servers
SendImage(viewfinder); SendImage(viewfinder);
return true;
} }
void ImageManager::SendImage(Mat image) void ImageManager::SendImage(Mat image)
+12 -9
View File
@@ -1,26 +1,29 @@
#ifndef IMAGE_MANAGER_H #ifndef ImageManager_H
#define IMAGE_MANAGER_H #define ImageManager_H
#include <QObject>
#include <QUdpSocket>
#include <opencv2/core.hpp> #include <opencv2/core.hpp>
#include <QUdpSocket>
#include "FaultManager.hpp"
#define THROTTLE_AMOUNT 1 #define THROTTLE_AMOUNT 1
class ImageManager: public QObject class ImageManager
{ {
Q_OBJECT;
public: public:
ImageManager(QObject *parent);
virtual ~ImageManager();
void ProcessImage(int width, int height, uint8_t *imgPointer); bool ProcessImage(uint32_t width, uint32_t height, uint8_t *imgPointer, FaultManager fault_mgr, bool test);
void SendImage(cv::Mat image); void SendImage(cv::Mat image);
QUdpSocket *socket; QUdpSocket *socket;
ImageManager() {
socket = new QUdpSocket();
socket->connectToHost(QHostAddress::LocalHost, 40000, QIODevice::ReadWrite);
}
private: private:
int throttle_count = 1; int throttle_count = 1;
}; };
+172 -129
View File
@@ -1,74 +1,15 @@
#include <iostream>
#include <PvSystem.h>
#include <PvDevice.h>
#include <PvDeviceGEV.h>
#include <PvStream.h>
#include <PvStreamGEV.h>
#include "StreamManager.hpp" #include "StreamManager.hpp"
#include "FaultFinder.hpp" #include "FaultManager.hpp"
StreamManager::StreamManager(QObject *parent) : QObject(parent) PvResult StreamManager::FindDevice(PvString *aConnectionID)
{
// Connect Signals
connect(((FaultFinder *)parent)->config_mgr, &ConfigManager::NewEmissivity, this, &StreamManager::SetEmissivity);
connect(((FaultFinder *)parent)->config_mgr, &ConfigManager::NewFrameRate, this, &StreamManager::SetFrameRate);
PvResult res;
res = FindDevice();
if (res.IsFailure())
exit(res.GetCode());
res = ConnectToDevice();
if (res.IsFailure())
exit(res.GetCode());
res = OpenStream();
if (res.IsFailure())
exit(res.GetCode());
ConfigureStream();
CreatePipeline();
StartStream();
ImageThread = new StreamReader(Device, Stream, Pipeline);
connect(ImageThread, &StreamReader::NewImage, this, &StreamManager::SendForProcessing, Qt::QueuedConnection);
ImageThread->start(QThread::TimeCriticalPriority);
}
StreamManager::~StreamManager()
{
ImageThread->requestInterruption();
ImageThread->wait();
StopStream();
Disconnect();
}
void StreamManager::SendForProcessing(int width, int height, uint8_t *imgPointer)
{
((FaultFinder *)parent())->image_mgr->ProcessImage(width, height, imgPointer);
}
void StreamManager::SetEmissivity(double emissivity)
{
if (lDeviceParams)
lDeviceParams->SetFloatValue("ObjectEmissivity", emissivity);
}
void StreamManager::SetFrameRate(int frame_rate)
{
if (lDeviceParams)
lDeviceParams->SetFloatValue("PS0FrameRate", frame_rate);
}
bool StreamManager::GetReadyState()
{
bool cold = false;
if (lDeviceParams)
lDeviceParams->GetBooleanValue("FPACold", cold);
return cold;
}
PvResult StreamManager::FindDevice()
{ {
PvResult lResult = PvResult(); PvResult lResult = PvResult();
const PvDeviceInfo *lSelectedDI = NULL; const PvDeviceInfo *lSelectedDI = NULL;
@@ -96,50 +37,55 @@ PvResult StreamManager::FindDevice()
if (lDIVector.size() == 0) if (lDIVector.size() == 0)
{ {
qCritical() << "Device not found!"; std::cout << "Device not found!" << std::endl;
lResult.SetCode(PV_NOT_FOUND); lResult.SetCode(PV_NOT_FOUND);
return lResult; return lResult;
} }
lSelectedDI = lDIVector.front(); lSelectedDI = lDIVector.front();
ConnectionID = lSelectedDI->GetConnectionID(); *aConnectionID = lSelectedDI->GetConnectionID();
lResult.SetCode(PV_OK); lResult.SetCode(PV_OK);
return lResult; return lResult;
} }
PvResult StreamManager::ConnectToDevice() PvResult StreamManager::ConnectToDevice(const PvString &aConnectionID)
{ {
PvResult lResult; PvResult lResult;
// Connect to the GigE Vision or USB3 Vision device // Connect to the GigE Vision or USB3 Vision device
qInfo() << "Connecting to device."; std::cout << "Connecting to device." << std::endl;
Device = PvDevice::CreateAndConnect(ConnectionID, &lResult); lDevice = PvDevice::CreateAndConnect(aConnectionID, &lResult);
if (Device == NULL) if (lDevice == NULL)
{ {
qCritical() << "Unable to connect to device."; std::cout << "Unable to connect to device." << std::endl;
} }
return lResult; return lResult;
} }
PvResult StreamManager::OpenStream() PvResult StreamManager::OpenStream(const PvString &aConnectionID)
{ {
PvResult lResult; PvResult lResult;
// Open stream to the GigE Vision or USB3 Vision device if (lDevice == NULL)
qInfo() << "Opening stream from device."; {
Stream = PvStream::CreateAndOpen(ConnectionID, &lResult); return lResult;
}
if (Stream != NULL) // Open stream to the GigE Vision or USB3 Vision device
std::cout << "Opening stream from device." << std::endl;
lStream = PvStream::CreateAndOpen(aConnectionID, &lResult);
if (lStream != NULL)
{ {
// If this is a GigE Vision device, configure GigE Vision specific streaming parameters // If this is a GigE Vision device, configure GigE Vision specific streaming parameters
PvDeviceGEV* lDeviceGEV = dynamic_cast<PvDeviceGEV *>(Device); PvDeviceGEV* lDeviceGEV = dynamic_cast<PvDeviceGEV *>(lDevice);
if ( lDeviceGEV != NULL ) if ( lDeviceGEV != NULL )
{ {
PvStreamGEV *lStreamGEV = static_cast<PvStreamGEV *>(Stream); PvStreamGEV *lStreamGEV = static_cast<PvStreamGEV *>(lStream);
// Negotiate packet size // Negotiate packet size
lDeviceGEV->NegotiatePacketSize(); lDeviceGEV->NegotiatePacketSize();
@@ -150,87 +96,184 @@ PvResult StreamManager::OpenStream()
} }
else else
{ {
qCritical() << "Unable to stream from device."; std::cout << "Unable to stream from device." << std::endl;
} }
return lResult; return lResult;
} }
void StreamManager::ConfigureStream() void StreamManager::CreateStreamBuffers()
{ {
// Reading payload size from device
uint32_t lSize = lDevice->GetPayloadSize();
// Use BUFFER_COUNT or the maximum number of buffers, whichever is smaller
uint32_t lBufferCount = (lStream->GetQueuedBufferMaximum() < BUFFER_COUNT) ?
lStream->GetQueuedBufferMaximum() :
BUFFER_COUNT;
// Allocate buffers
for (uint32_t i = 0; i < lBufferCount; i++)
{
// Create new buffer object
PvBuffer *lBuffer = new PvBuffer;
// Have the new buffer object allocate payload memory
lBuffer->Alloc(static_cast<uint32_t>(lSize));
// Add to external list - used to eventually release the buffers
lBufferList.push_back(lBuffer);
}
// Queue all buffers in the stream
BufferList::iterator lIt = lBufferList.begin();
while (lIt != lBufferList.end())
{
lStream->QueueBuffer( *lIt );
lIt++;
}
}
void StreamManager::AcquireImages(ImageManager image_mgr, FaultManager fault_mgr)
{
if (lDevice == NULL || lStream == NULL)
{
return;
}
CreateStreamBuffers();
// Get device parameters need to control streaming // Get device parameters need to control streaming
lDeviceParams = Device->GetParameters(); PvGenParameterArray *lDeviceParams = lDevice->GetParameters();
// Use Temperature Format Instead of Raw Counts // Use Temperature Format Instead of Raw Counts
lDeviceParams->SetEnumValue("IRFormat", 1); lDeviceParams->SetEnumValue("IRFormat", 1);
SetEmissivity(((FaultFinder *)parent())->config_mgr->GetEmissivity()); // Set Emissivity
SetFrameRate(((FaultFinder *)parent())->config_mgr->GetFrameRate()); //lDeviceParams->SetFloatValue("ObjectEmissivity", 0.95);
}
void StreamManager::CreatePipeline()
{
// Create the PvPipeline object
Pipeline = new PvPipeline( Stream );
if ( Pipeline != NULL )
{
// Reading payload size from device
uint32_t lSize = Device->GetPayloadSize();
// Set the Buffer count and the Buffer size
Pipeline->SetBufferCount( BUFFER_COUNT );
Pipeline->SetBufferSize( lSize );
}
}
void StreamManager::StartStream()
{
// Map the GenICam AcquisitionStart and AcquisitionStop commands // Map the GenICam AcquisitionStart and AcquisitionStop commands
PvGenCommand *lStart = dynamic_cast<PvGenCommand *>(lDeviceParams->Get("AcquisitionStart")); PvGenCommand *lStart = dynamic_cast<PvGenCommand *>(lDeviceParams->Get("AcquisitionStart"));
PvGenCommand *lStop = dynamic_cast<PvGenCommand *>(lDeviceParams->Get("AcquisitionStop"));
qInfo() << "Starting pipeline";
Pipeline->Start();
// Get stream parameters // Get stream parameters
PvGenParameterArray *lStreamParams = Stream->GetParameters(); PvGenParameterArray *lStreamParams = lStream->GetParameters();
// Map a few GenICam stream stats counters // Map a few GenICam stream stats counters
PvGenFloat *lFrameRate = dynamic_cast<PvGenFloat *>(lStreamParams->Get("AcquisitionRate")); PvGenFloat *lFrameRate = dynamic_cast<PvGenFloat *>(lStreamParams->Get("AcquisitionRate"));
PvGenFloat *lBandwidth = dynamic_cast<PvGenFloat *>(lStreamParams->Get("Bandwidth")); PvGenFloat *lBandwidth = dynamic_cast<PvGenFloat *>(lStreamParams->Get("Bandwidth"));
// Enable streaming and send the AcquisitionStart command // Enable streaming and send the AcquisitionStart command
qInfo() << "Enabling streaming and sending AcquisitionStart command."; std::cout << "Enabling streaming and sending AcquisitionStart command." << std::endl;
Device->StreamEnable(); lDevice->StreamEnable();
lStart->Execute(); lStart->Execute();
}
void StreamManager::StopStream() double lFrameRateVal = 0.0;
{ double lBandwidthVal = 0.0;
// Acquire images until the user instructs us to stop.
while (true)
{
PvBuffer *lBuffer = NULL;
PvResult lOperationResult;
// Retrieve next buffer
PvResult lResult = lStream->RetrieveBuffer(&lBuffer, &lOperationResult, 1000);
if (lResult.IsOK())
{
if (lOperationResult.IsOK())
{
PvPayloadType lType;
lFrameRate->GetValue(lFrameRateVal);
lBandwidth->GetValue(lBandwidthVal);
// If the buffer contains an image, display width and height.
uint32_t lWidth = 0, lHeight = 0;
lType = lBuffer->GetPayloadType();
if (lType == PvPayloadTypeImage)
{
// Get image specific buffer interface.
PvImage *lImage = lBuffer->GetImage();
// Read width, height.
lWidth = lImage->GetWidth();
lHeight = lImage->GetHeight();
// Process Image
if (!image_mgr.ProcessImage(lWidth, lHeight, lImage->GetDataPointer(), fault_mgr, false))
break;
std::cout << " W: " << std::dec << lWidth << " H: " << lHeight;
}
else
{
std::cout << " (buffer does not contain image)";
}
std::cout << " " << lFrameRateVal << " FPS " << ( lBandwidthVal / 1000000.0 ) << " Mb/s \r";
}
else
{
std::cout << lOperationResult.GetCodeString().GetAscii() << "\r";
}
// Re-queue the buffer in the stream object
lStream->QueueBuffer(lBuffer);
}
else
{
// Retrieve buffer failure
std::cout << lResult.GetCodeString().GetAscii() << "\r";
}
}
// Tell the device to stop sending images. // Tell the device to stop sending images.
qInfo() << "Sending AcquisitionStop command to the device"; std::cout << "Sending AcquisitionStop command to the device" << std::endl;
PvGenCommand *lStop = dynamic_cast<PvGenCommand *>(lDeviceParams->Get("AcquisitionStop"));
lStop->Execute(); lStop->Execute();
// Disable streaming on the device // Disable streaming on the device
qInfo() << "Disable streaming on the controller.";; std::cout << "Disable streaming on the controller." << std::endl;
Device->StreamDisable(); lDevice->StreamDisable();
// Stop the pipeline // Abort all buffers from the stream and dequeue
qInfo() << "Stop pipeline"; std::cout << "Aborting buffers still in stream" << std::endl;
Pipeline->Stop(); lStream->AbortQueuedBuffers();
while (lStream->GetQueuedBufferCount() > 0)
{
PvBuffer *lBuffer = NULL;
PvResult lOperationResult;
lStream->RetrieveBuffer(&lBuffer, &lOperationResult);
}
FreeStreamBuffers();
}
void StreamManager::FreeStreamBuffers()
{
// Go through the buffer list
BufferList::iterator lIt = lBufferList.begin();
while (lIt != lBufferList.end())
{
delete *lIt;
lIt++;
}
// Clear the buffer list
lBufferList.clear();
} }
void StreamManager::Disconnect() void StreamManager::Disconnect()
{ {
if (Stream != NULL) if (lStream != NULL)
{ {
Stream->Close(); lStream->Close();
PvStream::Free(Stream); PvStream::Free( lStream );
} }
if (Device != NULL) if (lDevice != NULL)
{ {
Device->Disconnect(); lDevice->Disconnect();
PvDevice::Free(Device); PvDevice::Free(lDevice);
} }
} }
+19 -38
View File
@@ -1,51 +1,32 @@
#ifndef STREAM_MANAGER_H #include <list>
#define STREAM_MANAGER_H
#include <QObject>
#include <QDebug>
#include <PvSystem.h>
#include <PvDevice.h> #include <PvDevice.h>
#include <PvStream.h> #include <PvStream.h>
#include <PvPipeline.h> #include <PvBuffer.h>
#include <PvDeviceGEV.h>
#include <PvStreamGEV.h> #include "ImageManager.hpp"
#include "StreamReader.hpp" #include "FaultManager.hpp"
#define BUFFER_COUNT (32) #define BUFFER_COUNT (32)
typedef std::list<PvBuffer *> BufferList;
class StreamManager : public QObject class StreamManager
{ {
Q_OBJECT;
public: public:
StreamManager(QObject *parent);
virtual ~StreamManager();
bool GetReadyState(); PvResult FindDevice(PvString *aConnectionID);
PvResult ConnectToDevice(const PvString &aConnectionID);
public slots: PvResult OpenStream(const PvString &aConnectionID);
void SetEmissivity(double emissivity); void AcquireImages(ImageManager image_mgr, FaultManager fault_mgr);
void SetFrameRate(int frame_rate);
void SendForProcessing(int width, int height, uint8_t *imgPointer);
private:
PvResult FindDevice();
PvResult ConnectToDevice();
PvResult OpenStream();
void ConfigureStream();
void StartStream();
void StopStream();
void CreatePipeline();
void AcquireImages();
void Disconnect(); void Disconnect();
PvString ConnectionID; private:
PvDevice *Device = NULL;
PvStream *Stream = NULL;
PvGenParameterArray *lDeviceParams = NULL;
PvPipeline *Pipeline = NULL;
StreamReader *ImageThread;
};
#endif PvDevice *lDevice = NULL;
PvStream *lStream = NULL;
BufferList lBufferList;
void CreateStreamBuffers();
void FreeStreamBuffers();
};
-61
View File
@@ -1,61 +0,0 @@
#include "StreamReader.hpp"
StreamReader::StreamReader(PvDevice *Device, PvStream *Stream, PvPipeline *Pipeline)
{
this->Device = Device;
this->Stream = Stream;
this->Pipeline = Pipeline;
}
void StreamReader::run()
{
while (!isInterruptionRequested())
{
PvBuffer *lBuffer = NULL;
PvResult lOperationResult;
// wait for this to unblock before called in event loop
// Retrieve next buffer
PvResult lResult = Pipeline->RetrieveNextBuffer(&lBuffer, 1000, &lOperationResult);
if (lResult.IsOK())
{
if (lOperationResult.IsOK())
{
PvPayloadType lType;
// If the buffer contains an image, display width and height.
uint32_t lWidth = 0, lHeight = 0;
lType = lBuffer->GetPayloadType();
if (lType == PvPayloadTypeImage)
{
// Get image specific buffer interface.
PvImage *lImage = lBuffer->GetImage();
// Read width, height.
lWidth = lImage->GetWidth();
lHeight = lImage->GetHeight();
// May need to push copy of data, not pointer to buffer in case it deallocs
emit NewImage(lWidth, lHeight, lImage->GetDataPointer());
}
else
{
qWarning() << " (buffer does not contain image)";
}
}
else
{
qInfo() << lOperationResult.GetCodeString().GetAscii() << "\r";
}
// Re-queue the buffer in the stream object
Stream->QueueBuffer(lBuffer);
}
else
{
// Retrieve buffer failure
qCritical() << lResult.GetCodeString().GetAscii() << "\r";
}
}
}
-28
View File
@@ -1,28 +0,0 @@
#ifndef STREAM_READER_H
#define STREAM_READER_H
#include <QThread>
#include <QDebug>
#include <PvDevice.h>
#include <PvStream.h>
#include <PvPipeline.h>
class StreamReader : public QThread
{
Q_OBJECT;
void run();
public:
StreamReader(PvDevice *Device, PvStream *Stream, PvPipeline *Pipeline);
signals:
void NewImage(int width, int height, uint8_t *imgPointer);
private:
PvDevice *Device = NULL;
PvStream *Stream = NULL;
PvPipeline *Pipeline = NULL;
};
#endif
+2
View File
@@ -0,0 +1,2 @@
- Switch BufferList to Pipeline
- Signal Break From While Loop
+1 -1
View File
@@ -89,7 +89,7 @@ if(NOT Ebus_INCLUDE_DIR OR NOT EXISTS ${Ebus_INCLUDE_DIR})
"path to ebus include directory," "path to ebus include directory,"
"e.g. /opt/pleora/ebus_sdk/Ubuntu-x86_64/include.") "e.g. /opt/pleora/ebus_sdk/Ubuntu-x86_64/include.")
else() else()
#message(STATUS "ebus include dir found: " ${Ebus_INCLUDE_DIR}) message(STATUS "ebus include dir found: " ${Ebus_INCLUDE_DIR})
endif() endif()
# Find library directory for ebus # Find library directory for ebus
-21
View File
@@ -1,21 +0,0 @@
#include <csignal>
#include <QCoreApplication>
#include "FaultFinder.hpp"
using namespace std;
void handleClose(int signal)
{
qApp->exit(14);
}
int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
FaultFinder ff(&app);
signal(SIGINT, &handleClose);
return app.exec();
}