(1) Qt+OpenCV llamando al desarrollo de muestra SDK de cámara industrial Haikang

Directorio de artículos de la serie

提示:这里是该系列文章的所有文章的目录
Capítulo 1: (1) Qt+OpenCV llama al desarrollo de muestra del SDK de la cámara industrial Haikang
Capítulo 2: (2) Qt multi-threading realiza la adquisición de imágenes en tiempo real de las cámaras industriales Haikang
Capítulo 3: (3) Qt multi-threading realiza la cámara industrial Hikvision adquisición de imágenes + detección de algoritmos + visualización en tiempo real de OpenGLWidget



prefacio

En el desarrollo reciente de las cámaras industriales de Hikvision en el entorno Qt, descubrí que los ejemplos proporcionados por Hikvision no tienen demostraciones de Qt, pero hay ejemplos basados ​​en el marco MFC. Por lo tanto, en base a este ejemplo, el desarrollo SDK de Qt llamando Las cámaras industriales HIK se llevan a cabo aquí. , y muestran el código relevante para que todos aprendan. Si hay algún error, todos pueden criticar y corregir.

Efecto del proyecto
Por favor agregue una descripción de la imagen


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

1. Configuración del entorno

El entorno utilizado en mi proyecto de ejemplo es QT5.14+OpenCV_4.5.1. En cuanto a cómo configurar el entorno OpenCv, puede consultar este artículo que escribí antes para obtener más detalles: Qt5.14_MinGW_64bit +CMake_3.24+OpenCV_4.5.1 entorno de construcción debajo de la ventana

2. Preparación del proyecto

Aquí ya lo clasifiqué y puse las carpetas OpenCV y SDK en el mismo directorio que el programa, que contiene algunos archivos de encabezado requeridos, archivos de biblioteca, etc. El código agregado en el siguiente archivo de perfil depende de la situación específica:
Por favor agregue una descripción de la imagen

Luego agregue el siguiente código al archivo MyCamera.pro:

#OpenCV
INCLUDEPATH += $$PWD/OpenCV/Includes
LIBS += -L $$PWD/OpenCV/Lib/libopencv_*.a

#SDK
INCLUDEPATH += $$PWD/SDK/Includes
DEPENDPATH += $$PWD/SDK/Includes
LIBS += -L $$PWD/SDK/Lib/MvCameraControl.lib

3. Ejemplo de visualización de código completo/enlace de descarga

1.cmvcamera.h (copiar directamente del SDK proporcionado por Haikang)

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

#ifndef _MV_CAMERA_H_
#define _MV_CAMERA_H_

#include "MvCameraControl.h"
#include <string.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:开启抓图 | 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);

    //读取buffer
    int ReadBuffer(Mat &image);

private:

    void *m_hDevHandle;

    //用于保存图像的缓存
    unsigned int m_nBufSizeForSaveImage;
    
};
#endif//_MV_CAMERA_H_

2.cmvcámara.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:开启抓图 | 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(Mat &image)
{
    
    
    Mat* getImage = new Mat();
    unsigned int nRecvBufSize = 0;
    MVCC_INTVALUE stParam;
    memset(&stParam, 0, sizeof(MVCC_INTVALUE));
    int tempValue = MV_CC_GetIntValue(m_hDevHandle, "PayloadSize", &stParam);
    if (tempValue != 0)
    {
    
    
        return -1;
    }
    nRecvBufSize = stParam.nCurValue;
    unsigned char* pDate;
    pDate=(unsigned char *)malloc(nRecvBufSize);

    MV_FRAME_OUT_INFO_EX stImageInfo = {
    
    0};
    tempValue= MV_CC_GetOneFrameTimeout(m_hDevHandle, pDate, nRecvBufSize, &stImageInfo, 700);
    if(tempValue!=0)
    {
    
    
        return -1;
    }
    m_nBufSizeForSaveImage = stImageInfo.nWidth * stImageInfo.nHeight * 3 + 2048;
    unsigned char* m_pBufForSaveImage;
    m_pBufForSaveImage = (unsigned char*)malloc(m_nBufSizeForSaveImage);


    bool isMono;
    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 = Mat(stImageInfo.nHeight,stImageInfo.nWidth,CV_8UC1,pDate);
        //imwrite("d:\\测试opencv_Mono.tif", image);
    }
    else
    {
    
    
        //转换图像格式为BGR8
        MV_CC_PIXEL_CONVERT_PARAM stConvertParam = {
    
    0};
        memset(&stConvertParam, 0, sizeof(MV_CC_PIXEL_CONVERT_PARAM));
        stConvertParam.nWidth = stImageInfo.nWidth;                 //ch:图像宽 | en:image width
        stConvertParam.nHeight = stImageInfo.nHeight;               //ch:图像高 | en:image height
        //stConvertParam.pSrcData = m_pBufForDriver;                  //ch:输入数据缓存 | en:input data buffer
        stConvertParam.pSrcData = pDate;                  //ch:输入数据缓存 | en:input data buffer
        stConvertParam.nSrcDataLen = stImageInfo.nFrameLen;         //ch:输入数据大小 | en:input data size
        stConvertParam.enSrcPixelType = stImageInfo.enPixelType;    //ch:输入像素格式 | en:input pixel format
        stConvertParam.enDstPixelType = PixelType_Gvsp_BGR8_Packed; //ch:输出像素格式 | en:output pixel format  适用于OPENCV的图像格式
        //stConvertParam.enDstPixelType = PixelType_Gvsp_RGB8_Packed; //ch:输出像素格式 | en:output pixel format
        stConvertParam.pDstBuffer = m_pBufForSaveImage;                    //ch:输出数据缓存 | en:output data buffer
        stConvertParam.nDstBufferSize = m_nBufSizeForSaveImage;            //ch:输出缓存大小 | en:output buffer size
        MV_CC_ConvertPixelType(m_hDevHandle, &stConvertParam);

        *getImage = Mat(stImageInfo.nHeight,stImageInfo.nWidth,CV_8UC3,m_pBufForSaveImage);
        //imwrite("d:\\测试opencv_Color.tif", image);
    }
    (*getImage).copyTo(image);
    (*getImage).release();
    free(pDate);
    free(m_pBufForSaveImage);
    return 0;
}

3.mihilo.h

#ifndef MYTHREAD_H
#define MYTHREAD_H

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

class MyThread : public QThread
{
    
    
    Q_OBJECT

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

    void run();
    void getCameraPtr(CMvCamera *camera);
    void getImagePtr(cv::Mat *image);

signals:
    void signal_message();
    void signal_messImage(QImage myImage);

private:
    CMvCamera *cameraPtr = NULL;
    cv::Mat *imagePtr = NULL;
    QImage *myImage = NULL;

};
#endif // MYTHREAD_H

4.mihilo.cpp

#include "mythread.h"

MyThread::MyThread(QObject *parent)
    : QThread{
    
    parent}
{
    
    
    myImage = new QImage();
}

MyThread::~MyThread()
{
    
    
    delete myImage;
    if(cameraPtr == NULL)
    {
    
    
        delete cameraPtr;
    }
    if(imagePtr == NULL)
    {
    
    
        delete imagePtr;
    }
}

void MyThread::getCameraPtr(CMvCamera *camera)
{
    
    
    cameraPtr = camera;
}

void MyThread::getImagePtr(cv::Mat *image)
{
    
    
    imagePtr = image;
}

void MyThread::run()
{
    
    
    if(cameraPtr == NULL)
    {
    
    
        return;
    }
    if(imagePtr == NULL)
    {
    
    
        return;
    }

    while(!isInterruptionRequested())
    {
    
    
        qDebug()<<"SoftTrigger:"<<cameraPtr->CommandExecute("TriggerSoftware");
        qDebug()<<"ReadBuffer:"<<cameraPtr->ReadBuffer(*imagePtr);

        //先发送好再处理
        //emit signal_message();
        //msleep(10);

        //先处理好再发送
        if(imagePtr->channels()>1)
        {
    
    
            *myImage = QImage((const unsigned char*)(imagePtr->data),imagePtr->cols,imagePtr->rows,QImage::Format_RGB888);
        }
        else
        {
    
    
            *myImage = QImage((const unsigned char*)(imagePtr->data),imagePtr->cols,imagePtr->rows,QImage::Format_Indexed8);
        }
        emit signal_messImage(*myImage);
        msleep(10);

        //耗时操作,需要放到线程中保存
        //QImage保存图像
        //QString savePath = QDir::currentPath() + "/myImage/";
        //QString curDate = QDateTime::currentDateTime().toString("yyyyMMdd-hhmmss.zzz");
        //QString saveName = savePath + curDate + ".png";
        //qDebug()<<"saveName:"<<saveName;
        //myImage->save(saveName);
    }
}

5.widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QMessageBox>
#include "cmvcamera.h"
#include "mythread.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();
    void saveImage(QString format);
    void display(const Mat* image);

private slots:
    void slot_display();
    void slot_displayImage(QImage myImage);
    void on_pb_find_clicked();
    void on_pb_open_clicked();
    void on_pb_close_clicked();
    void on_pb_single_clicked();
    void on_pb_start_clicked();
    void on_pb_stop_clicked();
    void on_pb_saveBmp_clicked();
    void on_pb_savePng_clicked();

private:
    Ui::Widget *ui;

    bool m_bOpenDevice;

    MV_CC_DEVICE_INFO_LIST m_stDevList;
    CMvCamera *m_pcMyCamera = NULL;
    MyThread *myThread = NULL;
    Mat *myImage = NULL;

};
#endif // WIDGET_H

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;
    delete myImage;
    if(m_pcMyCamera)
    {
    
    
        m_pcMyCamera->Close();
        delete m_pcMyCamera;
        m_pcMyCamera = NULL;
    }
    if(myThread->isRunning())
    {
    
    
        myThread->requestInterruption();
        myThread->wait();
        delete myThread;
    }
}

void Widget::initWidget()
{
    
    
    //设置窗口属性
    this->setWindowTitle("相机测试");
    this->setWindowFlags(Qt::WindowCloseButtonHint | Qt::Dialog);
    this->setWindowModality(Qt::ApplicationModal);
    this->setFixedSize(this->width(),this->height());

    //初始化变量
    m_bOpenDevice = false;

    //生成保存图片的文件夹
    QString imagePath = QDir::currentPath() + "/myImage/";
    QDir dstDir(imagePath);
    if(!dstDir.exists())
    {
    
    
        if(!dstDir.mkdir(imagePath))
        {
    
    
            qDebug()<<"创建Image文件夹失败!";
            //return;
        }
    }

    //图像指针对象
    myImage = new Mat();

    //线程对象实例化
    myThread = new MyThread();
    connect(myThread,SIGNAL(signal_message()),this,SLOT(slot_display()));
    connect(myThread,SIGNAL(signal_messImage(QImage)),this,SLOT(slot_displayImage(QImage)));
}

//保存图片
void Widget::saveImage(QString format)
{
    
    
    if(ui->lb_show->pixmap() == NULL)
    {
    
    
        QMessageBox::warning(this,"警告","保存失败,未采集到图像!");
        return;
    }
    //QPixmap方法保存在程序运行目录
    //format: .bmp .tif .png .jpg
    QString savePath = QDir::currentPath() + "/myImage/";
    QString curDate = QDateTime::currentDateTime().toString("yyyyMMdd-hhmmss.zzz");
    QString saveName = savePath + curDate + "." + format;
    const QPixmap *curImage = ui->lb_show->pixmap();
    qDebug()<<"saveName:"<<saveName;
    if(curImage->save(saveName))
    {
    
    
        qDebug()<<"保存成功!";
    }
    else
    {
    
    
        qDebug()<<"保存失败!";
    }
}

//用于显示单张图像
void Widget::display(const Mat* imagePtr)
{
    
    
    qDebug()<<"single display ok";
    //判断是黑白、彩色图像
    QImage* QmyImage = new QImage();
    if(imagePtr->channels()>1)
    {
    
    
        *QmyImage = QImage((const unsigned char*)(imagePtr->data),imagePtr->cols,imagePtr->rows,QImage::Format_RGB888);
    }
    else
    {
    
    
        *QmyImage = QImage((const unsigned char*)(imagePtr->data),imagePtr->cols,imagePtr->rows,QImage::Format_Indexed8);
    }

    *QmyImage = (*QmyImage).scaled(ui->lb_show->size(),Qt::IgnoreAspectRatio,Qt::SmoothTransformation);

    //QImage保存图像
    //QmyImage->save(saveName);

    //显示图像
    ui->lb_show->setPixmap(QPixmap::fromImage(*QmyImage));
    delete QmyImage;
}

void Widget::slot_display()
{
    
    
    qDebug()<<"continuous display ok";
    //判断是黑白、彩色图像
    QImage *QmyImage = new QImage();
    if(myImage->channels()>1)
    {
    
    
        *QmyImage = QImage((const unsigned char*)(myImage->data),myImage->cols,myImage->rows,QImage::Format_RGB888);
    }
    else
    {
    
    
        *QmyImage = QImage((const unsigned char*)(myImage->data),myImage->cols,myImage->rows,QImage::Format_Indexed8);
    }

    *QmyImage = (*QmyImage).scaled(ui->lb_show->size(),Qt::IgnoreAspectRatio,Qt::SmoothTransformation);

    //显示图像
    ui->lb_show->setPixmap(QPixmap::fromImage(*QmyImage));
    delete QmyImage;
}

void Widget::slot_displayImage(QImage myImage)
{
    
    
    //显示图像
    //QSize imageSize = QSize(400,400);
    //可以使用imageSize代替ui->lb_show->size(),固定图片显示窗口的大小,解决布局情况下图像窗口逐渐变大的bug。
    myImage = (myImage).scaled(ui->lb_show->size(),Qt::IgnoreAspectRatio,Qt::SmoothTransformation);
    ui->lb_show->setPixmap(QPixmap::fromImage(myImage));
}

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)
    {
    
    
        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;
        }
        qDebug()<<"strModelName:"<<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;
    if(NULL == m_pcMyCamera)
    {
    
    
        return;
    }
    int nIndex = ui->cb_devices->currentIndex();
    //打开设备
    int nRet = m_pcMyCamera->Open(m_stDevList.pDeviceInfo[nIndex]);
    qDebug()<<"Connect:"<<nRet;
    if(MV_OK != nRet)
    {
    
    
        delete m_pcMyCamera;
        m_pcMyCamera = NULL;
        QMessageBox::warning(this,"警告","打开设备失败!");
        return;
    }
    //设置为触发模式
    qDebug()<<"TriggerMode:"<<m_pcMyCamera->SetEnumValue("TriggerMode",1);
    //设置触发源为软触发
    qDebug()<<"TriggerSource:"<<m_pcMyCamera->SetEnumValue("TriggerSource",7);
    //设置曝光时间
    qDebug()<<"SetExposureTime:"<<m_pcMyCamera->SetFloatValue("ExposureTime",5000);
    //开启相机采集
    qDebug()<<"StartCamera:"<<m_pcMyCamera->StartGrabbing();

    myThread->getCameraPtr(m_pcMyCamera);
    myThread->getImagePtr(myImage);

    m_bOpenDevice = true;

}

void Widget::on_pb_close_clicked()
{
    
    
    if(m_pcMyCamera)
    {
    
    
        m_pcMyCamera->Close();
        delete m_pcMyCamera;
        m_pcMyCamera = NULL;
        m_bOpenDevice = false;
    }
}

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

    Mat *image = new Mat();
    //发送软触发
    qDebug()<<"single SoftTrigger:"<<m_pcMyCamera->CommandExecute("TriggerSoftware");
    //读取Mat格式的图像
    qDebug()<<"single ReadBuffer:"<<m_pcMyCamera->ReadBuffer(*image);
    display(image);
    //释放指针
    delete image;
}

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

    if(!myThread->isRunning())
    {
    
    
        myThread->start();
    }
}

void Widget::on_pb_stop_clicked()
{
    
    
    if(myThread->isRunning())
    {
    
    
        myThread->requestInterruption();
        myThread->wait();
    }
}

void Widget::on_pb_saveBmp_clicked()
{
    
    
    saveImage("bmp");   //文件较大
}

void Widget::on_pb_savePng_clicked()
{
    
    
    saveImage("png");   //文件较小
}

7.widget.ui
Por favor agregue una descripción de la imagen

8. Código completo
enlace de enlace de disco de red Baidu: https://pan.baidu.com/s/1bs59hJz155NP3aQMnqCDSA
código de extracción: xxcj

4. Resolución de problemas

1.error: '__int64' no nombra un tipo; ¿quiso decir '__divtc3'? typedef __int64 int64_t;
Solución:
ingrese el archivo PixelType.h, modifique la línea: 181
#define __int64 long long
Por favor agregue una descripción de la imagen

2. error: la referencia a 'ACCESS_MASK' es ambigua typedef ACCESS_MASK *PACCESS_MASK;
Solución:
enmascare o elimine "using namepac cv;" en el archivo de encabezado,
y luego agregue el prefijo "cv::" a la función o tipo de datos correspondiente Para ejemplo: "cv::Mat"


Resumir

En comparación con la demostración proporcionada por Haikang, este ejemplo también carece de algunas funciones para configurar parámetros, y la implementación es relativamente simple.La imagen se guarda en el directorio en ejecución del programa utilizando el método QPixmap en qt, y no se escriben algunos otros trabajos preparatorios. En este artículo, puede ver los siguientes blogs de referencia para obtener más detalles.


hola:
Aprendamos juntos y progresemos juntos. Si aún tiene preguntas relacionadas, puede dejar un mensaje en el área de comentarios para la discusión.

Blog de referencia: lo llevará a imitar el desarrollo secundario de Hikvision sdk+Qt (abajo)
Desarrollo secundario de Hikvision Industrial Camera SDK (VS+Opencv+QT+Hikang SDK+C++) (2)

Supongo que te gusta

Origin blog.csdn.net/XCJandLL/article/details/127126555
Recomendado
Clasificación