当前位置:   article > 正文

(三)Qt+OpenCV调用海康工业相机SDK抓拍示例_qt 海康相机

qt 海康相机

系列文章目录

提示:这里是该系列文章的所有文章的目录
第一章: (一)Qt+OpenCV调用海康工业相机SDK示例开发
第二章: (二)Qt多线程实现海康工业相机图像实时采集
第三章: (三)Qt+OpenCV调用海康工业相机SDK抓拍示例



前言

在这系列文章中,讲述了Qt下结合OpenCV与海康工业相机的使用,对前文的功能进行拓展,在这里做了一个使用海康彩色工业相机定时抓拍的示例,并将相关代码展现出来以便大家学习,如有错误之处,欢迎大家批评指正。

项目效果
请添加图片描述


提示:以下是本篇文章正文内容,下面案例可供参考

一、项目配置

本文示例是在MSVC_64bit下Release构建的,然后引入了海康SDK和OpenCV对应的库,所以项目的pro文件如下:
MyCamera.pro

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

DEFINES += QT_DEPRECATED_WARNINGS

#设置字符
contains( CONFIG,"msvc" ):QMAKE_CXXFLAGS += /source-charset:utf-8 /execution-charset:utf-8
contains( CONFIG,"msvc" ):QMAKE_CFLAGS +=/source-charset:utf-8 /execution-charset:utf-8

SOURCES += \
    capturethread.cpp \
    cmvcamera.cpp \
    main.cpp \
    widget.cpp

HEADERS += \
    capturethread.h \
    cmvcamera.h \
    widget.h

FORMS += \
    widget.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

#HikSDK
INCLUDEPATH += $$PWD/SDK/HikSDK/Includes
DEPENDPATH += $$PWD/SDK/HikSDK/Includes
LIBS += -L$$PWD/SDK/HikSDK/Lib/ -lMvCameraControl

#OpenCV
INCLUDEPATH += $$PWD/SDK/OpenCV/Includes
DEPENDPATH += $$PWD/SDK/OpenCV/Includes
LIBS += -L$$PWD/SDK/OpenCV/Lib/ -lopencv_world455
  • 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

二、图像采集与保存

示例采集的原理:
//点击开始采集后,会关闭触发模式,相机就会不断回调,实时显示相机图像
//点击停止采集后,会开启触发模式并设置为软触发,需要调用命令触发回调

在设备打开后,通过点击抓拍按钮开启线程并打开保存标志位,在线程中使用OpenCV的imwrite函数来进行图像的保存。

//抓拍图像
void Widget::on_pb_grab_clicked()
{
    if(!m_bOpenDevice)
    {
        QMessageBox::warning(this,"警告","抓拍失败,请打开设备!");
        return;
    }

    int time = ui->le_time->text().toInt();
    int num = ui->le_num->text().toInt();
    m_captureThread->setCameraSignal(time,num);
    m_captureThread->setSwitchFlag(true);
    m_captureThread->setSaveFlag(true);
    m_captureThread->start();
}

......

//保存原图
void CaptureThread::saveOriginImage(cv::Mat imageMat)
{
    clock_t originClock = -clock();
    QString curTime = QTime::currentTime().toString("hhmmss");
    QString iamgeName = m_originPath + "GrabImage_" + curTime + ".jpg";
    cv::Mat saveMat;
    cvtColor(imageMat,saveMat,cv::COLOR_BGR2RGB);   //颜色格式转换
    imwrite(iamgeName.toStdString(),saveMat);
    originClock += clock();
    LOGDEBUG<<"保存原图耗时:"<<originClock<<"ms";   //测试在20ms左右
}
  • 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

三、示例完整代码

示例的功能实现就不多说了,在下面的代码中有详细的注释,这里将完整代码展示出来:
1.cmvcamera.h(直接从海康提供的SDK中复制,进行了一些修改)

/************************************************************************/
/* 以C++接口为基础,对常用函数进行二次封装,方便用户使用                */
/************************************************************************/

#ifndef _MV_CAMERA_H_
#define _MV_CAMERA_H_

#include <string.h>
#include <QCoreApplication>
#include "MvCameraControl.h"
#include "opencv2/opencv.hpp"

//会跟系统函数定义冲突
//using namespace cv;

#ifndef MV_NULL
#define MV_NULL    0
#endif

class CMvCamera
{
public:
    CMvCamera();
    ~CMvCamera();

    // ch:获取SDK版本号 | en:Get SDK Version
    static int GetSDKVersion();

    // ch:枚举设备 | en:Enumerate Device
    static int EnumDevices(unsigned int nTLayerType, MV_CC_DEVICE_INFO_LIST* pstDevList);

    // ch:判断设备是否可达 | en:Is the device accessible
    static bool IsDeviceAccessible(MV_CC_DEVICE_INFO* pstDevInfo, unsigned int nAccessMode);

    // ch:打开设备 | en:Open Device
    int Open(MV_CC_DEVICE_INFO* pstDeviceInfo);

    // ch:关闭设备 | en:Close Device
    int Close();

    // ch:判断相机是否处于连接状态 | en:Is The Device Connected
    bool IsDeviceConnected();

    // ch:注册图像数据回调 | en:Register Image Data CallBack
    int RegisterImageCallBack(void(__stdcall* cbOutput)(unsigned char * pData, MV_FRAME_OUT_INFO_EX* pFrameInfo, void* pUser), void* pUser);

    // ch:注册彩色图像数据回调
    int RegisterImageCallBackRGB(void(__stdcall* cbOutput)(unsigned char * pData, MV_FRAME_OUT_INFO_EX* pFrameInfo, void* pUser), void* pUser);

    // ch:开启抓图 | en:Start Grabbing
    int StartGrabbing();

    // ch:停止抓图 | en:Stop Grabbing
    int StopGrabbing();

    // ch:主动获取一帧图像数据 | en:Get one frame initiatively
    int GetImageBuffer(MV_FRAME_OUT* pFrame, int nMsec);

    // ch:释放图像缓存 | en:Free image buffer
    int FreeImageBuffer(MV_FRAME_OUT* pFrame);

    // ch:显示一帧图像 | en:Display one frame image
    int DisplayOneFrame(MV_DISPLAY_FRAME_INFO* pDisplayInfo);

    // ch:设置SDK内部图像缓存节点个数 | en:Set the number of the internal image cache nodes in SDK
    int SetImageNodeNum(unsigned int nNum);

    // ch:获取设备信息 | en:Get device information
    int GetDeviceInfo(MV_CC_DEVICE_INFO* pstDevInfo);

    // ch:获取GEV相机的统计信息 | en:Get detect info of GEV camera
    int GetGevAllMatchInfo(MV_MATCH_INFO_NET_DETECT* pMatchInfoNetDetect);

    // ch:获取U3V相机的统计信息 | en:Get detect info of U3V camera
    int GetU3VAllMatchInfo(MV_MATCH_INFO_USB_DETECT* pMatchInfoUSBDetect);

    // ch:获取和设置Int型参数,如 Width和Height,详细内容参考SDK安装目录下的 MvCameraNode.xlsx 文件
    // en:Get Int type parameters, such as Width and Height, for details please refer to MvCameraNode.xlsx file under SDK installation directory
    int GetIntValue(IN const char* strKey, OUT MVCC_INTVALUE_EX *pIntValue);
    int SetIntValue(IN const char* strKey, IN int64_t nValue);

    // ch:获取和设置Enum型参数,如 PixelFormat,详细内容参考SDK安装目录下的 MvCameraNode.xlsx 文件
    // en:Get Enum type parameters, such as PixelFormat, for details please refer to MvCameraNode.xlsx file under SDK installation directory
    int GetEnumValue(IN const char* strKey, OUT MVCC_ENUMVALUE *pEnumValue);
    int SetEnumValue(IN const char* strKey, IN unsigned int nValue);
    int SetEnumValueByString(IN const char* strKey, IN const char* sValue);
    int GetEnumEntrySymbolic(IN const char* strKey, IN MVCC_ENUMENTRY* pstEnumEntry);

    // ch:获取和设置Float型参数,如 ExposureTime和Gain,详细内容参考SDK安装目录下的 MvCameraNode.xlsx 文件
    // en:Get Float type parameters, such as ExposureTime and Gain, for details please refer to MvCameraNode.xlsx file under SDK installation directory
    int GetFloatValue(IN const char* strKey, OUT MVCC_FLOATVALUE *pFloatValue);
    int SetFloatValue(IN const char* strKey, IN float fValue);

    // ch:获取和设置Bool型参数,如 ReverseX,详细内容参考SDK安装目录下的 MvCameraNode.xlsx 文件
    // en:Get Bool type parameters, such as ReverseX, for details please refer to MvCameraNode.xlsx file under SDK installation directory
    int GetBoolValue(IN const char* strKey, OUT bool *pbValue);
    int SetBoolValue(IN const char* strKey, IN bool bValue);

    // ch:获取和设置String型参数,如 DeviceUserID,详细内容参考SDK安装目录下的 MvCameraNode.xlsx 文件UserSetSave
    // en:Get String type parameters, such as DeviceUserID, for details please refer to MvCameraNode.xlsx file under SDK installation directory
    int GetStringValue(IN const char* strKey, MVCC_STRINGVALUE *pStringValue);
    int SetStringValue(IN const char* strKey, IN const char * strValue);

    // ch:执行一次Command型命令,如 UserSetSave,详细内容参考SDK安装目录下的 MvCameraNode.xlsx 文件
    // en:Execute Command once, such as UserSetSave, for details please refer to MvCameraNode.xlsx file under SDK installation directory
    int CommandExecute(IN const char* strKey);

    // ch:探测网络最佳包大小(只对GigE相机有效) | en:Detection network optimal package size(It only works for the GigE camera)
    int GetOptimalPacketSize(unsigned int* pOptimalPacketSize);

    // ch:注册消息异常回调 | en:Register Message Exception CallBack
    int RegisterExceptionCallBack(void(__stdcall* cbException)(unsigned int nMsgType, void* pUser), void* pUser);

    // ch:注册单个事件回调 | en:Register Event CallBack
    int RegisterEventCallBack(const char* pEventName, void(__stdcall* cbEvent)(MV_EVENT_OUT_INFO * pEventInfo, void* pUser), void* pUser);

    // ch:强制IP | en:Force IP
    int ForceIp(unsigned int nIP, unsigned int nSubNetMask, unsigned int nDefaultGateWay);

    // ch:配置IP方式 | en:IP configuration method
    int SetIpConfig(unsigned int nType);

    // ch:设置网络传输模式 | en:Set Net Transfer Mode
    int SetNetTransMode(unsigned int nType);

    // ch:像素格式转换 | en:Pixel format conversion
    int ConvertPixelType(MV_CC_PIXEL_CONVERT_PARAM* pstCvtParam);

    // ch:保存图片 | en:save image
    int SaveImage(MV_SAVE_IMAGE_PARAM_EX* pstParam);

    // ch:保存图片为文件 | en:Save the image as a file
    int SaveImageToFile(MV_SAVE_IMG_TO_FILE_PARAM* pstParam);

    // ch:绘制圆形辅助线 | en:Draw circle auxiliary line
    int DrawCircle(MVCC_CIRCLE_INFO* pCircleInfo);

    // ch:绘制线形辅助线 | en:Draw lines auxiliary line
    int DrawLines(MVCC_LINES_INFO* pLinesInfo);

    //读取相机中的图像
    int ReadBuffer(cv::Mat &image);

    //保存相机中的图像
    int SaveBuffer(QByteArray imageName);

private:

    void *m_hDevHandle;
};
#endif//_MV_CAMERA_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

2.cmvcamera.cpp

#include "cmvcamera.h"

CMvCamera::CMvCamera()
{
    m_hDevHandle = MV_NULL;
}

CMvCamera::~CMvCamera()
{
    if (m_hDevHandle)
    {
        MV_CC_DestroyHandle(m_hDevHandle);
        m_hDevHandle = MV_NULL;
    }
}

// ch:获取SDK版本号 | en:Get SDK Version
int CMvCamera::GetSDKVersion()
{
    return MV_CC_GetSDKVersion();
}

// ch:枚举设备 | en:Enumerate Device
int CMvCamera::EnumDevices(unsigned int nTLayerType, MV_CC_DEVICE_INFO_LIST* pstDevList)
{
    return MV_CC_EnumDevices(nTLayerType, pstDevList);
}

// ch:判断设备是否可达 | en:Is the device accessible
bool CMvCamera::IsDeviceAccessible(MV_CC_DEVICE_INFO* pstDevInfo, unsigned int nAccessMode)
{
    return MV_CC_IsDeviceAccessible(pstDevInfo, nAccessMode);
}

// ch:打开设备 | en:Open Device
int CMvCamera::Open(MV_CC_DEVICE_INFO* pstDeviceInfo)
{
    if (MV_NULL == pstDeviceInfo)
    {
        return MV_E_PARAMETER;
    }

    if (m_hDevHandle)
    {
        return MV_E_CALLORDER;
    }

    int nRet  = MV_CC_CreateHandle(&m_hDevHandle, pstDeviceInfo);
    if (MV_OK != nRet)
    {
        return nRet;
    }

    nRet = MV_CC_OpenDevice(m_hDevHandle);
    if (MV_OK != nRet)
    {
        MV_CC_DestroyHandle(m_hDevHandle);
        m_hDevHandle = MV_NULL;
    }

    return nRet;
}

// ch:关闭设备 | en:Close Device
int CMvCamera::Close()
{
    if (MV_NULL == m_hDevHandle)
    {
        return MV_E_HANDLE;
    }

    MV_CC_CloseDevice(m_hDevHandle);

    int nRet = MV_CC_DestroyHandle(m_hDevHandle);
    m_hDevHandle = MV_NULL;

    return nRet;
}

// ch:判断相机是否处于连接状态 | en:Is The Device Connected
bool CMvCamera::IsDeviceConnected()
{
    return MV_CC_IsDeviceConnected(m_hDevHandle);
}

// ch:注册图像数据回调 | en:Register Image Data CallBack
int CMvCamera::RegisterImageCallBack(void(__stdcall* cbOutput)(unsigned char * pData, MV_FRAME_OUT_INFO_EX* pFrameInfo, void* pUser), void* pUser)
{
    return MV_CC_RegisterImageCallBackEx(m_hDevHandle, cbOutput, pUser);
}

// ch:注册彩色图像数据回调
int CMvCamera::RegisterImageCallBackRGB(void(__stdcall* cbOutput)(unsigned char * pData, MV_FRAME_OUT_INFO_EX* pFrameInfo, void* pUser), void* pUser)
{
    return MV_CC_RegisterImageCallBackForRGB(m_hDevHandle, cbOutput, pUser);
}

// ch:开启抓图 | en:Start Grabbing
int CMvCamera::StartGrabbing()
{
    return MV_CC_StartGrabbing(m_hDevHandle);
}

// ch:停止抓图 | en:Stop Grabbing
int CMvCamera::StopGrabbing()
{
    return MV_CC_StopGrabbing(m_hDevHandle);
}

// ch:主动获取一帧图像数据 | en:Get one frame initiatively
int CMvCamera::GetImageBuffer(MV_FRAME_OUT* pFrame, int nMsec)
{
    return MV_CC_GetImageBuffer(m_hDevHandle, pFrame, nMsec);
}

// ch:释放图像缓存 | en:Free image buffer
int CMvCamera::FreeImageBuffer(MV_FRAME_OUT* pFrame)
{
    return MV_CC_FreeImageBuffer(m_hDevHandle, pFrame);
}

// ch:设置显示窗口句柄 | en:Set Display Window Handle
int CMvCamera::DisplayOneFrame(MV_DISPLAY_FRAME_INFO* pDisplayInfo)
{
    return MV_CC_DisplayOneFrame(m_hDevHandle, pDisplayInfo);
}

// ch:设置SDK内部图像缓存节点个数 | en:Set the number of the internal image cache nodes in SDK
int CMvCamera::SetImageNodeNum(unsigned int nNum)
{
    return MV_CC_SetImageNodeNum(m_hDevHandle, nNum);
}

// ch:获取设备信息 | en:Get device information
int CMvCamera::GetDeviceInfo(MV_CC_DEVICE_INFO* pstDevInfo)
{
    return MV_CC_GetDeviceInfo(m_hDevHandle, pstDevInfo);
}

// ch:获取GEV相机的统计信息 | en:Get detect info of GEV camera
int CMvCamera::GetGevAllMatchInfo(MV_MATCH_INFO_NET_DETECT* pMatchInfoNetDetect)
{
    if (MV_NULL == pMatchInfoNetDetect)
    {
        return MV_E_PARAMETER;
    }

    MV_CC_DEVICE_INFO stDevInfo = {0};
    GetDeviceInfo(&stDevInfo);
    if (stDevInfo.nTLayerType != MV_GIGE_DEVICE)
    {
        return MV_E_SUPPORT;
    }

    MV_ALL_MATCH_INFO struMatchInfo = {0};

    struMatchInfo.nType = MV_MATCH_TYPE_NET_DETECT;
    struMatchInfo.pInfo = pMatchInfoNetDetect;
    struMatchInfo.nInfoSize = sizeof(MV_MATCH_INFO_NET_DETECT);
    memset(struMatchInfo.pInfo, 0, sizeof(MV_MATCH_INFO_NET_DETECT));

    return MV_CC_GetAllMatchInfo(m_hDevHandle, &struMatchInfo);
}

// ch:获取U3V相机的统计信息 | en:Get detect info of U3V camera
int CMvCamera::GetU3VAllMatchInfo(MV_MATCH_INFO_USB_DETECT* pMatchInfoUSBDetect)
{
    if (MV_NULL == pMatchInfoUSBDetect)
    {
        return MV_E_PARAMETER;
    }

    MV_CC_DEVICE_INFO stDevInfo = {0};
    GetDeviceInfo(&stDevInfo);
    if (stDevInfo.nTLayerType != MV_USB_DEVICE)
    {
        return MV_E_SUPPORT;
    }

    MV_ALL_MATCH_INFO struMatchInfo = {0};

    struMatchInfo.nType = MV_MATCH_TYPE_USB_DETECT;
    struMatchInfo.pInfo = pMatchInfoUSBDetect;
    struMatchInfo.nInfoSize = sizeof(MV_MATCH_INFO_USB_DETECT);
    memset(struMatchInfo.pInfo, 0, sizeof(MV_MATCH_INFO_USB_DETECT));

    return MV_CC_GetAllMatchInfo(m_hDevHandle, &struMatchInfo);
}

// ch:获取和设置Int型参数,如 Width和Height,详细内容参考SDK安装目录下的 MvCameraNode.xlsx 文件
// en:Get Int type parameters, such as Width and Height, for details please refer to MvCameraNode.xlsx file under SDK installation directory
int CMvCamera::GetIntValue(IN const char* strKey, OUT MVCC_INTVALUE_EX *pIntValue)
{
    return MV_CC_GetIntValueEx(m_hDevHandle, strKey, pIntValue);
}

int CMvCamera::SetIntValue(IN const char* strKey, IN int64_t nValue)
{
    return MV_CC_SetIntValueEx(m_hDevHandle, strKey, nValue);
}

// ch:获取和设置Enum型参数,如 PixelFormat,详细内容参考SDK安装目录下的 MvCameraNode.xlsx 文件
// en:Get Enum type parameters, such as PixelFormat, for details please refer to MvCameraNode.xlsx file under SDK installation directory
int CMvCamera::GetEnumValue(IN const char* strKey, OUT MVCC_ENUMVALUE *pEnumValue)
{
    return MV_CC_GetEnumValue(m_hDevHandle, strKey, pEnumValue);
}

int CMvCamera::SetEnumValue(IN const char* strKey, IN unsigned int nValue)
{
    return MV_CC_SetEnumValue(m_hDevHandle, strKey, nValue);
}

int CMvCamera::SetEnumValueByString(IN const char* strKey, IN const char* sValue)
{
    return MV_CC_SetEnumValueByString(m_hDevHandle, strKey, sValue);
}

int CMvCamera::GetEnumEntrySymbolic(IN const char* strKey, IN MVCC_ENUMENTRY* pstEnumEntry)
{
    return MV_CC_GetEnumEntrySymbolic(m_hDevHandle, strKey, pstEnumEntry);
}

// ch:获取和设置Float型参数,如 ExposureTime和Gain,详细内容参考SDK安装目录下的 MvCameraNode.xlsx 文件
// en:Get Float type parameters, such as ExposureTime and Gain, for details please refer to MvCameraNode.xlsx file under SDK installation directory
int CMvCamera::GetFloatValue(IN const char* strKey, OUT MVCC_FLOATVALUE *pFloatValue)
{
    return MV_CC_GetFloatValue(m_hDevHandle, strKey, pFloatValue);
}

int CMvCamera::SetFloatValue(IN const char* strKey, IN float fValue)
{
    return MV_CC_SetFloatValue(m_hDevHandle, strKey, fValue);
}

// ch:获取和设置Bool型参数,如 ReverseX,详细内容参考SDK安装目录下的 MvCameraNode.xlsx 文件
// en:Get Bool type parameters, such as ReverseX, for details please refer to MvCameraNode.xlsx file under SDK installation directory
int CMvCamera::GetBoolValue(IN const char* strKey, OUT bool *pbValue)
{
    return MV_CC_GetBoolValue(m_hDevHandle, strKey, pbValue);
}

int CMvCamera::SetBoolValue(IN const char* strKey, IN bool bValue)
{
    return MV_CC_SetBoolValue(m_hDevHandle, strKey, bValue);
}

// ch:获取和设置String型参数,如 DeviceUserID,详细内容参考SDK安装目录下的 MvCameraNode.xlsx 文件UserSetSave
// en:Get String type parameters, such as DeviceUserID, for details please refer to MvCameraNode.xlsx file under SDK installation directory
int CMvCamera::GetStringValue(IN const char* strKey, MVCC_STRINGVALUE *pStringValue)
{
    return MV_CC_GetStringValue(m_hDevHandle, strKey, pStringValue);
}

int CMvCamera::SetStringValue(IN const char* strKey, IN const char* strValue)
{
    return MV_CC_SetStringValue(m_hDevHandle, strKey, strValue);
}

// ch:执行一次Command型命令,如 UserSetSave,详细内容参考SDK安装目录下的 MvCameraNode.xlsx 文件
// en:Execute Command once, such as UserSetSave, for details please refer to MvCameraNode.xlsx file under SDK installation directory
int CMvCamera::CommandExecute(IN const char* strKey)
{
    return MV_CC_SetCommandValue(m_hDevHandle, strKey);
}

// ch:探测网络最佳包大小(只对GigE相机有效) | en:Detection network optimal package size(It only works for the GigE camera)
int CMvCamera::GetOptimalPacketSize(unsigned int* pOptimalPacketSize)
{
    if (MV_NULL == pOptimalPacketSize)
    {
        return MV_E_PARAMETER;
    }

    int nRet = MV_CC_GetOptimalPacketSize(m_hDevHandle);
    if (nRet < MV_OK)
    {
        return nRet;
    }

    *pOptimalPacketSize = (unsigned int)nRet;

    return MV_OK;
}

// ch:注册消息异常回调 | en:Register Message Exception CallBack
int CMvCamera::RegisterExceptionCallBack(void(__stdcall* cbException)(unsigned int nMsgType, void* pUser),void* pUser)
{
    return MV_CC_RegisterExceptionCallBack(m_hDevHandle, cbException, pUser);
}

// ch:注册单个事件回调 | en:Register Event CallBack
int CMvCamera::RegisterEventCallBack(const char* pEventName, void(__stdcall* cbEvent)(MV_EVENT_OUT_INFO * pEventInfo, void* pUser), void* pUser)
{
    return MV_CC_RegisterEventCallBackEx(m_hDevHandle, pEventName, cbEvent, pUser);
}

// ch:强制IP | en:Force IP
int CMvCamera::ForceIp(unsigned int nIP, unsigned int nSubNetMask, unsigned int nDefaultGateWay)
{
    return MV_GIGE_ForceIpEx(m_hDevHandle, nIP, nSubNetMask, nDefaultGateWay);
}

// ch:配置IP方式 | en:IP configuration method
int CMvCamera::SetIpConfig(unsigned int nType)
{
    return MV_GIGE_SetIpConfig(m_hDevHandle, nType);
}

// ch:设置网络传输模式 | en:Set Net Transfer Mode
int CMvCamera::SetNetTransMode(unsigned int nType)
{
    return MV_GIGE_SetNetTransMode(m_hDevHandle, nType);
}

// ch:像素格式转换 | en:Pixel format conversion
int CMvCamera::ConvertPixelType(MV_CC_PIXEL_CONVERT_PARAM* pstCvtParam)
{
    return MV_CC_ConvertPixelType(m_hDevHandle, pstCvtParam);
}

// ch:保存图片 | en:save image
int CMvCamera::SaveImage(MV_SAVE_IMAGE_PARAM_EX* pstParam)
{
    return MV_CC_SaveImageEx2(m_hDevHandle, pstParam);
}

// ch:保存图片为文件 | en:Save the image as a file
int CMvCamera::SaveImageToFile(MV_SAVE_IMG_TO_FILE_PARAM* pstSaveFileParam)
{
    return MV_CC_SaveImageToFile(m_hDevHandle, pstSaveFileParam);
}

// ch:绘制圆形辅助线 | en:Draw circle auxiliary line
int CMvCamera::DrawCircle(MVCC_CIRCLE_INFO* pCircleInfo)
{
    return MV_CC_DrawCircle(m_hDevHandle, pCircleInfo);
}

// ch:绘制线形辅助线 | en:Draw lines auxiliary line
int CMvCamera::DrawLines(MVCC_LINES_INFO* pLinesInfo)
{
    return MV_CC_DrawLines(m_hDevHandle, pLinesInfo);
}

//读取相机中的图像
int CMvCamera::ReadBuffer(cv::Mat &image)
{
    unsigned int nRecvBufSize = 0;
    MVCC_INTVALUE_EX stParam;
    memset(&stParam,0,sizeof(MVCC_INTVALUE_EX));
    int nRet = GetIntValue("PayloadSize",&stParam);
    if(MV_OK != nRet)
    {
        return nRet;
    }
    nRecvBufSize = stParam.nCurValue;
    unsigned char* pDate;
    pDate = (unsigned char *)malloc(nRecvBufSize);
    MV_FRAME_OUT_INFO_EX stImageInfo;
    memset(&stImageInfo,0,sizeof(MV_FRAME_OUT_INFO));
    nRet = MV_CC_GetOneFrameTimeout(m_hDevHandle,pDate,nRecvBufSize,&stImageInfo,500);
    if(MV_OK != nRet)
    {
        return nRet;
    }

    //用于保存图像的缓存
    unsigned int nBufSizeForSaveImage = stImageInfo.nWidth * stImageInfo.nHeight * 3 + 2048;
    unsigned char* pBufForSaveImage = (unsigned char*)malloc(nBufSizeForSaveImage);

    //判断是否为黑白图像
    bool isMono;
    cv::Mat getImage;
    switch(stImageInfo.enPixelType)
    {
    case PixelType_Gvsp_Mono8:
    case PixelType_Gvsp_Mono10:
    case PixelType_Gvsp_Mono10_Packed:
    case PixelType_Gvsp_Mono12:
    case PixelType_Gvsp_Mono12_Packed:
        isMono=true;
        break;
    default:
        isMono=false;
        break;
    }
    if(isMono)
    {
        getImage = cv::Mat(stImageInfo.nHeight,stImageInfo.nWidth,CV_8UC1,pDate);   //单色
    }
    else
    {
        //转换图像格式为RGB8
        MV_CC_PIXEL_CONVERT_PARAM stConvertParam;
        memset(&stConvertParam,0,sizeof(MV_CC_PIXEL_CONVERT_PARAM));
        stConvertParam.nWidth = stImageInfo.nWidth;
        stConvertParam.nHeight = stImageInfo.nHeight;
        stConvertParam.pSrcData = pDate;                                //输入数据缓存
        stConvertParam.nSrcDataLen = stImageInfo.nFrameLen;
        stConvertParam.enSrcPixelType = stImageInfo.enPixelType;
        //stConvertParam.enDstPixelType = PixelType_Gvsp_BGR8_Packed;   //输出像素格式
        stConvertParam.enDstPixelType = PixelType_Gvsp_RGB8_Packed;
        stConvertParam.pDstBuffer = pBufForSaveImage;                   //输出数据缓存
        stConvertParam.nDstBufferSize = nBufSizeForSaveImage;           //输出缓存大小
        MV_CC_ConvertPixelType(m_hDevHandle, &stConvertParam);
        getImage = cv::Mat(stImageInfo.nHeight,stImageInfo.nWidth,CV_8UC3,pBufForSaveImage);
    }
    getImage.copyTo(image);
    getImage.release();
    free(pDate);
    free(pBufForSaveImage);
    return MV_OK;
}

//读取保存相机中的图像
int CMvCamera::SaveBuffer(QByteArray imageName)
{
    unsigned int nRecvBufSize = 0;
    MVCC_INTVALUE_EX stParam;
    memset(&stParam,0,sizeof(MVCC_INTVALUE_EX));
    int nRet = GetIntValue("PayloadSize",&stParam);   //获取Integer属性值
    if(MV_OK != nRet)
    {
        return nRet;
    }
    nRecvBufSize = stParam.nCurValue;
    unsigned char* pDate;
    pDate = (unsigned char *)malloc(nRecvBufSize);
    MV_FRAME_OUT_INFO_EX stImageInfo;
    memset(&stImageInfo,0,sizeof(MV_FRAME_OUT_INFO));
    nRet = MV_CC_GetOneFrameTimeout(m_hDevHandle,pDate,nRecvBufSize,&stImageInfo,500);   //采用超时机制获取一帧图片
    if(MV_OK != nRet)
    {
        return nRet;
    }
    MV_SAVE_IMG_TO_FILE_PARAM stSaveFileParam;
    memset(&stSaveFileParam,0,sizeof(MV_SAVE_IMG_TO_FILE_PARAM));
    stSaveFileParam.enImageType = MV_Image_Bmp;
    stSaveFileParam.enPixelType = stImageInfo.enPixelType;
    stSaveFileParam.nWidth      = stImageInfo.nWidth;
    stSaveFileParam.nHeight     = stImageInfo.nHeight;
    stSaveFileParam.nDataLen    = stImageInfo.nFrameLen;
    stSaveFileParam.pData       = pDate;
    stSaveFileParam.iMethodValue = 0;
    sprintf_s(stSaveFileParam.pImagePath,256,imageName.data());   //文件名
    nRet = SaveImageToFile(&stSaveFileParam);   //保存图片为文件
    if(MV_OK != nRet)
    {
        return nRet;
    }
    free(pDate);
    return MV_OK;
}
  • 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

3.capturethread.h

#ifndef CAPTURETHREAD_H
#define CAPTURETHREAD_H

#include <QObject>
#include <QThread>
#include <QImage>
#include <QDir>
#include <QTimer>
#include <QDate>
#include <QDateTime>
#include <QDebug>
#include "cmvcamera.h"

#define LOGDEBUG qDebug()<<QTime::currentTime().toString("[hh:mm:ss:zzz]")

class CaptureThread : public QThread
{
    Q_OBJECT

public:
     explicit CaptureThread(QObject *parent = nullptr);
     ~CaptureThread();

    void initThread();
    void setCameraPtr(CMvCamera *camera);
    void setCameraSignal(int time,int num);
    void setSavePath(QString originPath);
    void setSaveFlag(bool saveFlag);
    void setSwitchFlag(bool switchFlag);
    void setSoftModeFlag(bool softModeFlag);
    void setImageBuffer(cv::Mat imageMat);

    void run();

    QImage cvMatToImage(const cv::Mat imageMat);
    void saveOriginImage(cv::Mat imageMat);

signals:
    void signal_newImage(QImage newImage);

private:
    static void __stdcall ImageCallback(unsigned char * pData,MV_FRAME_OUT_INFO_EX* pFrameInfo,void* pUser);

private:
    CMvCamera *m_cameraPtr = NULL;
    int m_imageTime;   //抓拍间隔时间
    int m_imageNum;    //抓拍间隔次数
    QString m_originPath;   //原图保存路径

    bool m_saveFlag;        //保存图像标志
    bool m_switchFlag;      //线程开启标志
    bool m_softModeFlag;    //软触发模式标志

};
#endif // CAPTURETHREAD_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

4.capturethread.cpp

#include "capturethread.h"

CaptureThread::CaptureThread(QObject *parent)
    : QThread{parent}
{
    this->initThread();
}

CaptureThread::~CaptureThread()
{

}

//初始化图像捕获线程
void CaptureThread::initThread()
{
    m_imageTime = 1000;
    m_imageNum = 1;
    m_originPath = "";
    m_saveFlag = false;
    m_switchFlag = false;
    m_softModeFlag = false;
}

//设置相机指针
void CaptureThread::setCameraPtr(CMvCamera *camera)
{
    m_cameraPtr = camera;

    //注册回调函数
    int nRet = m_cameraPtr->RegisterImageCallBackRGB(ImageCallback,this);    //彩色相机
    if(MV_OK != nRet)
    {
        LOGDEBUG<<"相机注册回调函数失败";
    }
    else
    {
        LOGDEBUG<<"相机注册回调函数成功";
    }
}

//设置相机拍照间隔时间和次数
void CaptureThread::setCameraSignal(int time,int num)
{
    m_imageTime = time*1000;
    m_imageNum = num;
    if(m_imageTime <= 0)
    {
        m_imageTime = 1000;
    }
    if(m_imageNum <= 0)
    {
        m_imageNum = 1;
    }
}

//设置图像保存路径
void CaptureThread::setSavePath(QString originPath)
{
    m_originPath = originPath;
    LOGDEBUG<<"相机原图保存路径:"<<m_originPath;
}

//设置是否保存图像
void CaptureThread::setSaveFlag(bool saveFlag)
{
    m_saveFlag = saveFlag;
}

//设置线程开关
void CaptureThread::setSwitchFlag(bool switchFlag)
{
    m_switchFlag = switchFlag;
}

//设置软触发
void CaptureThread::setSoftModeFlag(bool softModeFlag)
{
    m_softModeFlag = softModeFlag;
}

//获取回调返回的图像
void CaptureThread::setImageBuffer(cv::Mat imageMat)
{
    LOGDEBUG<<"获取回调图像";
    if(m_saveFlag)
    {
        m_saveFlag = false;
        saveOriginImage(imageMat);
    }
    emit signal_newImage(cvMatToImage(imageMat));
}

//线程运行
void CaptureThread::run()
{
    static int startNum = 0;
    while(m_switchFlag)
    {
        if(startNum < m_imageNum)
        {
            startNum++;
            if(m_softModeFlag)
            {
                m_cameraPtr->CommandExecute("TriggerSoftware");
            }
            m_saveFlag = true;
        }
        else
        {
            startNum = 0;
            m_switchFlag = false;
        }
        msleep(m_imageTime);
    }
}

//cv::Mat转QImage
QImage CaptureThread::cvMatToImage(const cv::Mat imageMat)
{
    //颜色转换,opencv默认的彩色图像的颜色空间是BGR
    //cvtColor(imageMat,imageMat,cv::COLOR_BGR2RGB);

    QImage myImage;
    if(imageMat.channels() > 1)
    {
        myImage = QImage((const unsigned char*)(imageMat.data),imageMat.cols,imageMat.rows,QImage::Format_RGB888);   //彩色图
    }
    else
    {
        myImage = QImage((const unsigned char*)(imageMat.data),imageMat.cols,imageMat.rows,QImage::Format_Indexed8);   //灰度图
    }
    return myImage;
}

//保存原图
void CaptureThread::saveOriginImage(cv::Mat imageMat)
{
    clock_t originClock = -clock();
    QString curTime = QTime::currentTime().toString("hhmmss");
    QString iamgeName = m_originPath + "GrabImage_" + curTime + ".jpg";
    cv::Mat saveMat;
    cvtColor(imageMat,saveMat,cv::COLOR_BGR2RGB);   //颜色格式转换
    imwrite(iamgeName.toStdString(),saveMat);
    originClock += clock();
    LOGDEBUG<<"保存原图耗时:"<<originClock<<"ms";   //测试在20ms左右
}

//回调函数
void __stdcall CaptureThread::ImageCallback(unsigned char * pData,MV_FRAME_OUT_INFO_EX* pFrameInfo,void* pUser)
{
    //LOGDEBUG<<"回调触发";
    CaptureThread* pThread = static_cast<CaptureThread *>(pUser);

    //创建cv::Mat对象
    cv::Mat showMat(pFrameInfo->nHeight,pFrameInfo->nWidth,CV_8UC3,pData);   //彩色

    //将图像保存到容器中
    pThread->setImageBuffer(showMat);
}
  • 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

5.widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QMessageBox>
#include "capturethread.h"

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

    void initWidget();

private slots:
    void slot_displayImage(QImage myImage);
    void on_pb_find_clicked();
    void on_pb_open_clicked();
    void on_pb_close_clicked();
    void on_pb_set_clicked();
    void on_pb_start_clicked();
    void on_pb_stop_clicked();
    void on_pb_grab_clicked();

private:
    Ui::Widget *ui;

    bool m_bOpenDevice;
    QSize m_showSize;

    CaptureThread *m_captureThread;

    MV_CC_DEVICE_INFO_LIST m_stDevList;
    CMvCamera *m_pcMyCamera = NULL;
    MV_SAVE_IAMGE_TYPE m_nSaveImageType = MV_Image_Bmp;

};
#endif // WIDGET_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

6.widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    initWidget();
}

Widget::~Widget()
{
    delete ui;
    if(m_pcMyCamera)
    {
        m_pcMyCamera->Close();
        delete m_pcMyCamera;
        m_pcMyCamera = NULL;
    }
}

//初始化
void Widget::initWidget()
{
    //设置窗口属性
    this->setWindowTitle("抓图测试");
    ui->pb_close->setEnabled(false);
    ui->pb_stop->setEnabled(false);

    //初始化变量
    m_bOpenDevice = false;
    m_showSize = QSize(768,512);

    //生成保存图片的文件夹
    QString imagePath = QCoreApplication::applicationDirPath() + "/SaveImage/";
    QDir dstDir(imagePath);
    if(!dstDir.exists())
    {
        if(!dstDir.mkdir(imagePath))
        {
            LOGDEBUG<<"创建图像保存文件夹失败!";
        }
        else
        {
            LOGDEBUG<<"创建图像保存文件夹成功!";
        }
    }

    //初始化线程
    m_captureThread = new CaptureThread();
    connect(m_captureThread,SIGNAL(signal_newImage(QImage)),this,SLOT(slot_displayImage(QImage)),Qt::BlockingQueuedConnection);
    m_captureThread->setSavePath(imagePath);

}

//显示图像
void Widget::slot_displayImage(QImage myImage)
{
    QPixmap newPixmap = QPixmap::fromImage(myImage).scaled(m_showSize,Qt::KeepAspectRatio,Qt::SmoothTransformation);
    ui->lb_show->setPixmap(newPixmap);
}

//查找设备
void Widget::on_pb_find_clicked()
{
    ui->cb_devices->clear();
    memset(&m_stDevList, 0, sizeof(MV_CC_DEVICE_INFO_LIST));

    //枚举子网内所有设备
    int nRet = CMvCamera::EnumDevices(MV_GIGE_DEVICE | MV_USB_DEVICE,&m_stDevList);
    if(MV_OK != nRet)
    {
        LOGDEBUG<<"设备枚举失败";
        return;
    }
    for(unsigned int i = 0; i < m_stDevList.nDeviceNum; i++)
    {
        MV_CC_DEVICE_INFO* pDeviceInfo = m_stDevList.pDeviceInfo[i];
        QString strModelName = "";
        if(pDeviceInfo->nTLayerType == MV_USB_DEVICE)
        {
            strModelName = (char*)pDeviceInfo->SpecialInfo.stUsb3VInfo.chModelName;
        }
        else if(pDeviceInfo->nTLayerType == MV_GIGE_DEVICE)
        {
            strModelName = (char*)pDeviceInfo->SpecialInfo.stGigEInfo.chModelName;
        }
        else
        {
            QMessageBox::warning(this,"警告","未知设备枚举!");
            return;
        }
        LOGDEBUG<<"相机型号:"<<strModelName;
        ui->cb_devices->addItem(strModelName);
    }
}

//打开设备
void Widget::on_pb_open_clicked()
{
    if(m_bOpenDevice)
    {
        return;
    }
    QString deviceModel = ui->cb_devices->currentText();
    if(deviceModel == "")
    {
        QMessageBox::warning(this,"警告","请先查找并选择设备!");
        return;
    }

    //相机对象
    m_pcMyCamera = new CMvCamera;

    //打开设备
    int nIndex = ui->cb_devices->currentIndex();
    int nRet = m_pcMyCamera->Open(m_stDevList.pDeviceInfo[nIndex]);
    if(MV_OK != nRet)
    {
        delete m_pcMyCamera;
        m_pcMyCamera = NULL;
        QMessageBox::warning(this,"警告","打开设备失败!");
        return;
    }
    else
    {
        LOGDEBUG<<"打开设备成功!";
    }

    //设置为触发模式,触发源为软触发
    m_pcMyCamera->SetEnumValue("TriggerMode",1);
    m_pcMyCamera->SetEnumValue("TriggerSource",7);

    //设置曝光时间和增益
    int exposureTime = ui->le_exposureTime->text().toInt();
    int gain = ui->le_gain->text().toInt();
    m_pcMyCamera->SetFloatValue("ExposureTime",exposureTime);
    m_pcMyCamera->SetEnumValue("GainAuto",0);
    m_pcMyCamera->SetFloatValue("Gain",gain);

    //相机线程设置,注册回调
    m_captureThread->setCameraPtr(m_pcMyCamera);

    //开启相机采集
    m_pcMyCamera->StartGrabbing();

    //开启标志位
    m_bOpenDevice = true;

    //使能按键
    ui->pb_find->setEnabled(false);
    ui->pb_open->setEnabled(false);
    ui->pb_close->setEnabled(true);
}

//关闭设备
void Widget::on_pb_close_clicked()
{
    if(m_bOpenDevice)
    {
        m_bOpenDevice = false;
        if(m_pcMyCamera)
        {
            m_pcMyCamera->Close();
            delete m_pcMyCamera;
            m_pcMyCamera = NULL;
        }
    }

    //使能按键
    ui->pb_find->setEnabled(true);
    ui->pb_open->setEnabled(true);
    ui->pb_close->setEnabled(false);
}

//设置
void Widget::on_pb_set_clicked()
{
    if(!m_bOpenDevice)
    {
        QMessageBox::warning(this,"警告","设置失败,请打开设备!");
        return;
    }

    int exposureTime = ui->le_exposureTime->text().toInt();
    int gain = ui->le_gain->text().toInt();
    //设置曝光时间
    m_pcMyCamera->SetFloatValue("ExposureTime",exposureTime);

    //设置增益前先把自动增益关闭,失败无需返回
    m_pcMyCamera->SetEnumValue("GainAuto",0);
    m_pcMyCamera->SetFloatValue("Gain",gain);

    //设置显示宽度和高度
    int showW = ui->le_w->text().toInt();
    int showH = ui->le_h->text().toInt();
    if(showW < 768)
    {
        showW = 768;
        ui->le_w->setText("768");
    }
    if(showH < 512)
    {
        showH = 512;
        ui->le_h->setText("512");
    }
    m_showSize = QSize(showW,showH);

}

//开始采集
//点击开始采集后,会关闭触发模式,相机就会不断回调,实时显示相机图像
void Widget::on_pb_start_clicked()
{
    if(!m_bOpenDevice)
    {
        QMessageBox::warning(this,"警告","采集失败,请打开设备!");
        return;
    }

    //不保存图像
    m_captureThread->setSaveFlag(false);

    //关闭触发模式
    m_captureThread->setSoftModeFlag(false);
    m_pcMyCamera->SetEnumValue("TriggerMode",0);

    //使能按键
    ui->pb_find->setEnabled(false);
    ui->pb_open->setEnabled(false);
    ui->pb_close->setEnabled(false);
    ui->pb_start->setEnabled(false);
    ui->pb_stop->setEnabled(true);
}

//停止采集
//点击停止采集后,会开启触发模式并设置为软触发,需要调用命令触发回调
void Widget::on_pb_stop_clicked()
{
    if(!m_bOpenDevice)
    {
        QMessageBox::warning(this,"警告","采集失败,请打开设备!");
        return;
    }

    //设置为触发模式,触发源为软触发
    m_captureThread->setSoftModeFlag(true);
    m_pcMyCamera->SetEnumValue("TriggerMode",1);
    m_pcMyCamera->SetEnumValue("TriggerSource",7);

    //使能按键
    ui->pb_find->setEnabled(false);
    ui->pb_open->setEnabled(false);
    ui->pb_close->setEnabled(true);
    ui->pb_start->setEnabled(true);
    ui->pb_stop->setEnabled(false);
    ui->pb_grab->setEnabled(true);
}

//抓拍图像
void Widget::on_pb_grab_clicked()
{
    if(!m_bOpenDevice)
    {
        QMessageBox::warning(this,"警告","抓拍失败,请打开设备!");
        return;
    }

    int time = ui->le_time->text().toInt();
    int num = ui->le_num->text().toInt();
    m_captureThread->setCameraSignal(time,num);
    m_captureThread->setSwitchFlag(true);
    m_captureThread->setSaveFlag(true);
    m_captureThread->start();
}
  • 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

7.widget.ui
请添加图片描述

总结

这个示例相较于前文,也是增加了下设置相机曝光时间和增益这两个参数的功能,可以看到也是比较简单的,主要是要了解相机SDK相关的接口,并且海康相机的相关文档和示例也是很详细的,类似这样的开发,我们首先要做的就是从文档中找答案~


hello:
共同学习,共同进步,如果还有相关问题,可在评论区留言进行讨论。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/885122
推荐阅读
相关标签
  

闽ICP备14008679号