qt项目:大恒相机实时采集,单帧采集,并且在屏幕上显示,含有保存bmp图片功能

软件框架

在这里插入图片描述

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

.pro文件

#-------------------------------------------------
#
# 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

#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

#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

#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

#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

#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

#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

#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

#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

#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

#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

#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

#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

#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

  • 15
    点赞
  • 92
    收藏
    觉得还不错? 一键收藏
  • 82
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 82
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值