1. 程式人生 > 程式設計 >Qt(C++)呼叫工業相機Basler的SDK使用示例

Qt(C++)呼叫工業相機Basler的SDK使用示例

簡介

由於公司採購的AVT相機不足,需要用Basler相機來彌補,所以我也瞭解了一下Basler這款相機的SDK。由於Basler這邊的相機提供的沒有提供Qt的示例,所以我做一個分享出來。

本篇的Demo採用的是工業黑白相機。工業應用中,如果我們要處理的是與影象顏色有關,那麼我們最好採用彩色工業相機;如果不是,那麼我們最好選用黑白工業相機,因為在同樣解析度下的工業相機,黑白工業教學精度比彩色工業相機高,尤其是在看影象邊緣的時候,黑白工業相機的效果更好。

開發環境

  • Qt: 5.6.2vc2013版
  • Basler: 5.0.11版

效果圖

Qt(C++)呼叫工業相機Basler的SDK使用示例

上圖只是做了SDK部分介面的獲取和設定。相機的觸發方式、曝光時間、增益、頻率,以及圖片的尺寸、燈的觸發訊號等。

Basler相機SDK介面呼叫控制類

#ifndef SBASLERCAMERACONTROL_H
#define SBASLERCAMERACONTROL_H
 
#include <QObject>
#include <pylon/PylonIncludes.h>
#include <QImage>
#include <QTimer>
 
#define DOUBLE_MAX 100000
#define DOUBLE_MIN 0
 
using namespace std;
using namespace Pylon;
using namespace GenApi;
class SBaslerCameraControl : public QObject
{
  Q_OBJECT
public:
  explicit SBaslerCameraControl(QObject *parent = 0);
  ~SBaslerCameraControl();
 
  enum SBaslerCameraControl_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 initSome();
  void deleteAll();
  QStringList cameras();
  int OpenCamera(QString cameraSN);
  int CloseCamera();
 
  void setExposureTime(double time); // 設定曝光時間
  int getExposureTime(); // 獲取曝光時間
  int getExposureTimeMin(); // 最小曝光時間
  int getExposureTimeMax(); // 最大曝光時間
 
  void setFeatureTriggerSourceType(QString type); // 設定種類
  QString getFeatureTriggerSourceType(); // 獲取種類:軟觸發、外觸發等等
 
  void setFeatureTriggerModeType(bool on); // 設定模式觸發
  bool getFeatureTriggerModeType(); // 獲取模式觸發
  void SetCamera(SBaslerCameraControl::SBaslerCameraControl_Type index,double tmpValue = 0.0); // 設定各種引數
  double GetCamera(SBaslerCameraControl::SBaslerCameraControl_Type index); // 獲取各種引數
 
  long GrabImage(QImage& image,int timeout = 2000);
  long StartAcquire(); // 開始採集
  long StopAcquire(); // 結束採集
signals:
  void sigCameraUpdate(QStringList list);
  void sigSizeChange(QSize size);
  void sigCameraCount(int count);
  void sigCurrentImage(QImage img);
private:
  void UpdateCameraList();
  void CopyToImage(CGrabResultPtr pInBuffer,QImage &OutImage);
private slots:
  void onTimerGrabImage();
private:
  CInstantCamera m_basler;
  QStringList m_cameralist;
  QString m_currentMode;
  bool m_isOpenAcquire = false; // 是否開始採集
  bool m_isOpen = false; // 是否開啟攝像頭
  QSize m_size;
};
 
#endif // SBASLERCAMERACONTROL_H

原始檔:

#include "sbaslercameracontrol.h"
#include <QDateTime>
#include <QDebug>
 
SBaslerCameraControl::SBaslerCameraControl(QObject *parent) : QObject(parent)
{
}
 
SBaslerCameraControl::~SBaslerCameraControl()
{
}
 
void SBaslerCameraControl::initSome()
{
  qDebug() << "SBaslerCameraControl: PylonInitialize initSome" ;
  PylonInitialize();
  CTlFactory &TlFactory = CTlFactory::GetInstance();
  TlInfoList_t lstInfo;
  int n = TlFactory.EnumerateTls(lstInfo);
 
  TlInfoList_t::const_iterator it;
  for ( it = lstInfo.begin(); it != lstInfo.end(); ++it ) {
    qDebug() << "FriendlyName: " << it->GetFriendlyName() << "FullName: " << it->GetFullName();
    qDebug() << "VendorName: " << it->GetVendorName() << "DeviceClass: " << it->GetDeviceClass() ;
  }
  UpdateCameraList();
  emit sigCameraCount(n);
  qDebug() << "SBasler Camera Count: " << n;
}
 
void SBaslerCameraControl::deleteAll()
{
  //停止採集
  if(m_isOpenAcquire) {
    StopAcquire();
  }
  //關閉攝像頭
  CloseCamera();
  //關閉庫
  qDebug() << "SBaslerCameraControl deleteAll: PylonTerminate" ;
  PylonTerminate();
  qDebug() << "SBaslerCameraControl deleteAll: Close" ;
}
 
QStringList SBaslerCameraControl::cameras()
{
  return m_cameralist;
}
 
void SBaslerCameraControl::UpdateCameraList()
{
  CTlFactory& TLFactory = CTlFactory::GetInstance();
  ITransportLayer * pTl = TLFactory.CreateTl("BaslerGigE");
  DeviceInfoList_t devices;
  int n = pTl->EnumerateDevices(devices);
  CInstantCameraArray cameraArray(devices.size());
  if(n == 0) {
    qDebug() << "Cannot find Any camera!";
    return;
  }
  for (int i=0 ; i<cameraArray.GetSize() ; i++) {
    cameraArray[i].Attach(TLFactory.CreateDevice(devices[i]));
    string sn = cameraArray[i].GetDeviceInfo().GetSerialNumber();
    m_cameralist << QString::fromStdString(sn);
  }
  emit sigCameraUpdate(m_cameralist);
}
 
void SBaslerCameraControl::CopyToImage(CGrabResultPtr pInBuffer,QImage &OutImage)
{
  uchar* buff = (uchar*)pInBuffer->GetBuffer();
  int nHeight = pInBuffer->GetHeight();
  int nWidth = pInBuffer->GetWidth();
  if(m_size != QSize(nWidth,nHeight)) {
    m_size = QSize(nWidth,nHeight);
    emit sigSizeChange(m_size);
  }
  QImage imgBuff(buff,nWidth,nHeight,QImage::Format_Indexed8);
  OutImage = imgBuff;
  if(pInBuffer->GetPixelType() == PixelType_Mono8) {
    uchar* pCursor = OutImage.bits();
    if ( OutImage.bytesPerLine() != nWidth ) {
      for ( int y=0; y<nHeight; ++y ) {
        pCursor = OutImage.scanLine( y );
        for ( int x=0; x<nWidth; ++x ) {
          *pCursor =* buff;
          ++pCursor;
          ++buff;
        }
      }
    } else {
      memcpy( OutImage.bits(),buff,nWidth * nHeight );
    }
  }
}
 
void SBaslerCameraControl::onTimerGrabImage()
{
  if(m_isOpenAcquire) {
    QImage image;
    GrabImage(image,5);
    if(!image.isNull()) {
      emit sigCurrentImage(image);
    }
    QTimer::singleShot(5,this,SLOT(onTimerGrabImage()));
  }
}
 
int SBaslerCameraControl::OpenCamera(QString cameraSN)
{
  try {
    CDeviceInfo cInfo;
    String_t str = String_t(cameraSN.toStdString().c_str());
    cInfo.SetSerialNumber(str);
    m_basler.Attach(CTlFactory::GetInstance().CreateDevice(cInfo));
    m_basler.Open();
    //獲取觸發模式
    getFeatureTriggerSourceType();
    m_isOpen = true;
  } catch (GenICam::GenericException &e) {
    OutputDebugString(L"OpenCamera Error\n");
    m_isOpen = false;
    return -2;
  }
  return 0;
}
 
int SBaslerCameraControl::CloseCamera()
{
  if(!m_isOpen) {
    return -1;
  }
  try {
    if(m_basler.IsOpen()) {
      m_basler.DetachDevice();
      m_basler.Close();
    }
  } catch (GenICam::GenericException &e) {
    OutputDebugString(LPCWSTR(e.GetDescription()));
    return -2;
  }
  return 0;
}
 
void SBaslerCameraControl::setExposureTime(double time)
{
  SetCamera(Type_Basler_ExposureTimeAbs,time);
}
 
int SBaslerCameraControl::getExposureTime()
{
  return QString::number(GetCamera(Type_Basler_ExposureTimeAbs)).toInt();
}
 
int SBaslerCameraControl::getExposureTimeMin()
{
  return DOUBLE_MIN;
}
 
int SBaslerCameraControl::getExposureTimeMax()
{
  return DOUBLE_MAX;
}
 
void SBaslerCameraControl::setFeatureTriggerSourceType(QString type)
{
  //停止採集
  if(m_isOpenAcquire) {
    StopAcquire();
  }
  if(type == "Freerun") {
    SetCamera(Type_Basler_Freerun);
  } else if(type == "Line1"){
    SetCamera(Type_Basler_Line1);
  }
}
 
QString SBaslerCameraControl::getFeatureTriggerSourceType()
{
  INodeMap &cameraNodeMap = m_basler.GetNodeMap();
  CEnumerationPtr ptrTriggerSel = cameraNodeMap.GetNode ("TriggerSelector");
  ptrTriggerSel->FromString("FrameStart");
  CEnumerationPtr ptrTrigger = cameraNodeMap.GetNode ("TriggerMode");
  ptrTrigger->SetIntValue(1);
  CEnumerationPtr ptrTriggerSource = cameraNodeMap.GetNode ("TriggerSource");
 
  String_t str = ptrTriggerSource->ToString();
  m_currentMode = QString::fromLocal8Bit(str.c_str());
  return m_currentMode;
}
 
void SBaslerCameraControl::setFeatureTriggerModeType(bool on)
{
  INodeMap &cameraNodeMap = m_basler.GetNodeMap();
  CEnumerationPtr ptrTriggerSel = cameraNodeMap.GetNode ("TriggerSelector");
  ptrTriggerSel->FromString("FrameStart");
  CEnumerationPtr ptrTrigger = cameraNodeMap.GetNode ("TriggerMode");
  ptrTrigger->SetIntValue(on?1:0);
}
 
bool SBaslerCameraControl::getFeatureTriggerModeType()
{
  INodeMap &cameraNodeMap = m_basler.GetNodeMap();
  CEnumerationPtr ptrTriggerSel = cameraNodeMap.GetNode ("TriggerSelector");
  ptrTriggerSel->FromString("FrameStart");
  CEnumerationPtr ptrTrigger = cameraNodeMap.GetNode ("TriggerMode");
  return ptrTrigger->GetIntValue() == 1;
}
 
void SBaslerCameraControl::SetCamera(SBaslerCameraControl::SBaslerCameraControl_Type index,double 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;
  }
}
 
double SBaslerCameraControl::GetCamera(SBaslerCameraControl::SBaslerCameraControl_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;
  }
}
 
long SBaslerCameraControl::StartAcquire()
{
  m_isOpenAcquire = true;
  qDebug() << "SBaslerCameraControl IsGrabbing";
  try {
    qDebug() << "SBaslerCameraControl StartAcquire" << m_currentMode;
     if(m_currentMode == "Freerun") {
       m_basler.StartGrabbing(GrabStrategy_LatestImageOnly,GrabLoop_ProvidedByInstantCamera);
     } else if(m_currentMode == "Software") {
       m_basler.StartGrabbing(GrabStrategy_LatestImageOnly);
       onTimerGrabImage();
     } else if(m_currentMode == "Line1") {
       m_basler.StartGrabbing(GrabStrategy_OneByOne);
     } else if(m_currentMode == "Line2") {
       m_basler.StartGrabbing(GrabStrategy_OneByOne);
     }
  } catch (GenICam::GenericException &e) {
    OutputDebugString(L"StartAcquire error:");
    return -2;
  }
  return 0;
}
 
long SBaslerCameraControl::StopAcquire()
{
  m_isOpenAcquire = false;
  qDebug() << "SBaslerCameraControl StopAcquire";
  try {
    if (m_basler.IsGrabbing()) {
      m_basler.StopGrabbing();
    }
  } catch (GenICam::GenericException &e) {
    OutputDebugString(LPCWSTR(e.GetDescription()));
    return -2;
  }
  return 0;
}
 
long SBaslerCameraControl::GrabImage(QImage &image,int timeout)
{
  try {
    if (!m_basler.IsGrabbing()) {
      StartAcquire();
    }
    CGrabResultPtr ptrGrabResult;
    if(m_currentMode == "Freerun") {
    } else if(m_currentMode == "Software") {
      if (m_basler.WaitForFrameTriggerReady(1000,TimeoutHandling_Return)) {
        m_basler.ExecuteSoftwareTrigger();
        m_basler.RetrieveResult(timeout,ptrGrabResult,TimeoutHandling_Return);
      }
    } else if(m_currentMode == "Line1") {
      m_basler.RetrieveResult(timeout,TimeoutHandling_Return);
    } else if(m_currentMode == "Line2") {
      m_basler.RetrieveResult(timeout,TimeoutHandling_Return);
    }
    if (ptrGrabResult->GrabSucceeded()) {
      if (!ptrGrabResult.IsValid()) { OutputDebugString(L"GrabResult not Valid Error\n"); return -1; }
      EPixelType pixelType = ptrGrabResult->GetPixelType();
      switch (pixelType) {
      case PixelType_Mono8: {
        CopyToImage(ptrGrabResult,image);
      } break;
      case PixelType_BayerRG8: { qDebug() << "what: PixelType_BayerRG8"; } break;
      default: qDebug() << "what: default"; break;
      }
    } else {
      OutputDebugString(L"Grab Error!!!");
      return -3;
    }
  } catch (GenICam::GenericException &e) {
    OutputDebugString(L"GrabImage Error\n");
    return -2;
  } catch(...) {
    OutputDebugString(L"ZP 11 Shot GetParam Try 12 No know Error\n");
    return -1;
  }
  return 0;
}

如何呼叫

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
 
#include <QMainWindow>
#include "BaslerCamera/sbaslercameracontrol.h"
 
namespace Ui {
class MainWindow;
}
 
class MainWindow : public QMainWindow
{
  Q_OBJECT
 
public:
  explicit MainWindow(QWidget *parent = 0);
  ~MainWindow();
 
private slots:
  void on_pushButton_GetExTime_clicked();
  void on_pushButton_SetExTime_clicked();
  void on_pushButton_SetMode_clicked();
  void on_pushButton_GetMode_clicked();
  void on_pushButton_CFMode_clicked();
  void on_comboBox_CFMode_activated(int index);
  void on_pushButton_Start_clicked();
  void on_pushButtonRotate_clicked();
private:
  Ui::MainWindow *ui;
  SBaslerCameraControl* m_control = Q_NULLPTR;
  QMatrix m_matrix;
};
 
#endif // MAINWINDOW_H

原始檔:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
 
MainWindow::MainWindow(QWidget *parent) :
  QMainWindow(parent),ui(new Ui::MainWindow)
{
  ui->setupUi(this);
  m_control = new SBaslerCameraControl(this);
  m_control->initSome();
  connect(m_control,&SBaslerCameraControl::sigCurrentImage,[=](QImage img){
    QPixmap pix = QPixmap::fromImage(img).transformed(m_matrix);
    ui->label->setPixmap(pix);
    ui->widget_pic->setFixedSize(pix.size());
  });
  connect(m_control,&SBaslerCameraControl::sigSizeChange,[=](QSize size){
    // 預設大小641,494
    ui->label_size->setText(QString("\345\260\272\345\257\270:%0*%1").arg(QString::number(size.width())).arg(QString::number(size.height()))); // 尺寸
    ui->widget_pic->setFixedSize(size);
  });
  m_control->OpenCamera(m_control->cameras().first());
}
 
MainWindow::~MainWindow()
{
  m_control->CloseCamera();
  m_control->deleteAll();
  delete ui;
}
 
void MainWindow::on_pushButton_GetExTime_clicked()
{
  ui->label_exTime->setText(QString::number(m_control->getExposureTime()));
}
 
void MainWindow::on_pushButton_SetExTime_clicked()
{
  m_control->setExposureTime(ui->lineEdit_exTime->text().toDouble());
}
 
void MainWindow::on_pushButton_SetMode_clicked()
{
  m_control->setFeatureTriggerSourceType(ui->lineEdit_SetMode->text());
}
 
void MainWindow::on_pushButton_GetMode_clicked()
{
  ui->label_Mode->setText(m_control->getFeatureTriggerSourceType());
}
 
void MainWindow::on_pushButton_CFMode_clicked()
{
  ui->label_CFMode->setText(m_control->getFeatureTriggerModeType()?"Open":"Close");
}
 
void MainWindow::on_comboBox_CFMode_activated(int index)
{
  m_control->setFeatureTriggerModeType(index == 0);
}
 
void MainWindow::on_pushButton_Start_clicked()
{
  if(ui->pushButton_Start->text() == "\345\274\200\345\247\213\351\207\207\351\233\206") {// 開始採集
    m_control->StartAcquire();
    ui->pushButton_Start->setText("\347\273\223\346\235\237\351\207\207\351\233\206");// 結束採集
  } else {
    m_control->StopAcquire();
    ui->pushButton_Start->setText("\345\274\200\345\247\213\351\207\207\351\233\206");// 開始採集
  }
}
 
void MainWindow::on_pushButtonRotate_clicked()
{
  m_matrix.rotate(90);
}

pro檔案

(注意:引用庫檔案的路徑哦)

#-------------------------------------------------
#
# Project created by QtCreator 2017-12-14T17:55:52
#
#-------------------------------------------------
 
QT    += core gui
 
greaterThan(QT_MAJOR_VERSION,4): QT += widgets
 
TARGET = Demo_BaslerCamera
TEMPLATE = app
 
CONFIG  += c++11
 
#--------------------------------------------Basler-------------------------------------------
INCLUDEPATH += $$PWD/include
LIBS += -L$$PWD/lib/Win32 -lGCBase_MD_VC120_v3_0_Basler_pylon_v5_0 -lGenApi_MD_VC120_v3_0_Basler_pylon_v5_0 -lPylonBase_MD_VC120_v5_0 -lPylonC_MD_VC120 -lPylonGUI_MD_VC120_v5_0 -lPylonUtility_MD_VC120_v5_0
#----------------------------------------------------------------------------------------------
 
SOURCES += main.cpp\
    mainwindow.cpp \
  BaslerCamera/sbaslercameracontrol.cpp
 
HEADERS += mainwindow.h \
  BaslerCamera/sbaslercameracontrol.h
 
FORMS  += mainwindow.ui

我把原始碼已經上傳到碼雲和Github

碼雲

https://gitee.com/ShaShiDiZhuanLan/Demo_BaslerCamera

Github

https://github.com/ShaShiDiZhuanLan/Demo_BaslerCamera_Qt

到此這篇關於Qt(C++)呼叫工業相機Basler的SDK使用示例的文章就介紹到這了,更多相關Qt呼叫Basler的SDK內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!