本文介绍了使用QT对Basler相机(GigE接口)进行二次开发,并且把相机的图像转换为OpenCV可处理的图片格式,以供大家学习参考。
INCLUDEPATH += $$PWD/include
INCLUDEPATH += $$PWD/include/opencv
INCLUDEPATH += $$PWD/include/opencv2
LIBS += $$PWD/lib/x64/GCBase_MD_VC141_v3_1_Basler_pylon.lib
LIBS += $$PWD/lib/x64/GenApi_MD_VC141_v3_1_Basler_pylon.lib
LIBS += $$PWD/lib/x64/PylonBase_v6_0.lib
LIBS += $$PWD/lib/x64/PylonC.lib
LIBS += $$PWD/lib/x64/PylonGUI_v6_0.lib
LIBS += $$PWD/lib/x64/PylonUtility_v6_0.lib
win32:CONFIG(release, debug|release): LIBS += -L$$PWD/lib/x64/ -lopencv_world343
else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/lib/x64/ -lopencv_world343d
else:unix: LIBS += -L$$PWD/lib/x64/ -lopencv_world343
INCLUDEPATH += $$PWD/lib/x64
DEPENDPATH += $$PWD/lib/x64
#include
#include
#include
#include
#include
#include
#include
using namespace std;
using namespace Pylon;
using namespace GenApi;
using namespace cv;
private slots:
void onTimerGrabImage();
private:
CInstantCamera m_basler;
INodeMap *nodemap;//相机属性节点
CGrabResultPtr ptrGrabResult;
CPylonImage pylonImage;
public:
Mat openCvImage;//用于OpenCV图像处理
private:
bool m_isOpenAcquire = false; // 是否开始采集
bool m_isOpen = false; // 是否打开摄像头
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
camSDK = new CamSDK();
PylonInitialize();
connect(camSDK, &CamSDK::sigCurrentImage, [=](QImage img)
{
QPixmap pix = QPixmap::fromImage(img);
ui->label->setPixmap(pix);
});
connect(camSDK,&CamSDK::sigCamBegin,this,&MainWindow::camBeginCtl);
connect(camSDK,&CamSDK::sigCamStop,this,&MainWindow::camStopCtl);
camSDK->OpenCamera();
}
void MainWindow::on_pushButton_Start_clicked()
{
camSDK->StartAcquire();
}
void MainWindow::on_pushButton_Stop_clicked()
{
camSDK->StopAcquire();
}
int CamSDK::OpenCamera()
{
try
{
m_basler.Attach(CTlFactory::GetInstance().CreateFirstDevice());//实例化第一个找到的设备
m_basler.Open();
m_isOpen = true;
// emit sigCamBegin();
}
catch (GenICam::GenericException &e)
{
qDebug() << "OpenCamera Error" << QString(e.GetDescription());
m_isOpen = false;
emit sigCamStop();
return -2;
}
return 0;
}
void CamSDK::deleteAll()
{
//停止采集
if(m_isOpenAcquire)
{
StopAcquire();
}
//关闭摄像头
CloseCamera();
//关闭库
PylonTerminate();
}
long CamSDK::StopAcquire()
{
m_isOpenAcquire = false;
try
{
if (m_basler.IsGrabbing())
{
m_basler.StopGrabbing();
emit sigCamStop();
}
}
catch (GenICam::GenericException &e)
{
qDebug() << "StopAcquire Error:" << QString(e.GetDescription());
return -2;
}
return 0;
}
int CamSDK::CloseCamera()
{
if(!m_isOpen)
{
return -1;
}
try
{
if(m_basler.IsOpen())
{
m_basler.DetachDevice();
m_basler.Close();
}
}
catch (GenICam::GenericException &e)
{
qDebug() << "CloseCamera Error:" << QString(e.GetDescription());
return -2;
}
return 0;
}
long CamSDK::StartAcquire()
{
m_isOpenAcquire = true;
try
{
m_basler.StartGrabbing(GrabStrategy_OneByOne);
onTimerGrabImage();
}
catch (GenICam::GenericException &e)
{
qDebug() << "StartAcquire Error:" << QString(e.GetDescription());
return -2;
}
return 0;
}
void CamSDK::onTimerGrabImage()
{
if(m_isOpenAcquire)
{
QImage image;
GrabImage(image, 5000);
if(!image.isNull())
{
emit sigCurrentImage(image);
}
QTimer::singleShot(5, this, SLOT(onTimerGrabImage()));
}
}
long CamSDK::GrabImage(QImage &image, unsigned int timeout)
{
try
{
if (!m_basler.IsGrabbing())
{
StartAcquire();
}
m_basler.RetrieveResult(timeout, ptrGrabResult, TimeoutHandling_ThrowException);
if(ptrGrabResult == NULL)
{
return -5;
}
if (ptrGrabResult->GrabSucceeded())
{
qDebug() << "what: ptrGrabResult GrabSucceeded";
if (!ptrGrabResult.IsValid())
{
OutputDebugString(L"GrabResult not Valid Error\n"); return -1;
}
// 新建pylon ImageFormatConverter对象
CImageFormatConverter formatConverter;
// 创建一个Pylonlmage后续将用来创建OpenCV images
formatConverter.OutputPixelFormat = PixelType_BGR8packed;
//将抓取的缓冲数据转化成pylon image.
formatConverter.Convert(pylonImage, ptrGrabResult);
// 将 pylon image转成OpenCV image.
openCvImage = Mat(static_cast<int>(ptrGrabResult->GetHeight()), static_cast<int>(ptrGrabResult->GetWidth()), CV_8UC3, static_cast<uint8_t *>(pylonImage.GetBuffer()));
EPixelType pixelType = ptrGrabResult->GetPixelType();
switch (pixelType)
{
case PixelType_Mono8:
{
CopyToImage(ptrGrabResult, image);//转为QImage
}
break;
case PixelType_BayerRG8:
{
qDebug() << "what: PixelType_BayerRG8";
}
break;
default:
qDebug() << "what: default"; break;
}
}
else
{
qDebug() << "Grab Error!!!";
return -3;
}
}
catch (GenICam::GenericException &e)
{
qDebug() << "GrabImage Error:" << QString(e.GetDescription());
return -2;
}
return 0;
}
void CamSDK::CopyToImage(CGrabResultPtr pInBuffer, QImage &OutImage)
{
try
{
uchar* buff = static_cast<uchar*>(pInBuffer->GetBuffer());
int nHeight = static_cast<int>(pInBuffer->GetHeight());
int nWidth = static_cast<int>(pInBuffer->GetWidth());
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, static_cast<size_t>(nWidth * nHeight));
}
}
}
catch (GenICam::GenericException &e)
{
qDebug() << "CopyToImage Error:" << QString(e.GetDescription());
}
}
https://msd.misuland.com/pd/2878646270447061120
[BASLER+OpenCV]:
https://www.cnblogs.com/star91/p/6747946.html
[QT+OpenCV]:
https://baijiahao.baidu.com/s?id=1648921394348848148&wfr=spider&for=pc
https://blog.csdn.net/zong596568821xp/article/details/78819275
[Qt+BASLER+OpenCV]:
https://blog.csdn.net/zong596568821xp/article/details/78790363