简介
由于公司采购的AVT相机不足,需要用Basler相机来弥补,所以我也了解了一下Basler这款相机的SDK。由于Basler这边的相机提供的没有提供Qt的示例,所以我做一个分享出来。
本篇的Demo采用的是工业黑白相机。工业应用中,如果我们要处理的是与图像颜色有关,那么我们最好采用彩色工业相机;如果不是,那么我们最好选用黑白工业相机,因为在同样分辨率下的工业相机,黑白工业教学精度比彩色工业相机高,尤其是在看图像边缘的时候,黑白工业相机的效果更好。
开发环境
效果图
上图只是做了SDK部分接口的获取和设置。相机的触发方式、曝光时间、增益、频率,以及图片的尺寸、灯的触发信号等。
Basler相机SDK接口调用控制类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
#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 |
源文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
|
#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, ptrGrabResult, TimeoutHandling_Return); } else if (m_currentMode == "Line2" ) { m_basler.RetrieveResult(timeout, ptrGrabResult, 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; } |
如何调用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
#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 |
源文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
#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文件
(注意:引用库文件的路径哦)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
#------------------------------------------------- # # 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
码云
Github