QT(C++)调用海康工业相机SDK采集图像的简单示例

QT(C++)调用海康工业相机SDK采集图像的简单示例

简介
前一篇是用VS(C#)调用海康SDK采集图像,调用halcon库将采集到的图像进行转换,有时在测试相机时会涉及到halcon的license问题,比较麻烦,所以打算利用opencv图像库来转换图像,顺便用QT来实现图像的采集。
在这里插入图片描述
开发环境
Qt 5.4.0 (MSVC 2010, 32 bit)
QT Creator 3.3.0
OpenCV 2.4.9

引用海康的库文件
1.将海康安装目录\MVS\Development\下的Includes文件夹连同里面的文件一起复制到QT工程目录下。
2. 将海康安装目录\MVS\Development\Libraries\win64\下的MvCameraControl.lib文件复制到QT工程文件下的指定位置,例如刚刚复制到QT工程里面的Includes文件夹中(后面引用该库文件会设置在这个位置)。
3. 在QT的pro文件中添加以下代码:
LIBS += -L $ $PWD/Includes/ -lMvCameraControl
INCLUDEPATH += $ $ PWD/Includes
DEPENDPATH += $ $ PWD/Includes
4. 创建的相机类头文件中添加引用#include"Includes/MvCameraControl.h"

此外还需要引用OpenCV的库,具体方法请百度。

1.创建相机类
鼠标右键单击项目文件–添加新文件–选择“C++ Class”–单击右下角“Choose…”,输入类名称,例如Mycamera–下一步–完成。
在这里插入图片描述
头文件mycamera.h

#ifndef MYCAMERA_H
#define MYCAMERA_H
#include"Includes/MvCameraControl.h"
#include"iostream"
#include"opencv2/opencv.hpp"
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace std;
using namespace cv;
class Mycamera
{
  public:
      Mycamera();
      ~Mycamera();
  //声明相关变量及函数等
  static int EnumDevices(MV_CC_DEVICE_INFO_LIST* pstDevList);

  // ch:连接相机
  int connectCamera(string id);

  //设置是否为触发模式
  int setTriggerMode(unsigned int TriggerModeNum);

  //开启相机采集
  int startCamera();

  //发送软触发
  int softTrigger();

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

  //设置心跳时间
  int setHeartBeatTime(unsigned int time);

  //设置曝光时间
  int setExposureTime(float ExposureTimeNum);
  private:
      void*               m_hDevHandle;

  public:
      unsigned char*  m_pBufForSaveImage;         // 用于保存图像的缓存
      unsigned int    m_nBufSizeForSaveImage;

      unsigned char*  m_pBufForDriver;            // 用于从驱动获取图像的缓存
      unsigned int    m_nBufSizeForDriver;
      };
#endif // MYCAMERA_H

编写对应的mycamera.cpp文件

#include "mycamera.h"

MV_CC_DEVICE_INFO_LIST m_stDevList;       // ch:设备信息列表结构体变量,用来存储设备列表
MV_CC_DEVICE_INFO* m_Device=NULL;         //设备对象

Mycamera::Mycamera()
{
    m_hDevHandle    = NULL;
}

Mycamera::~Mycamera()
{
    if (m_hDevHandle)
    {
        MV_CC_DestroyHandle(m_hDevHandle);
        m_hDevHandle    = NULL;
    }
}

//查询设备列表
int Mycamera::EnumDevices(MV_CC_DEVICE_INFO_LIST* pstDevList)
{
    int temp= MV_CC_EnumDevices(MV_GIGE_DEVICE | MV_USB_DEVICE, pstDevList);
    if (MV_OK != temp)
    {
        return -1;
    }
    return 0;
}

//连接相机
int  Mycamera::connectCamera(string id)
{
    int temp= EnumDevices(&m_stDevList);
    if(temp!=0)
        //设备更新成功接收命令的返回值为0,返回值不为0则为异常
        return -1;
    if(m_stDevList.nDeviceNum==0)
        //未找到任何相机
        return 2;
    for (unsigned int i = 0; i < m_stDevList.nDeviceNum; i++)
    {
        MV_CC_DEVICE_INFO* pDeviceInfo = m_stDevList.pDeviceInfo[i];
        if (NULL == pDeviceInfo)
        {
            continue;
        }
        if(id== (char*)pDeviceInfo->SpecialInfo.stGigEInfo.chUserDefinedName||id== (char*)pDeviceInfo->SpecialInfo.stGigEInfo.chSerialNumber)
        {
            m_Device= m_stDevList.pDeviceInfo[i];
            break;
        }else
        {
            continue;
        }
    }
    if(m_Device==NULL)
    {
        //未找到指定名称的相机
        return 3;
    }
    temp  = MV_CC_CreateHandle(&m_hDevHandle, m_Device);
    if(temp  !=0)
        return -1;

    temp  = MV_CC_OpenDevice(m_hDevHandle);
    if (temp  !=0)
    {
        MV_CC_DestroyHandle(m_hDevHandle);
        m_hDevHandle = NULL;
        return -1;
    }else
    {
        setTriggerMode(1);
        return 0;
    }
    if (m_Device->nTLayerType == MV_GIGE_DEVICE)
    {
       //std::cout<<"Gige Camera"<<std::endl;
    }
}
//启动相机采集
int Mycamera::startCamera()
{
    int temp=MV_CC_StartGrabbing(m_hDevHandle);
    if(temp!=0)
    {
        return -1;
    }else
    {
        return 0;
    }
}
//发送软触发
int Mycamera::softTrigger()
{
    int tempValue= MV_CC_SetCommandValue(m_hDevHandle, "TriggerSoftware");
    if(tempValue!=0)
    {
        return -1;
    }else
    {
        return 0;
    }
}
//读取相机中的图像
int Mycamera::ReadBuffer(Mat &image)
{
    unsigned int nRecvBufSize = 0;
    MVCC_INTVALUE stParam;
    memset(&stParam, 0, sizeof(MVCC_INTVALUE));
    int temp = MV_CC_GetIntValue(m_hDevHandle, "PayloadSize", &stParam);
    if (temp != 0)
    {
        return -1;
    }
    nRecvBufSize = stParam.nCurValue;
    m_pBufForDriver = (unsigned char *)malloc(nRecvBufSize);
    MV_FRAME_OUT_INFO_EX stImageInfo = {0};
    tempValue= MV_CC_GetOneFrameTimeout(m_hDevHandle, m_pBufForDriver, nRecvBufSize, &stImageInfo, 700);
    if(tempValue!=0)
    {
        return -1;
    }
    m_nBufSizeForSaveImage = stImageInfo.nWidth * stImageInfo.nHeight * 3 + 2048;
    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)
    {
        image=Mat(stImageInfo.nHeight,stImageInfo.nWidth,CV_8UC1,m_pBufForDriver);
    }
    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.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);
        image=Mat(stImageInfo.nHeight,stImageInfo.nWidth,CV_8UC3,m_pBufForSaveImage);
    }
    return 0;
}
//设置心跳时间
int Mycamera::setHeartBeatTime(unsigned int time)
{
    //心跳时间最小为500ms
    if(time<500)
        time=500;
    int temp=MV_CC_SetIntValue(m_hDevHandle, "GevHeartbeatTimeout", time);
    if(temp!=0)
    {
        return -1;
    }
    else
    {
        return 0;
    }
}
//设置曝光时间
int Mycamera::setExposureTime(float ExposureTimeNum)
{
    int temp= MV_CC_SetFloatValue(m_hDevHandle, "ExposureTime",ExposureTimeNum );
    if(temp!=0)
        return -1;
    return 0;
}

2.利用QT中的Label将图像显示出来
编写用于显示图像的槽函数。在本文中,是创建了一个线程对象th,在线程中采集图像,采集到的图像变量为th->grabImage。

void MainWindow::dis()
{
    //std::cout<<"SLOT函数"<<std::endl;
    QImage img = QImage((const unsigned char*)(th->grabImage.data),th->grabImage.cols, th->grabImage.rows, QImage::Format_RGB888);
    //设定图像大小自适应label窗口的大小
    img = img.scaled(ui->labelImage->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
    ui->labelImage->setPixmap(QPixmap::fromImage(img));
}

注意:Qimage显示的彩色图像为RGB格式,而OpenCV默认的彩色图像格式是BGR,本文中的图像格式是RGB,无需转换,如果显示的图形为BGR格式,转换方法具体如下:

Mat rgb;
cv::cvtColor(th->grabImage,rgb,CV_BGR2RGB);


有很多人在问我要工程文件,现已将工程文件源码进行上传,下载地址如下:https://download.csdn.net/download/biggestcherry/11226810

水平有限,难免有错误和不足之处,恳请批评指正。

由于很多人私下问我很多相关的问题,实在没有时间一一作答,现将相关问题整理,添加了相关的功能,重新写了一篇以供参考,位置如下;
https://blog.csdn.net/biggestcherry/article/details/106154321

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页