共计 9005 个字符,预计需要花费 23 分钟才能阅读完成。
1、采图 UI 显示
2、硬件连贯和 IP 配置
2.1 外触发硬件接线
依据相机接线图,连贯相机的电源的触发信号输出;
2.2 IP 配置
Gige 网口相机须要电脑网卡和相机在同一 ip 段内,反对动静、动态等形式配置 IP,关上 Pylon IP Configurator 来匹配 IP,如下
3、代码实现
根本采图性能 Balser 都有对应的 Demo 进行参考,这里只截取相机采图和局部参数设置性能演示。
balser_gigeCamera.h
#ifndef BALSER_GIGECAMERA_H | |
#define BALSER_GIGECAMERA_H | |
/*************************** | |
* @projectName camera_test | |
* @brief Basler 相机图像采集及参数设置性能;* @author Alaric | |
* @date 2018-11-04 | |
**************************/ | |
#include <QImage> | |
#include "balser_gigecamera_global.h" | |
#include <QObject> | |
#include <pylon/PylonIncludes.h> | |
#include <pylon/BaslerUniversalInstantCamera.h> | |
#include <pylon/_BaslerUniversalCameraParams.h> | |
#include <QMutex> | |
using namespace std; | |
using namespace Pylon; | |
using namespace GenApi; | |
using namespace Basler_UniversalCameraParams; | |
class BALSER_GIGECAMERASHARED_EXPORT Balser_GigeCamera : public QObject, public CImageEventHandler | |
{ | |
Q_OBJECT | |
public: | |
Balser_GigeCamera(QObject *parent = nullptr); | |
~Balser_GigeCamera(); | |
enum BaslerCamera_Type{ | |
Type_Basler_Freerun, // 设置相机的内触发 | |
Type_Basler_Line1, // 设置相机的外触发 | |
Type_Basler_ExposureTimeAbs, // 设置相机的曝光工夫 | |
Type_Basler_GainRaw, // 设置相机的增益 | |
Type_Basler_AcquisitionFrameRateAbs, // 设置相机的频率 | |
Type_Basler_Width, // 图片的宽度 | |
Type_Basler_Height, // 图片的高度 | |
Type_Basler_LineSource, // 灯的触发信号 | |
}; | |
void initCamera(); // 初始化相机 | |
void OpenCamera(); // 关上相机 | |
void CloseCamera(); // 敞开相机 | |
void deleteAll(); // 删除相机 | |
int getExposureTime(); // 取得曝光工夫 | |
void setExposureTime(int time); // 设置曝光工夫 | |
int getGain(); // 取得增益 | |
void setGain(int value); // 设置增益 | |
void setFrameRate(int value); // 设置帧率 | |
int getFrameRate(); // 取得帧率 | |
void OneKeyAutoExTime(); // 一键主动曝光 | |
void SetCamera(Balser_GigeCamera::BaslerCamera_Type index, int tmpValue = 0); // 设置各种参数 | |
int GetCamera(Balser_GigeCamera::BaslerCamera_Type index); // 获取各种参数 | |
void AutoExposureOnce(CBaslerUniversalInstantCamera& camera); // 主动曝光 | |
void StartAcquire(); // 开始采集 | |
void StopAcquire(); // 完结采集 | |
void StartSnap(); // 抓图 | |
bool GrabOnLine_Signal; // 实时采图信号 | |
signals: | |
void canShowImg(QImage img); // 发送图像数据 | |
public slots: | |
void WorkTypeSignal(int work_type); // 接管图像处理信号,0 为 Once,1 为 Online; | |
private: | |
CBaslerUniversalInstantCamera m_basler; | |
CGrabResultPtr m_ptrGrabResult; | |
CImageFormatConverter m_formatConverter;//Basler 图片格式转换类 | |
CPylonImage pylonImage; //Basler 图像格式 | |
QMutex m_mutexLock; | |
int TestImg_WorkType = -1; // 图像处理形式,默认 - 1 为不解决,0 为 Once,1 为 Online;QImage CopyImgToQImage(CGrabResultPtr ptrGrabResult); | |
protected: | |
virtual void OnImageGrabbed(CInstantCamera &camera, const CGrabResultPtr &grabResult); | |
}; | |
#endif // BALSER_GIGECAMERA_H |
这里 balser 采集到的 BYTE 格局的图像数据依照通道数转换成 QImage 格局,最初发送给 UI 线程进行显示。
balser_gigecamera.cpp
#include "balser_gigecamera.h" | |
#include <QDebug> | |
Balser_GigeCamera::Balser_GigeCamera(QObject *parent) : QObject(parent) | |
{ } | |
Balser_GigeCamera::~Balser_GigeCamera() | |
{ } | |
void Balser_GigeCamera::initCamera() | |
{PylonInitialize(); | |
m_basler.RegisterImageEventHandler(this, RegistrationMode_Append, Cleanup_Delete); | |
m_basler.Attach(CTlFactory::GetInstance().CreateFirstDevice(),Cleanup_Delete); | |
qDebug()<<"Using device" << m_basler.GetDeviceInfo().GetModelName()<<endl; | |
m_basler.Open(); | |
if (!m_basler.IsOpen() || m_basler.IsGrabbing()) | |
{qDebug()<<"camera open failed"<<endl; | |
return; | |
} | |
} | |
void Balser_GigeCamera::CloseCamera() | |
{if(m_basler.IsOpen()) {m_basler.DetachDevice(); | |
m_basler.Close(); | |
m_basler.DestroyDevice(); | |
m_ptrGrabResult.Release();} | |
} | |
void Balser_GigeCamera::deleteAll() | |
{ | |
// 进行采集 | |
if(GrabOnLine_Signal) {StopAcquire(); | |
} | |
// 敞开摄像头 | |
try | |
{CloseCamera(); | |
m_basler.DeregisterImageEventHandler(this); | |
// 敞开库 | |
qDebug() << "SBaslerCameraControl deleteAll: PylonTerminate" ; | |
PylonTerminate();} | |
catch (const Pylon::GenericException& e) | |
{qDebug() << e.what();} | |
} | |
int Balser_GigeCamera::getExposureTime() | |
{return GetCamera(Type_Basler_ExposureTimeAbs); | |
} | |
void Balser_GigeCamera::setExposureTime(int time) | |
{SetCamera(Type_Basler_ExposureTimeAbs, time); | |
} | |
void Balser_GigeCamera::setGain(int value) | |
{SetCamera(Type_Basler_GainRaw, value); | |
} | |
int Balser_GigeCamera::getGain() | |
{return GetCamera(Type_Basler_GainRaw); | |
} | |
int Balser_GigeCamera::getFrameRate() | |
{return GetCamera(Type_Basler_AcquisitionFrameRateAbs); | |
} | |
void Balser_GigeCamera::setFrameRate(int value) | |
{SetCamera(Type_Basler_AcquisitionFrameRateAbs, value); | |
} | |
void Balser_GigeCamera::OneKeyAutoExTime() | |
{AutoExposureOnce(m_basler); | |
} | |
void Balser_GigeCamera::SetCamera(Balser_GigeCamera::BaslerCamera_Type index, int tmpValue) | |
{INodeMap &cameraNodeMap = m_basler.GetNodeMap(); | |
switch (index) { | |
case Type_Basler_Freerun: {CEnumerationPtr ptrTriggerSel = cameraNodeMap.GetNode ("TriggerSelector"); | |
ptrTriggerSel->FromString("FrameStart"); | |
CEnumerationPtr ptrTrigger = cameraNodeMap.GetNode ("TriggerMode"); | |
#ifdef Real_Freerun | |
ptrTrigger->SetIntValue(0); | |
#else //Software | |
ptrTrigger->SetIntValue(1); | |
CEnumerationPtr ptrTriggerSource = cameraNodeMap.GetNode ("TriggerSource"); | |
ptrTriggerSource->FromString("Software"); | |
#endif | |
} break; | |
case Type_Basler_Line1: {CEnumerationPtr ptrTriggerSel = cameraNodeMap.GetNode ("TriggerSelector"); | |
ptrTriggerSel->FromString("FrameStart"); | |
CEnumerationPtr ptrTrigger = cameraNodeMap.GetNode ("TriggerMode"); | |
ptrTrigger->SetIntValue(1); | |
CEnumerationPtr ptrTriggerSource = cameraNodeMap.GetNode ("TriggerSource"); | |
ptrTriggerSource->FromString("Line1"); | |
} break; | |
case Type_Basler_ExposureTimeAbs: {const CFloatPtr exposureTime = cameraNodeMap.GetNode("ExposureTimeAbs"); | |
exposureTime->SetValue(tmpValue); | |
} break; | |
case Type_Basler_GainRaw: {const CIntegerPtr cameraGen = cameraNodeMap.GetNode("GainRaw"); | |
cameraGen->SetValue(tmpValue); | |
} break; | |
case Type_Basler_AcquisitionFrameRateAbs: {const CBooleanPtr frameRate = cameraNodeMap.GetNode("AcquisitionFrameRateEnable"); | |
frameRate->SetValue(TRUE); | |
const CFloatPtr frameRateABS = cameraNodeMap.GetNode("AcquisitionFrameRateAbs"); | |
frameRateABS->SetValue(tmpValue); | |
} break; | |
case Type_Basler_Width: {const CIntegerPtr widthPic = cameraNodeMap.GetNode("Width"); | |
widthPic->SetValue(tmpValue); | |
} break; | |
case Type_Basler_Height: {const CIntegerPtr heightPic = cameraNodeMap.GetNode("Height"); | |
heightPic->SetValue(tmpValue); | |
} break; | |
case Type_Basler_LineSource: {CEnumerationPtr ptrLineSource = cameraNodeMap.GetNode ("LineSource"); | |
ptrLineSource->SetIntValue(2); | |
} break; | |
default: | |
break; | |
} | |
} | |
int Balser_GigeCamera::GetCamera(Balser_GigeCamera::BaslerCamera_Type index) | |
{INodeMap &cameraNodeMap = m_basler.GetNodeMap(); | |
switch (index) { | |
case Type_Basler_ExposureTimeAbs: {const CFloatPtr exposureTime = cameraNodeMap.GetNode("ExposureTimeAbs"); | |
return exposureTime->GetValue();} break; | |
case Type_Basler_GainRaw: {const CIntegerPtr cameraGen = cameraNodeMap.GetNode("GainRaw"); | |
return cameraGen->GetValue();} break; | |
case Type_Basler_AcquisitionFrameRateAbs: {const CBooleanPtr frameRate = cameraNodeMap.GetNode("AcquisitionFrameRateEnable"); | |
frameRate->SetValue(TRUE); | |
const CFloatPtr frameRateABS = cameraNodeMap.GetNode("AcquisitionFrameRateAbs"); | |
return frameRateABS->GetValue();} break; | |
case Type_Basler_Width: {const CIntegerPtr widthPic = cameraNodeMap.GetNode("Width"); | |
return widthPic->GetValue();} break; | |
case Type_Basler_Height: {const CIntegerPtr heightPic = cameraNodeMap.GetNode("Height"); | |
return heightPic->GetValue();} break; | |
default: | |
return -1; | |
break; | |
} | |
} | |
void Balser_GigeCamera::OnImageGrabbed(CInstantCamera &camera, const CGrabResultPtr &grabResult) | |
{m_mutexLock.lock(); | |
qDebug() <<"Capturest"<<endl; | |
if (grabResult->GrabSucceeded()) | |
{ | |
m_ptrGrabResult = grabResult;// 将捕捉到的图像传递进来 | |
qDebug() <<"Captureok"<<endl; | |
QImage CurrentImg; | |
CurrentImg = CopyImgToQImage(m_ptrGrabResult); | |
if(TestImg_WorkType == 1) | |
{emit canShowImg(CurrentImg); | |
// startImgProcess(CurrentImg); | |
qDebug() <<"Captureok"<<endl;} | |
else{emit canShowImg(CurrentImg); | |
} | |
} | |
m_mutexLock.unlock();} | |
void Balser_GigeCamera::StartAcquire() | |
{if ( !m_basler.IsGrabbing() ){qDebug()<<"grabstart"<<endl; | |
GrabOnLine_Signal = true; | |
m_basler.StartGrabbing(GrabStrategy_LatestImageOnly,GrabLoop_ProvidedByInstantCamera); | |
} | |
else {qDebug()<<"error"<<endl; | |
} | |
} | |
void Balser_GigeCamera::StartSnap() | |
{m_basler.StartGrabbing(1); | |
CBaslerUniversalGrabResultPtr ptrGrabResult; | |
m_basler.RetrieveResult(5000, ptrGrabResult, TimeoutHandling_ThrowException); | |
if (ptrGrabResult->GrabSucceeded()) | |
{qDebug()<<"snapok"<<endl; | |
QImage CurrentImg = CopyImgToQImage(ptrGrabResult); | |
emit canShowImg(CurrentImg); | |
if(TestImg_WorkType == 0){// startImgProcess(CurrentImg); | |
TestImg_WorkType = -1; | |
} | |
} | |
} | |
void Balser_GigeCamera::StopAcquire() | |
{if ( m_basler.IsGrabbing()){ | |
GrabOnLine_Signal = false; | |
m_basler.StopGrabbing(); // 进行抓取图像} | |
} | |
void Balser_GigeCamera::AutoExposureOnce(CBaslerUniversalInstantCamera& camera) | |
{if ( !camera.ExposureAuto.IsWritable()) | |
{ | |
cout << "The camera does not support Exposure Auto." << endl << endl; | |
return; | |
} | |
camera.ExposureAuto.SetValue(ExposureAuto_Once); | |
int n = 0; | |
while (camera.ExposureAuto.GetValue() != ExposureAuto_Off) | |
{ | |
++n; | |
//For demonstration purposes only. Wait until the image is shown. | |
WaitObject::Sleep(100); | |
//Make sure the loop is exited. | |
if (n > 100) | |
{throw TIMEOUT_EXCEPTION( "The adjustment of auto exposure did not finish."); | |
} | |
} | |
} | |
void Balser_GigeCamera::WorkTypeSignal(int work_type) | |
{TestImg_WorkType = work_type;} | |
QImage Balser_GigeCamera::CopyImgToQImage(CGrabResultPtr ptrGrabResult) | |
{ | |
QImage Qimg; | |
// 格局转换 | |
m_formatConverter.Convert(pylonImage, ptrGrabResult); | |
uchar * din = (uchar *)(pylonImage.GetBuffer()); // 数据指针 | |
// 单通道 Momo | |
if(IsMono(pylonImage.GetPixelType())) | |
{qDebug()<<"黑白图像"; | |
Qimg = QImage(din, ptrGrabResult->GetWidth(), ptrGrabResult->GetHeight(), QImage::Format_Indexed8); | |
} | |
else | |
{ | |
// 此处能够依据相机的格局获取特定格局的彩色图像 | |
if(IsRGB(pylonImage.GetPixelType())) | |
{Qimg = QImage(din, ptrGrabResult->GetWidth(), ptrGrabResult->GetHeight(), QImage::Format_RGB888); | |
} | |
} | |
return Qimg; | |
} |
4、源码下载
相机采图及相机设置局部封装成动静库,能够在 UI 线程调用相机类来实现相机的加载,采图及参数设置操作。
源码下载:https://download.csdn.net/dow…
正文完