我是靠谱客的博主 稳重灯泡,这篇文章主要介绍qt项目:大恒相机实时采集,单帧采集,并且在屏幕上显示,含有保存bmp图片功能文件下载,现在分享给大家,希望可以做个参考。

软件框架

在这里插入图片描述

ui界面框架在这里插入图片描述

.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
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
#------------------------------------------------- # # Project created by QtCreator 2019-12-20T09:41:39 # #------------------------------------------------- QT += core gui QT+=charts greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport TARGET = RailMeasurement TEMPLATE = app # The following define makes your compiler emit warnings if you use # any feature of Qt which as been marked as deprecated (the exact warnings # depend on your compiler). Please consult the documentation of the # deprecated API in order to know how to port your code away from it. DEFINES += QT_DEPRECATED_WARNINGS # You can also make your code fail to compile if you use deprecated APIs. # In order to do so, uncomment the following line. # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += main.cpp mainwindow.cpp qcustomplot.cpp camerawindow.cpp mat2qtformatmethod.cpp cgxbitmap.cpp convertstring.cpp drawwidget.cpp HEADERS += mainwindow.h qcustomplot.h camerawindow.h mat2qtformatmethod.h cgxbitmap.h convertstring.h drawwidget.h FORMS += mainwindow.ui camerawindow.ui # opencv环境,添加了imgproc,core,highui库 win32:CONFIG(release, debug|release): LIBS += -L$$PWD/../../cvpack/package/opencv/build/x64/vc14/lib/ -lopencv_imgproc2413 else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/../../cvpack/package/opencv/build/x64/vc14/lib/ -lopencv_imgproc2413d else:unix: LIBS += -L$$PWD/../../cvpack/package/opencv/build/x64/vc14/lib/ -lopencv_imgproc2413 INCLUDEPATH += $$PWD/../../cvpack/package/opencv/build/include DEPENDPATH += $$PWD/../../cvpack/package/opencv/build/include win32:CONFIG(release, debug|release): LIBS += -L$$PWD/../../cvpack/package/opencv/build/x64/vc14/lib/ -lopencv_core2413 else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/../../cvpack/package/opencv/build/x64/vc14/lib/ -lopencv_core2413d else:unix: LIBS += -L$$PWD/../../cvpack/package/opencv/build/x64/vc14/lib/ -lopencv_core2413 INCLUDEPATH += $$PWD/../../cvpack/package/opencv/build/include DEPENDPATH += $$PWD/../../cvpack/package/opencv/build/include win32:CONFIG(release, debug|release): LIBS += -L$$PWD/../../cvpack/package/opencv/build/x64/vc14/lib/ -lopencv_highgui2413 else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/../../cvpack/package/opencv/build/x64/vc14/lib/ -lopencv_highgui2413d else:unix: LIBS += -L$$PWD/../../cvpack/package/opencv/build/x64/vc14/lib/ -lopencv_highgui2413 INCLUDEPATH += $$PWD/../../cvpack/package/opencv/build/include DEPENDPATH += $$PWD/../../cvpack/package/opencv/build/include # 大恒sdk环境,添加了C++库和包含路径,没有添加c程序的库 unix|win32: LIBS += -L$$PWD/'../../CameraDemo/C++ SDK/lib/x64/' -lGxIAPICPPEx INCLUDEPATH += $$PWD/'../../CameraDemo/C++ SDK/lib/x64' DEPENDPATH += $$PWD/'../../CameraDemo/C++ SDK/lib/x64' INCLUDEPATH += $$PWD/'../../CameraDemo/C++ SDK/inc' DEPENDPATH += $$PWD/'../../CameraDemo/C++ SDK/inc' CONFIG +=C++11

camerawindow.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
#ifndef CAMERAWINDOW_H #define CAMERAWINDOW_H #include "GalaxyIncludes.h" #include <QDebug> #include <opencv2/core.hpp> #include <opencv2/highgui.hpp> #include <opencv2/imgproc.hpp> #include "mat2qtformatmethod.h" #include <QPixmap> #include <QImage> #include <QLabel> #include <QMessageBox> #include <string> #include "cgxbitmap.h" #include "convertstring.h" #include <time.h> #include <QPainter> #include "drawwidget.h" struct CameraWindowGeoParams{ int WidgetWidth; int WidgetHeight; int LabelWidth; int LabelHeight; int LineeditWidth; int LineeditHeight; int ButtonWidth; int ButtonHeight; }; struct MyUserParam{ cv::Mat CurImgMat; QLabel* LabelShowImgPtr; }; #include <QWidget> namespace Ui { class CameraWindow; struct CameraWindowGeoParams; //class CSampleCaptureEventHandler; } class CameraWindow : public QWidget { Q_OBJECT private: //回调采集事件类 class CSampleCaptureEventHandler : public ICaptureEventHandler { public: void DoOnImageCaptured(CImageDataPointer& objImageDataPointer, void* pUserParam) { if (objImageDataPointer->GetStatus() == GX_FRAME_STATUS_SUCCESS) { CameraWindow* CamUiPtr=(CameraWindow*)pUserParam; //以下为连续采集部分的显示 void* pRaw8Buffer = NULL; pRaw8Buffer = objImageDataPointer->ConvertToRaw8(GX_BIT_0_7); std::memcpy(CamUiPtr->CurImgMat.data, pRaw8Buffer, (objImageDataPointer->GetHeight())*(objImageDataPointer->GetWidth())); //cv::flip(CamUiPtr->CurImgMat, CamUiPtr->CurImgMat, 0);//大恒的图像要进行翻转,但是此处似乎不需要翻转 //调用自定义绘图函数进行绘制实时采集图像 CamUiPtr->ShowCurImgInLabel(CamUiPtr->LabelShowCurImg,CamUiPtr->CurImgMat); //重新调整图像大小以适应窗口,并且此处进行了数据更新,这样才能使用update()函数 //使用drawimage进行绘图的代码 //先得到一张完整的qimage,然后根据窗口进行修改qimage的大小,最后再进行更新。更行时需要对窗口进行提升,使用自定义窗口。 //使用update进行画图有更好的连续性效果 //CamUiPtr->CurImgQimg=CV2QTFORMAT::cvMatToQImage(CamUiPtr->CurImgMat); //CamUiPtr->pDrawWidget->ReSizeImg(CamUiPtr->CurImgQimg); //CamUiPtr->pDrawWidget->update(); //单帧采集 if(CamUiPtr->m_bCheckSaveBmp==true){ MakeMyDirectory(CamUiPtr->strFilePath);//创建文件夹 std::string PathAndName=CamUiPtr->strFilePath+"\"+CamUiPtr->strFileName; CamUiPtr->m_pBitmap->SaveBmp(objImageDataPointer,PathAndName);//保存单帧图像 CamUiPtr->m_bCheckSaveBmp=false; //通过读取的方式画出单帧图像 QString LoadImgName=QString::fromStdString(PathAndName); CamUiPtr->SingleImgPixMap.load(LoadImgName,nullptr,Qt::AutoColor); CamUiPtr->LabelSingleImg->setPixmap(CamUiPtr->SingleImgPixMap); //仅仅在激发采集的时候是有意义的 CamUiPtr->TimeTakePhoto=clock(); qDebug()<<(double)(CamUiPtr->TimeTakePhoto-CamUiPtr->TimePushButton); CamUiPtr->TimePushButton=0; CamUiPtr->TimeTakePhoto=0; } } } }; public: explicit CameraWindow(QWidget *parent = 0); ~CameraWindow(); void CamWinParamsSet(int _WidgetW, int _WidgetH, int _SmallPartW, int _SmallPartH); private slots: void on_pushButton_ListDevice_clicked(); void on_pushButton_OpenCam_clicked(); void on_pushButton_CloseCam_clicked(); void on_pushButton_StartGrab_clicked(); void on_pushButton_StopGrab_clicked(); void on_pushButton_GetImg_clicked(); void on_pushButton_ParamsSet_clicked(); private: Ui::CameraWindow *ui; CameraWindowGeoParams CwParas; //相机库 GxIAPICPP::gxdeviceinfo_vector vectorDeviceInfo;//枚举设备结果 CGXDevicePointer ObjDevicePtr;//当前界面操作的相机指针 CGXStreamPointer ObjStreamPtr;//流采集指针 CGXFeatureControlPointer ObjFeatureControlPtr;//远端设备控制器 ICaptureEventHandler* pCaptureEventHandler;//注册回调事件指针 //Opencv参数 cv::Mat CurImgMat;//实时窗口的Mat void AllocateRoomForMatCurImgPtr();//为实时采集窗口指针分配空间 //这里使用string,然后使用自定义函数进行转换,放弃了MFC的CString类 std::string strFilePath;//保存路径 std::string strFileName;//文件名称 // 保存图像为BMP格式 CGXBitmap* m_pBitmap;// 保存图像指针 bool m_bCheckSaveBmp;// 是否保存图片 int ImgWidth;//记录图片的宽度 int ImgHeight;//记录图片的高度 //展示窗口指针 QLabel* LabelShowCurImg; QLabel* LabelSingleImg; QPixmap SingleImgPixMap; QPixmap CurImgPixMap;//画一个当前的图 DrawWidget* pDrawWidget;//提升窗口指针,使用drawqimage显示实时图像 //使用Painter事件来绘图drawQimg QImage CurImgQimg; QSize LableSize; //计时函数 clock_t TimePushButton; clock_t TimeTakePhoto; double DelayTime;//用于后期设定延时时间 //窗口几何参数设计 void GeoSetWidgetCurInput(int _x, int _y, int _width, int _height);//设置实时采集框几何尺寸 void GeoSetWidgetSampleImg(int _x, int _y, int _width, int _height);//设置单帧采集几何尺寸 void GeoSetFrameParamsSet(int _x, int _y, int _width, int _height, int _dx, int _dy);//设置参数框几何尺寸 void GeoSetFrameCamOperate();//设置操作框几何尺寸 void GeoSetFrameWinInfo();//设置抬头框几何尺寸 //绘制实时采集图像成比例 void ShowCurImgInLabel(QLabel* ptrLabelToShow,cv::Mat& CVMat); }; #endif // CAMERAWINDOW_H

cgxbitmap.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
#ifndef CGXBITMAP_H #define CGXBITMAP_H //------------------------------------------------------------------------ /* file GXBitmap.h brief 此类主要用于图像的显示和存储,图像显示和存储可以自适应黑白彩色相机, 图像存储可以存储为Bmp、Raw,对图像显示和存储进行了声明 */ //------------------------------------------------------------------------ #include "GalaxyIncludes.h" #include "convertstring.h" class CGXBitmap { public: //构造函数 CGXBitmap(CGXDevicePointer& objCGXDevicePointer); //析构函数 ~CGXBitmap(void); //显示图像 void Show(CImageDataPointer& objCImageDataPointer); //显示图像及帧率 void Show(CImageDataPointer& objCImageDataPointer,char* strDeviceSNFPS); //图像处理后并显示图像 void ShowImageProcess(CImageProcessConfigPointer& objCfg,CImageDataPointer& objCImageDataPointer); // 存储Bmp图像 void SaveBmp(CImageDataPointer& objCImageDataPointer,const std::string& strFilePath); // 存储Raw图像 void SaveRaw(CImageDataPointer& objCImageDataPointer,const std::string& strFilePath); //通过GX_PIXEL_FORMAT_ENTRY获取最优Bit位 GX_VALID_BIT_LIST GetBestValudBit(GX_PIXEL_FORMAT_ENTRY emPixelFormatEntry); private: //判断PixelFormat是否为8位 bool __IsPixelFormat8(GX_PIXEL_FORMAT_ENTRY emPixelFormatEntry); //为彩色相机图像显示准备资源 void __ColorPrepareForShowImg(); //为黑白相机图像显示准备资源 void __MonoPrepareForShowImg(); //判断是否兼容 bool __IsCompatible(BITMAPINFO *pBmpInfo, uint64_t nWidth, uint64_t nHeight); //更新Bitmap的信息 void __UpdateBitmap(CImageDataPointer& objCImageDataPointer); //将m_pBufferRGB中图像显示到界面 void __DrawImg(BYTE* pBuffer); //将m_pBufferRGB中图像和帧率显示到界面 void __DrawImg(BYTE* pBuffer, char* strDeviceSNFPS); //计算宽度所占的字节数 int64_t __GetStride(int64_t nWidth, bool bIsColor); private: //CameraWindow* pCamw; //<显示图像窗口(控件)指针 bool m_bIsColor ; //<是否支持彩色相机 int64_t m_nImageHeight; //<原始图像高 int64_t m_nImageWidth; //<原始图像宽 BITMAPINFO *m_pBmpInfo; //<BITMAPINFO 结构指针,显示图像时使用 char m_chBmpBuf[2048]; //<BIMTAPINFO 存储缓冲区,m_pBmpInfo即指向此缓冲区 //这里的这个mfc绘图句柄删去 //HDC m_hDC; //<绘制图像DC句柄 BYTE *m_pImageBuffer; //<保存翻转后的图像用于显示 private: CGXBitmap& operator=(const CGXBitmap&); CGXBitmap(const CGXBitmap&); }; #endif // CGXBITMAP_H

convertstring.h

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
#ifndef CONVERTSTRING_H #define CONVERTSTRING_H #include<string> #include<Windows.h>//此处必须添加windows.h,否则无法识别CreateDirectory函数和LPCTSTR std::wstring StringToWString( const std::string &s);//将string转换为wstring类,便于利用大恒接口写文件 bool MakeMyDirectory(const std::string& strFilePathDirctory);//创建文件夹,方便保存文件, #endif // CONVERTSTRING_H

drawwidget.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
#ifndef DRAWWIDGET_H #define DRAWWIDGET_H #include <QImage> #include <QWidget> #include <QPainter> class DrawWidget : public QWidget { Q_OBJECT public: explicit DrawWidget(QWidget *parent = nullptr); QImage ImgToDraw; void ReSizeImg(QImage InputImg);//将输入的Qimage调整为和窗口大小一致 void SetSize(); protected: void paintEvent(QPaintEvent *event); signals: public slots: private: QSize DrawWigetSize; }; #endif // DRAWWIDGET_H

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
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private slots: void PlotWidget(); void MyCustomPlot(); void on_pushButton_clicked(); private: Ui::MainWindow *ui; int amplitude=1; }; #endif // MAINWINDOW_H

mat2qtformatmethod.h

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#ifndef MAT2QTFORMATMETHOD_H #define MAT2QTFORMATMETHOD_H #include <QDebug> #include <QImage> #include <QPixmap> #include <QtGlobal> #include <opencv2/imgproc.hpp> #include <opencv2/imgproc/types_c.h> // 这是第二种将CV::mat转化为Qimage的函数方法 // 这种方法能够直接识别读入的mat的类型,并且进行相应的转换为Qimage和Qpixmap // 使用这种方法不需要额外调用cvtColor函数来进行BGR转换为RGB namespace CV2QTFORMAT { QImage cvMatToQImage( const cv::Mat &inMat );//cvMat转换为QImage QPixmap cvMatToQPixmap( const cv::Mat &inMat );//cvMat转换为Qpixmap } #endif // MAT2QTFORMATMETHOD_H

qcustomplot.h

camerawindow.cpp

复制代码
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
#include "camerawindow.h" #include "ui_camerawindow.h" #include <QWidget> #include <QString> //窗口构造函数 CameraWindow::CameraWindow(QWidget *parent) : QWidget(parent), ui(new Ui::CameraWindow) //自定义参数的初始化 ,ObjDevicePtr(NULL) ,ObjStreamPtr(NULL) ,ObjFeatureControlPtr(NULL) ,pCaptureEventHandler(NULL) ,m_pBitmap(NULL) ,m_bCheckSaveBmp(false) ,ImgWidth(0) ,ImgHeight(0) ,TimePushButton(0) ,TimeTakePhoto(0) { ui->setupUi(this); LabelShowCurImg=ui->label_CurInput; LabelSingleImg=ui->label_SampleImg;//这两个指针的赋值务必放在setupUi的后面,否则前面没有对应的指针,就是空的 LabelSingleImg->setScaledContents(true);//设置比例 //下面为实时采集图部分 pDrawWidget=ui->widget_CurInput;//用于绘制实时图的时候使用,使用drawimage来绘图 pDrawWidget->SetSize(); //LabelShowCurImg->hide();//使用label进行显示实时图时,将这段注释取消。 ui->lineEdit_ExplosureTime->setText("20000");//设置默认曝光参数 ui->lineEdit_FpsSet->setText("36");//设置默认帧率 ui->lineEdit_FilePath->setText(".\data");//设置默认保存路径,在当前目录下建立一个data文件夹 ui->lineEdit_CamIndex->setText("1");//相机序号默认为1 ui->lineEdit_FileName->setText("test.bmp"); this->CamWinParamsSet(800,800,100,30);//设置界面窗口与部件宽高 this->GeoSetWidgetCurInput(100,100,800,800);//设置实时窗口参数 this->GeoSetWidgetSampleImg(1000,100,800,800);//设置采集窗口参数 this->GeoSetFrameParamsSet(100,910,500,100,10,10);//设置参数框几何参数 } CameraWindow::~CameraWindow() { delete ui; } /* **************************************图形界面几何设计***********************************************/ //设置界面小部件的宽高参数 void CameraWindow::CamWinParamsSet(int _WidgetW,int _WidgetH,int _SmallPartW,int _SmallPartH) { CwParas.WidgetWidth=_WidgetW; CwParas.WidgetHeight=_WidgetH; CwParas.LabelWidth=_SmallPartW; CwParas.LabelHeight=_SmallPartH; CwParas.LineeditWidth=_SmallPartW; CwParas.LineeditHeight=_SmallPartH; CwParas.ButtonWidth=_SmallPartW; CwParas.ButtonHeight=_SmallPartH; } //设置实时采集widget void CameraWindow::GeoSetWidgetCurInput(int _x,int _y, int _width,int _height) { //函数作用:设置相机窗口中的实时采集图像框的几何尺寸 //输入:widget的起始位置x,y,以及widget的大小 //设置对象:包含外框widget部分以及label部分的 //设置变量:widget和label的位置和大小 //设置要求:label和widget大小相同,起始位置也相同 //设置widget ui->widget_CurInput->move(_x,_y); ui->widget_CurInput->resize(_width,_height); //设置label ui->label_CurInput->move(0,0); ui->label_CurInput->resize(_width,_height); } //设置单帧采集widget void CameraWindow::GeoSetWidgetSampleImg(int _x,int _y, int _width,int _height) { //函数作用:设置相机窗口中的单帧采集图像框的几何尺寸 //输入:widget的起始位置x,y,以及widget的大小 //设置对象:包含外框widget部分以及label部分的 //设置变量:widget和label的位置和大小 //设置要求:label和widget大小相同,起始位置也相同 //设置widget ui->widget_SampleImg->move(_x,_y); ui->widget_SampleImg->resize(_width,_height); //设置label ui->label_SampleImg->move(0,0); ui->label_SampleImg->resize(_width,_height); } //设置参数框 void CameraWindow::GeoSetFrameParamsSet(int _x,int _y,int _width, int _height,int _dx,int _dy) { ui->frame_ParmsSet->move(_x,_y); ui->frame_ParmsSet->resize(_width,_height); ui->label_ExplosureTime->move(_dx,_dy);//框内第一行,第一列 ui->label_ExplosureTime->resize(CwParas.LabelWidth,CwParas.LabelHeight); ui->label_FpsSet->move(_dx,2*_dy+CwParas.LabelHeight);//框内第二行,第一列 ui->label_FpsSet->resize(CwParas.LabelWidth,CwParas.LabelHeight); ui->lineEdit_ExplosureTime->move(2*_dx+CwParas.LabelWidth,_dy);//框内第一行,第二列 ui->lineEdit_ExplosureTime->resize(CwParas.LineeditWidth,CwParas.LineeditHeight); ui->lineEdit_FpsSet->move(2*_dx+CwParas.LabelWidth,2*_dy+CwParas.LabelHeight);//框内第二行,第二列 ui->lineEdit_FpsSet->resize(CwParas.LineeditWidth,CwParas.LineeditHeight); ui->pushButton_ParamsSet->move(3*_dx+CwParas.LabelWidth+CwParas.LabelWidth,2*_dy+CwParas.LabelHeight);//框内第二行第三列 ui->pushButton_ParamsSet->resize(CwParas.LineeditWidth,CwParas.LineeditHeight); } //设置操作框 void CameraWindow::GeoSetFrameCamOperate() { } //设置抬头框 void CameraWindow::GeoSetFrameWinInfo() { } /* **************************************相机操作框内的函数设计***********************************************/ //枚举设备按钮 void CameraWindow::on_pushButton_ListDevice_clicked() { IGXFactory::GetInstance().Init();//初始化 IGXFactory::GetInstance().UpdateDeviceList(1000, this->vectorDeviceInfo);//更新设备列表 ui->lineEdit_NumOfCam->setText(QString::number(vectorDeviceInfo.size()));//更新现有设备数,并在窗口显示 } //打开相机按钮 void CameraWindow::on_pushButton_OpenCam_clicked() { int IndexOfCam=(ui->lineEdit_CamIndex->text()).toInt();//得到打开相机的序号 if(vectorDeviceInfo.size()>0&&vectorDeviceInfo.size()>=IndexOfCam&&IndexOfCam>=1){ GxIAPICPP::gxstring strSN = vectorDeviceInfo[IndexOfCam-1].GetSN(); ObjDevicePtr = IGXFactory::GetInstance().OpenDeviceBySN(strSN, GX_ACCESS_EXCLUSIVE); ObjStreamPtr = ObjDevicePtr->OpenStream(IndexOfCam-1);//连接流采集通道 ObjFeatureControlPtr = ObjDevicePtr->GetRemoteFeatureControl();//获取远端设备控制器,可用于调节相机参数 AllocateRoomForMatCurImgPtr();//为Mat矩阵开辟空间 //判断图像对象是否为空 if (m_pBitmap != NULL) { delete m_pBitmap; m_pBitmap = NULL; } //为画图对象分配内存 m_pBitmap = new CGXBitmap(ObjDevicePtr);//为单帧采集开辟空间 } } //关闭相机按钮,使用了try来防止报错 void CameraWindow::on_pushButton_CloseCam_clicked() { try{ ObjStreamPtr->Close(); ObjDevicePtr->Close();//关闭相机,释放资源 if (m_pBitmap != NULL)//释放图片内存空间 { delete m_pBitmap; m_pBitmap = NULL; } } catch (CGalaxyException) { QMessageBox::information(this,"提示","关闭按钮报错,请先枚举设备,再打开相机"); } } //开始采集按钮 void CameraWindow::on_pushButton_StartGrab_clicked() { //进行注册回调采集函数,后期关闭相机自动释放资源 pCaptureEventHandler = new CSampleCaptureEventHandler(); ObjStreamPtr->RegisterCaptureCallback(pCaptureEventHandler,this);//将整个界面作为参数进行传递 //开启流通道采集 ObjStreamPtr->StartGrab(); //给设备发送开采命令 ObjFeatureControlPtr->GetCommandFeature("AcquisitionStart")->Execute(); } //停止采集按钮,使用了try来防止报错 void CameraWindow::on_pushButton_StopGrab_clicked() { try{ ObjFeatureControlPtr->GetCommandFeature("AcquisitionStop")->Execute(); ObjStreamPtr->StopGrab(); //注销采集回调 ObjStreamPtr->UnregisterCaptureCallback(); } catch (CGalaxyException) { QMessageBox::information(this,"提示","停止采集按钮报错,请先枚举设备,再打开相机"); } } //单帧采集按钮 void CameraWindow::on_pushButton_GetImg_clicked() { m_bCheckSaveBmp=true; TimePushButton=clock();//开始计时 /* 这个功能可以另外扩展为一个触发功能 CImageDataPointer ImageDataPtr;//定义一个数据指针 ImageDataPtr = ObjStreamPtr->GetImage(500);//采集单帧数据,超时时间使用500ms,用户可以自行设定 if (ImageDataPtr->GetStatus() == GX_FRAME_STATUS_SUCCESS) { //采图成功而且是完整帧,将数据保存为bmp格式,注意保存的文件名和路径根据窗口来设定 BOOL bRet = CreateDirectory((LPCWSTR)strFilePath.c_str(),NULL);//创建文件夹 m_pBitmap->SaveBmp(ImageDataPtr,strFileName); } */ } /* **************************************拍照参数函数设计***********************************************/ //相机参数设计 void CameraWindow::on_pushButton_ParamsSet_clicked() { //设置曝光时间 float ParmsExposureTime=(ui->lineEdit_ExplosureTime->text()).toFloat(); ParmsExposureTime=ParmsExposureTime>20?ParmsExposureTime:20; ObjFeatureControlPtr->GetFloatFeature("ExposureTime")->SetValue(ParmsExposureTime); //设置采集帧率 float ParmsFps=(ui->lineEdit_FpsSet->text()).toFloat(); ParmsFps=ParmsFps>0.1?ParmsFps:0.1; ObjFeatureControlPtr->GetFloatFeature("AcquisitionFrameRate")->SetValue(ParmsFps); //设置采集路径 strFilePath = ui->lineEdit_FilePath->text().toStdString(); //设置保存文件名 strFileName = ui->lineEdit_FileName->text().toStdString(); } /* **************************************Opencv函数设计***********************************************/ //打开相机时调用此函数获得图片基本信息 void CameraWindow::AllocateRoomForMatCurImgPtr() { ObjFeatureControlPtr= ObjDevicePtr->GetRemoteFeatureControl(); CIntFeaturePointer ObjIntPtrWidth = ObjFeatureControlPtr->GetIntFeature("AAROIWidth"); CIntFeaturePointer ObjIntPtrHeight = ObjFeatureControlPtr->GetIntFeature("AAROIHeight"); ImgWidth=ObjIntPtrWidth->GetValue();//获取图片宽 ImgHeight=ObjIntPtrHeight->GetValue();//获取图片高 CurImgMat.create(ImgHeight,ImgWidth,CV_8UC1);//为Mat矩阵开辟空间 } //连续采集绘图设备 void CameraWindow::ShowCurImgInLabel(QLabel *ptrLabelToShow, cv::Mat &CVMat) { //获取要显示图片的label的大小 QSize LabelSize=ptrLabelToShow->size(); QImage QSrcImg=CV2QTFORMAT::cvMatToQImage(CVMat);//获取一个QImage QImage QSrcImgRatio=QSrcImg.scaled(LabelSize,Qt::IgnoreAspectRatio);//重新调整图像大小以适应窗口 ptrLabelToShow->setPixmap(QPixmap::fromImage(QSrcImgRatio));//显示 }

cgxbitmap.cpp

复制代码
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
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
#include "cgxbitmap.h" #include <cstring> //------------------------------------------------------------------------ /* file GXBitmap.cpp brief 此类主要用于图像的显示和存储,图像显示和存储可以自适应黑白彩色相机, 图像存储可以存储为Bmp、Raw,对图像显示和存储进行了实现 */ //------------------------------------------------------------------------ //--------------------------------------------------------------------------------- /* brief 构造函数 param objCGXDevicePointer 图像设备指针 param pWnd 窗体指针 return 无 */ //---------------------------------------------------------------------------------- CGXBitmap::CGXBitmap(CGXDevicePointer& objCGXDevicePointer) : //pCamw(m_pCamw) //,m_hDC(NULL) m_bIsColor(false) ,m_nImageHeight(0) ,m_nImageWidth(0) ,m_pBmpInfo(NULL) ,m_pImageBuffer(NULL) { if (objCGXDevicePointer.IsNull()) { throw std::runtime_error("Argument is error"); } //这里将mfc的代码隐藏了 //HWND hWnd = pCamw->m_hWnd; //if (!::IsWindow(hWnd)) //{ // throw std::runtime_error("The HWND must be form"); //} //m_hDC = ::GetDC(m_pWnd->m_hWnd); memset(m_chBmpBuf,0,sizeof(m_chBmpBuf)); gxstring strValue = ""; //获得图像宽度、高度等 m_nImageWidth = (int64_t)objCGXDevicePointer->GetRemoteFeatureControl()->GetIntFeature("Width")->GetValue(); m_nImageHeight = (int64_t)objCGXDevicePointer->GetRemoteFeatureControl()->GetIntFeature("Height")->GetValue(); //获取是否为彩色相机 if (objCGXDevicePointer->GetRemoteFeatureControl()->IsImplemented("PixelColorFilter")) { strValue = objCGXDevicePointer->GetRemoteFeatureControl()->GetEnumFeature("PixelColorFilter")->GetValue(); if ("None" != strValue) { m_bIsColor = true; } } if (m_bIsColor) { __ColorPrepareForShowImg(); } else { __MonoPrepareForShowImg(); } } //--------------------------------------------------------------------------------- /* brief 析构函数 return 无 */ //---------------------------------------------------------------------------------- CGXBitmap::~CGXBitmap(void) { //释放pDC //::ReleaseDC(m_pWnd->m_hWnd, m_hDC); if (m_pImageBuffer != NULL) { delete m_pImageBuffer; m_pImageBuffer = NULL; } } //---------------------------------------------------------------------------------- /* brief 判断PixelFormat是否为8位 param emPixelFormatEntry 图像数据格式 return true为8为数据,false为非8位数据 */ //---------------------------------------------------------------------------------- bool CGXBitmap::__IsPixelFormat8(GX_PIXEL_FORMAT_ENTRY emPixelFormatEntry) { bool bIsPixelFormat8 = false; const unsigned PIXEL_FORMATE_BIT = 0x00FF0000; //<用于与当前的数据格式进行与运算得到当前的数据位数 unsigned uiPixelFormatEntry = (unsigned)emPixelFormatEntry; if ((uiPixelFormatEntry & PIXEL_FORMATE_BIT) == GX_PIXEL_8BIT) { bIsPixelFormat8 = true; } return bIsPixelFormat8; } //---------------------------------------------------------------------------------- /* brief 通过GX_PIXEL_FORMAT_ENTRY获取最优Bit位 param emPixelFormatEntry 图像数据格式 return 最优Bit位 */ //---------------------------------------------------------------------------------- GX_VALID_BIT_LIST CGXBitmap::GetBestValudBit(GX_PIXEL_FORMAT_ENTRY emPixelFormatEntry) { GX_VALID_BIT_LIST emValidBits = GX_BIT_0_7; switch (emPixelFormatEntry) { case GX_PIXEL_FORMAT_MONO8: case GX_PIXEL_FORMAT_BAYER_GR8: case GX_PIXEL_FORMAT_BAYER_RG8: case GX_PIXEL_FORMAT_BAYER_GB8: case GX_PIXEL_FORMAT_BAYER_BG8: { emValidBits = GX_BIT_0_7; break; } case GX_PIXEL_FORMAT_MONO10: case GX_PIXEL_FORMAT_BAYER_GR10: case GX_PIXEL_FORMAT_BAYER_RG10: case GX_PIXEL_FORMAT_BAYER_GB10: case GX_PIXEL_FORMAT_BAYER_BG10: { emValidBits = GX_BIT_2_9; break; } case GX_PIXEL_FORMAT_MONO12: case GX_PIXEL_FORMAT_BAYER_GR12: case GX_PIXEL_FORMAT_BAYER_RG12: case GX_PIXEL_FORMAT_BAYER_GB12: case GX_PIXEL_FORMAT_BAYER_BG12: { emValidBits = GX_BIT_4_11; break; } case GX_PIXEL_FORMAT_MONO14: { //暂时没有这样的数据格式待升级 break; } case GX_PIXEL_FORMAT_MONO16: case GX_PIXEL_FORMAT_BAYER_GR16: case GX_PIXEL_FORMAT_BAYER_RG16: case GX_PIXEL_FORMAT_BAYER_GB16: case GX_PIXEL_FORMAT_BAYER_BG16: { //暂时没有这样的数据格式待升级 break; } default: break; } return emValidBits; } //--------------------------------------------------------------------------------- /* brief 为彩色相机图像显示准备资源 return 无 */ //---------------------------------------------------------------------------------- void CGXBitmap::__ColorPrepareForShowImg() { //-------------------------------------------------------------------- //---------------------------初始化bitmap头--------------------------- m_pBmpInfo = (BITMAPINFO *)m_chBmpBuf; m_pBmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); m_pBmpInfo->bmiHeader.biWidth = (LONG)m_nImageWidth; m_pBmpInfo->bmiHeader.biHeight = (LONG)m_nImageHeight; m_pBmpInfo->bmiHeader.biPlanes = 1; m_pBmpInfo->bmiHeader.biBitCount = 24; m_pBmpInfo->bmiHeader.biCompression = BI_RGB; m_pBmpInfo->bmiHeader.biSizeImage = 0; m_pBmpInfo->bmiHeader.biXPelsPerMeter = 0; m_pBmpInfo->bmiHeader.biYPelsPerMeter = 0; m_pBmpInfo->bmiHeader.biClrUsed = 0; m_pBmpInfo->bmiHeader.biClrImportant = 0; } //--------------------------------------------------------------------------------- /* brief 为黑白相机图像显示准备资源 return 无 */ //---------------------------------------------------------------------------------- void CGXBitmap::__MonoPrepareForShowImg() { //--------------------------------------------------------------------- //----------------------初始化bitmap头--------------------------------- m_pBmpInfo = (BITMAPINFO *)m_chBmpBuf; m_pBmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); m_pBmpInfo->bmiHeader.biWidth = (LONG)m_nImageWidth; m_pBmpInfo->bmiHeader.biHeight = (LONG)m_nImageHeight; m_pBmpInfo->bmiHeader.biPlanes = 1; m_pBmpInfo->bmiHeader.biBitCount = 8; // 黑白图像为8 m_pBmpInfo->bmiHeader.biCompression = BI_RGB; m_pBmpInfo->bmiHeader.biSizeImage = 0; m_pBmpInfo->bmiHeader.biXPelsPerMeter = 0; m_pBmpInfo->bmiHeader.biYPelsPerMeter = 0; m_pBmpInfo->bmiHeader.biClrUsed = 0; m_pBmpInfo->bmiHeader.biClrImportant = 0; // 黑白图像需要初始化调色板 for(int i=0;i<256;i++) { m_pBmpInfo->bmiColors[i].rgbBlue =i; m_pBmpInfo->bmiColors[i].rgbGreen =i; m_pBmpInfo->bmiColors[i].rgbRed =i; m_pBmpInfo->bmiColors[i].rgbReserved=i; } //为经过翻转后的图像数据分配空间 if (m_pImageBuffer != NULL) { delete m_pImageBuffer; m_pImageBuffer = NULL; } m_pImageBuffer = new BYTE[(size_t)(m_nImageWidth * m_nImageHeight)]; if (m_pImageBuffer == NULL) { throw std::runtime_error("Fail to allocate memory"); } } //---------------------------------------------------------------------------------- /* brief 判断是否兼容 param pBmpInfo BITMAPINFO指针 param nWidth 图像宽 param nHeight 图像高 return true为一样,false不一样 */ //---------------------------------------------------------------------------------- bool CGXBitmap::__IsCompatible(BITMAPINFO *pBmpInfo, uint64_t nWidth, uint64_t nHeight) { if (pBmpInfo == NULL || pBmpInfo->bmiHeader.biHeight != nHeight || pBmpInfo->bmiHeader.biWidth != nWidth ) { return false; } return true; } //---------------------------------------------------------------------------------- /* brief 检查图像是否改变并更新Buffer并为图像显示准备资源 param objCImageDataPointer 图像数据对象 return 无 */ //---------------------------------------------------------------------------------- void CGXBitmap::__UpdateBitmap(CImageDataPointer& objCImageDataPointer) { if (!__IsCompatible(m_pBmpInfo, objCImageDataPointer->GetWidth(), objCImageDataPointer->GetHeight())) { m_nImageWidth = objCImageDataPointer->GetWidth(); m_nImageHeight = objCImageDataPointer->GetHeight(); if (m_bIsColor) { __ColorPrepareForShowImg(); } else { __MonoPrepareForShowImg(); } } } //--------------------------------------------------------------------------------- /* brief 将m_pBufferRGB中图像显示到界面 param pBuffer 图像数据Buffer指针 return 无 */ //---------------------------------------------------------------------------------- void CGXBitmap::__DrawImg(BYTE* pBuffer) { } //--------------------------------------------------------------------------------- /* brief 将m_pBufferRGB中图像显示到界面 param pBuffer 图像数据Buffer指针 param strDeviceSNFPS 设备帧率序列号 return 无 */ //---------------------------------------------------------------------------------- void CGXBitmap::__DrawImg(BYTE* pBuffer, char* strDeviceSNFPS) { } //---------------------------------------------------------------------------------- /* brief 计算宽度所占的字节数 param nWidth 图像宽度 param bIsColor 是否是彩色相机 return 图像一行所占的字节数 */ //---------------------------------------------------------------------------------- int64_t CGXBitmap::__GetStride(int64_t nWidth, bool bIsColor) { return bIsColor ? nWidth * 3 : nWidth; } //---------------------------------------------------------------------------------- /* brief 用于显示图像 param objCImageDataPointer 图像数据对象 return 无 */ //---------------------------------------------------------------------------------- void CGXBitmap::Show(CImageDataPointer& objCImageDataPointer) { GX_VALID_BIT_LIST emValidBits = GX_BIT_0_7; BYTE* pBuffer = NULL; if (objCImageDataPointer.IsNull()) { throw std::runtime_error("NULL pointer dereferenced"); } //检查图像是否改变并更新Buffer __UpdateBitmap(objCImageDataPointer); emValidBits = GetBestValudBit(objCImageDataPointer->GetPixelFormat()); if (m_bIsColor) { pBuffer = (BYTE*)objCImageDataPointer->ConvertToRGB24(emValidBits, GX_RAW2RGB_NEIGHBOUR, true); __DrawImg(pBuffer); } else { if (__IsPixelFormat8(objCImageDataPointer->GetPixelFormat())) { pBuffer = (BYTE*)objCImageDataPointer->GetBuffer(); } else { pBuffer = (BYTE*)objCImageDataPointer->ConvertToRaw8(emValidBits); } // 黑白相机需要翻转数据后显示 for(int i =0;i <m_nImageHeight;i++) { memcpy(m_pImageBuffer+i*m_nImageWidth, pBuffer+(m_nImageHeight-i-1)*m_nImageWidth,(size_t)m_nImageWidth); } __DrawImg(m_pImageBuffer); } } //---------------------------------------------------------------------------------- /* brief 用于显示图像 param objCImageDataPointer 图像数据对象 param strDeviceSNFPS 图像帧率序列号 return 无 */ //---------------------------------------------------------------------------------- void CGXBitmap::Show(CImageDataPointer& objCImageDataPointer,char* strDeviceSNFPS) { GX_VALID_BIT_LIST emValidBits = GX_BIT_0_7; BYTE* pBuffer = NULL; if (objCImageDataPointer.IsNull()) { throw std::runtime_error("NULL pointer dereferenced"); } //检查图像是否改变并更新Buffer __UpdateBitmap(objCImageDataPointer); emValidBits = GetBestValudBit(objCImageDataPointer->GetPixelFormat()); if (m_bIsColor) { pBuffer = (BYTE*)objCImageDataPointer->ConvertToRGB24(emValidBits, GX_RAW2RGB_NEIGHBOUR, true); __DrawImg(pBuffer,strDeviceSNFPS); } else { if (__IsPixelFormat8(objCImageDataPointer->GetPixelFormat())) { pBuffer = (BYTE*)objCImageDataPointer->GetBuffer(); } else { pBuffer = (BYTE*)objCImageDataPointer->ConvertToRaw8(emValidBits); } // 黑白相机需要翻转数据后显示 for(int i =0;i <m_nImageHeight;i++) { memcpy(m_pImageBuffer + i * m_nImageWidth, pBuffer + (m_nImageHeight - i -1) * m_nImageWidth,(size_t)m_nImageWidth); } __DrawImg(m_pImageBuffer,strDeviceSNFPS); } } //---------------------------------------------------------------------------------- /* brief 用于图像处理后并显示图像 param objCfg 图像处理调节参数对象 param objCImageDataPointer 图像数据对象 return 无 */ //---------------------------------------------------------------------------------- void CGXBitmap::ShowImageProcess(CImageProcessConfigPointer& objCfg,CImageDataPointer& objCImageDataPointer) { if ((objCfg.IsNull())||(objCImageDataPointer.IsNull())) { throw std::runtime_error("NULL pointer dereferenced"); } //检查图像是否改变并更新Buffer __UpdateBitmap(objCImageDataPointer); BYTE* pBuffer = (BYTE*)objCImageDataPointer->ImageProcess(objCfg); if (m_bIsColor) { __DrawImg(pBuffer); } else { // 黑白相机需要翻转数据后显示 for(int i =0;i <m_nImageHeight;i++) { memcpy(m_pImageBuffer + i * m_nImageWidth, pBuffer + (m_nImageHeight - i -1) * m_nImageWidth,(size_t)m_nImageWidth); } __DrawImg(m_pImageBuffer); } } //---------------------------------------------------------------------------------- /* brief 存储Bmp图像 param objCImageDataPointer 图像数据对象 param strFilePath 显示图像文件名 return 无 */ //---------------------------------------------------------------------------------- void CGXBitmap::SaveBmp(CImageDataPointer& objCImageDataPointer,const std::string& strFilePath) { GX_VALID_BIT_LIST emValidBits = GX_BIT_0_7; BYTE* pBuffer = NULL; if ((objCImageDataPointer.IsNull())||(strFilePath == "")) { throw std::runtime_error("Argument is error"); } //检查图像是否改变并更新Buffer __UpdateBitmap(objCImageDataPointer); emValidBits = GetBestValudBit(objCImageDataPointer->GetPixelFormat()); if (m_bIsColor) { pBuffer = (BYTE*)objCImageDataPointer->ConvertToRGB24(emValidBits, GX_RAW2RGB_NEIGHBOUR, true); } else { if (__IsPixelFormat8(objCImageDataPointer->GetPixelFormat())) { pBuffer = (BYTE*)objCImageDataPointer->GetBuffer(); } else { pBuffer = (BYTE*)objCImageDataPointer->ConvertToRaw8(emValidBits); } // 黑白相机需要翻转数据后显示 for(int i =0;i < m_nImageHeight;i++) { memcpy(m_pImageBuffer + i * m_nImageWidth, pBuffer + (m_nImageHeight - i -1) * m_nImageWidth,(size_t)m_nImageWidth); } pBuffer = m_pImageBuffer; } DWORD dwImageSize = (DWORD)(__GetStride(m_nImageWidth,m_bIsColor) * m_nImageHeight); BITMAPFILEHEADER stBfh = {0}; DWORD dwBytesRead = 0; stBfh.bfType = (WORD)'M' << 8 | 'B'; //定义文件类型 stBfh.bfOffBits = m_bIsColor ?sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) :sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + (256 * 4); //定义文件头大小true为彩色,false为黑白 stBfh.bfSize = stBfh.bfOffBits + dwImageSize; //文件大小 DWORD dwBitmapInfoHeader = m_bIsColor ?sizeof(BITMAPINFOHEADER) :sizeof(BITMAPINFOHEADER) + (256 * 4); //定义BitmapInfoHeader大小true为彩色,false为黑白 //创建文件 std::wstring s=StringToWString(strFilePath); LPCTSTR LPCSTR_ImgFileName=s.c_str();//使用了我自定义的一个转换函数,并且连续调用了.c_str(),并对下面CreateFile进行了修改 HANDLE hFile = ::CreateFile(LPCSTR_ImgFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { throw std::runtime_error("Handle is invalid"); } ::WriteFile(hFile, &stBfh, sizeof(BITMAPFILEHEADER), &dwBytesRead, NULL); ::WriteFile(hFile, m_pBmpInfo, dwBitmapInfoHeader, &dwBytesRead, NULL); //黑白和彩色自适应 ::WriteFile(hFile, pBuffer, dwImageSize, &dwBytesRead, NULL); CloseHandle(hFile); } //---------------------------------------------------------------------------------- /* brief 存储Raw图像 param objCImageDataPointer 图像数据对象 param strFilePath 显示图像文件名 return 无 */ //---------------------------------------------------------------------------------- void CGXBitmap::SaveRaw(CImageDataPointer& objCImageDataPointer,const std::string& strFilePath) { if ((objCImageDataPointer.IsNull())||(strFilePath == "")) { throw std::runtime_error("Argument is error"); } //检查图像是否改变并更新Buffer __UpdateBitmap(objCImageDataPointer); DWORD dwImageSize = (DWORD)objCImageDataPointer->GetPayloadSize(); // 写入文件的长度 DWORD dwBytesRead = 0; // 文件读取的长度 BYTE* pbuffer = (BYTE*)objCImageDataPointer->GetBuffer(); if (!m_bIsColor) { // 黑白相机需要翻转数据后显示 for(int i =0;i < m_nImageHeight;i++) { memcpy(m_pImageBuffer + i * m_nImageWidth, pbuffer + (m_nImageHeight - i -1) * m_nImageWidth,(size_t)m_nImageWidth); } pbuffer = m_pImageBuffer; } // 创建文件 std::wstring s=StringToWString(strFilePath); LPCTSTR LPCSTR_ImgFileName=s.c_str();//使用了我自定义的一个转换函数,并且连续调用了.c_str(),并对下面CreateFile进行了修改 HANDLE hFile = ::CreateFile(LPCSTR_ImgFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) // 创建失败则返回 { throw std::runtime_error("Handle is invalid"); } else // 保存Raw图像 { ::WriteFile(hFile, pbuffer, dwImageSize, &dwBytesRead, NULL); CloseHandle(hFile); } }

convertstring.cpp

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include"convertstring.h" std::wstring StringToWString( const std::string &s) { std::wstring wsTmp(s.begin(), s.end()); return wsTmp; } bool MakeMyDirectory(const std::string &strFilePathDirctory) { std::wstring wDirectoryName = StringToWString(strFilePathDirctory); LPCTSTR lpwdir = wDirectoryName.c_str(); return CreateDirectory(lpwdir, NULL); }

drawwidget.cpp

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include "drawwidget.h" DrawWidget::DrawWidget(QWidget *parent) : QWidget(parent) { } void DrawWidget::ReSizeImg(QImage InputImg) { ImgToDraw=InputImg.scaled(DrawWigetSize,Qt::IgnoreAspectRatio); } void DrawWidget::SetSize() { DrawWigetSize=this->size(); } void DrawWidget::paintEvent(QPaintEvent *event) { QPainter p(this); p.drawImage(0,0,ImgToDraw); }

main.cpp

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include "mainwindow.h" #include "camerawindow.h" #include <QApplication> #include <opencv2/core.hpp> #include <opencv2/highgui.hpp> #include<QDebug> int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; CameraWindow Cam; w.show(); Cam.show(); return a.exec(); }

mainwindow.cpp

复制代码
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
#include "mainwindow.h" #include <QtCharts> QT_CHARTS_USE_NAMESPACE #include "ui_mainwindow.h" #include <QDebug> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); this->PlotWidget(); this->MyCustomPlot(); } MainWindow::~MainWindow() { delete ui; } void MainWindow::PlotWidget() { QChart* chart = new QChart(); QLineSeries *series = new QLineSeries(); for (quint32 i = 0; i < 100; i++) { series->append(i, this->amplitude*sin(0.6f*i)); } chart->addSeries(series); chart->createDefaultAxes(); // 基于已添加到图表的 series 来创建默认的坐标轴 ui->widget_Plot->setChart(chart); ui->widget_Plot->resize(500,500); } void MainWindow::MyCustomPlot() { QVector<double> x(101), y(101); // initialize with entries 0..100 for (int i=0; i<101; ++i) { x[i] = i/50.0 - 1; // x goes from -1 to 1 y[i] = x[i]*x[i]; // let's plot a quadratic function } // create graph and assign data to it: ui->widget_customPlot->addGraph(); ui->widget_customPlot->graph(0)->setData(x, y); // give the axes some labels: ui->widget_customPlot->xAxis->setLabel("x"); ui->widget_customPlot->yAxis->setLabel("y"); // set axes ranges, so we see all data: ui->widget_customPlot->xAxis->setRange(-1, 1); ui->widget_customPlot->yAxis->setRange(0, 1); ui->widget_customPlot->replot(); } void MainWindow::on_pushButton_clicked() { this->amplitude=this->amplitude*10; }

mat2qtformatmethod.cpp

复制代码
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
#include "mat2qtformatmethod.h" namespace CV2QTFORMAT { // NOTE: This does not cover all cases - it should be easy to add new ones as required. QImage cvMatToQImage( const cv::Mat &inMat ) { switch ( inMat.type() ) { // 8-bit, 4 channel case CV_8UC4: { QImage image( inMat.data, inMat.cols, inMat.rows, static_cast<int>(inMat.step), QImage::Format_ARGB32 ); return image; } // 8-bit, 3 channel case CV_8UC3: { QImage image( inMat.data, inMat.cols, inMat.rows, static_cast<int>(inMat.step), QImage::Format_RGB888 ); return image.rgbSwapped(); } // 8-bit, 1 channel case CV_8UC1: { #if QT_VERSION >= QT_VERSION_CHECK(5, 5, 0) QImage image( inMat.data, inMat.cols, inMat.rows, static_cast<int>(inMat.step), QImage::Format_Grayscale8 ); #else static QVector<QRgb> sColorTable; // only create our color table the first time if ( sColorTable.isEmpty() ) { sColorTable.resize( 256 ); for ( int i = 0; i < 256; ++i ) { sColorTable[i] = qRgb( i, i, i ); } } QImage image( inMat.data, inMat.cols, inMat.rows, static_cast<int>(inMat.step), QImage::Format_Indexed8 ); image.setColorTable( sColorTable ); #endif return image; } default: qWarning() << "ASM::cvMatToQImage() - cv::Mat image type not handled in switch:" << inMat.type(); break; } return QImage(); } QPixmap cvMatToQPixmap( const cv::Mat &inMat ) { return QPixmap::fromImage( CV2QTFORMAT::cvMatToQImage( inMat ) ); } }

qcustomplot.cpp

文件下载

链接:https://pan.baidu.com/s/1RqvkmACFslQxbHzkkihV_g
提取码:o09o

最后

以上就是稳重灯泡最近收集整理的关于qt项目:大恒相机实时采集,单帧采集,并且在屏幕上显示,含有保存bmp图片功能文件下载的全部内容,更多相关qt项目:大恒相机实时采集内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(89)

评论列表共有 0 条评论

立即
投稿
返回
顶部