Qt调用工业相机之海康威视相机

作者:billy
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处

开发环境

操作系统:Windows 10 1903 18362.778
相机型号:MV-CA020-10GM
相机软件:MVS_SDK_V3_2_0_VC90_Runtime_190626,MVS_STD_3.1.0_181229
软件版本:Qt 5.12.8, vs2017 Community
通信方式:GigE - 千兆以太网通信协议

驱动与SDK

开发包和驱动下载地址
提取码:2hhn

安装驱动和开发包完成之后,可以找到以下目录:

  1. D:\Program Files (x86)\MVS\Development
    在这里插入图片描述
  • Documentations - 使用手册、示例程序说明等等
  • Includes - 头文件
  • Libraries - 库文件(包括 xxx.lib,xxx.a)
  • Samples - 示例程序源代码
  • 备注:默认在 C:\Program Files\ 或者 Program Files (x86)\Common Files\MVS 路径中,存在三个文件夹,分别是Drivers(驱动)、Runtime(动态库)、Service(相机日志服务)

海康威视相机介绍

海康威视相机的文档特别清晰,特别是示例代码非常详细,可以非常快速的上手并使用。安装了海康威视相机驱动也可以使用巴斯勒的相机,博主感觉海康威视相机像是对巴斯勒相机做了包装和拓展,博主查看了源代码,其中 GenICam 这一块的代码和巴斯勒是完全相同的。。。
在这里插入图片描述
函数定义中把每个函数的使用都介绍的很清楚,这里就不多做介绍了。

我的代码

实现功能:相机图像的实时显示,并且可以在需要的时候获取当前帧数据,用于分析或者保存;

首先需要在pro中配置头文件和库文件

INCLUDEPATH += $$PWD/MV_Camera_Control/include/ \

contains(DEFINES, WIN64) {
    LIBS += -L$$PWD/MV_Camera_Control/lib/win64/ -lMvCameraControl
} else {
    LIBS += -L$$PWD/MV_Camera_Control/lib/Win32/ -lMvCameraControl
}

自定义相机基类 Camera

#ifndef CAMERA_H
#define CAMERA_H

#include <QObject>
#include <QImage>
#include <QTimer>
#include <QMutex>

#include <opencv2/opencv.hpp>

class Camera : public QObject
{
    Q_OBJECT

public:
    enum CameraType {
        Basler = 1,                     // 巴斯勒相机
        IC_Imaging,                     // 映美精相机
        MV,                             // 海康威视相机
        Virtual                         // 虚拟相机
    };

    explicit Camera(CameraType type = Basler) : m_type(type) {}

    virtual void initCamera() = 0;      // 初始化相机
    virtual void destroyCamera() = 0;   // 销毁相机
    virtual void openCamera() = 0;      // 打开相机
    virtual void closeCamera() = 0;     // 关闭相机
    virtual void startWork() = 0;       // 开始工作
    virtual void stopWork() = 0;        // 停止工作
    virtual cv::Mat takeAPic() = 0;     // 获取当前图像

    void start() { m_timer.start(); }
    void stop() { m_timer.stop(); }
    void setInterval(int time) { m_timer.setInterval(time); }
    CameraType getCameraType() { return m_type; }

signals:
    void updateImage(QImage image);

protected:
    CameraType m_type;
    QMutex m_mutex;
    QTimer m_timer;
};

#endif // CAMERA_H

自定义 BMVCameraControl 相机控制类

#ifndef BMVCAMERCONTROL_H
#define BMVCAMERCONTROL_H

#include "../camera.h"
#include "MvCameraControl.h"

class BMVCameraControl : public Camera
{
    Q_OBJECT
public:
    enum BMVCameraProperty {
        Width,                      // 图片宽度
        Height,                     // 图片高度
        ExposureTime,               // 曝光时间
        Brightness,                 // 亮度
        FrameRate,                  // 帧率
        Gain,                       // 增益
        PixelFormat,                // 像素格式
        TriggerMode                 // 触发模式
    };

    explicit BMVCameraControl(Camera::CameraType type = Camera::CameraType::MV);

    virtual void initCamera() override;
    virtual void destroyCamera() override;

    virtual void openCamera() override;
    virtual void closeCamera() override;

    virtual void startWork() override;
    virtual void stopWork() override;

    virtual cv::Mat takeAPic() override;

    QString getCameraProperty(BMVCameraControl::BMVCameraProperty type);                 	// 获取相机参数
    void setCameraProperty(BMVCameraControl::BMVCameraProperty type, double value = 0.0);	// 设置相机参数

public slots:
    void updateFrame();

private:
    void *m_devHandle;
    unsigned char *m_data;
    int m_size;
    MV_FRAME_OUT_INFO_EX m_frame_info;
};

#endif // BMVCAMERCONTROL_H
#include "bmvcameracontrol.h"
#include "globalfun.h"

BMVCameraControl::BMVCameraControl(Camera::CameraType type) : Camera(type)
{
    m_timer.setInterval(GlobalValue::cam_itl);
    connect(&m_timer, &QTimer::timeout, this, &BMVCameraControl::updateFrame);
}

void BMVCameraControl::initCamera()
{
    m_devHandle = nullptr;
    m_data = nullptr;
    m_size = 0;
}

void BMVCameraControl::destroyCamera()
{
    try {
        stopWork();
        closeCamera();

        if ( m_devHandle ) {
            MV_CC_DestroyHandle(m_devHandle);   // 销毁设备句柄
            m_devHandle = nullptr;
            delete[] m_data;
        }
    } catch (...) {
        qDebug() << "destroyCamera error !";
    }
}

void BMVCameraControl::openCamera()
{
    try {
        MV_CC_DEVICE_INFO_LIST pstDevList;
        int ret = MV_CC_EnumDevices(MV_GIGE_DEVICE | MV_USB_DEVICE, &pstDevList);

        if ( ret == MV_OK ) {
            if ( pstDevList.nDeviceNum == 0 ) {
                qDebug() << "No device found !";
            } else {
                MV_CC_DEVICE_INFO m_stDevInfo;
                memcpy(&m_stDevInfo, pstDevList.pDeviceInfo[0], sizeof(MV_CC_DEVICE_INFO));

                ret = MV_CC_CreateHandle(&m_devHandle, &m_stDevInfo);           // 创建设备句柄
                if ( ret != MV_OK ) { qDebug() << "CreateHandle failed !"; }
                ret = MV_CC_OpenDevice(m_devHandle);                            // 打开设备
                if ( ret != MV_OK ) { qDebug() << "OpenDevice failed !"; }

                // 探测网络最佳包大小(只对GigE相机有效)
                if ( m_stDevInfo.nTLayerType == MV_GIGE_DEVICE )
                {
                    int nPacketSize = MV_CC_GetOptimalPacketSize(m_devHandle);
                    if (nPacketSize > 0)
                    {
                        ret = MV_CC_SetIntValue(m_devHandle, "GevSCPSPacketSize", nPacketSize);
                        if ( ret != MV_OK ) { qDebug() << "SetIntValue failed !"; }
                    }
                }

                ret = MV_CC_SetPixelFormat(m_devHandle, PixelType_Gvsp_Mono8);  // 设置像素格式
                if ( ret != MV_OK ) { qDebug() << "SetPixelFormat failed !"; }
            }
        }
    } catch (...) {
        qDebug() << "openCamera error !";
    }
}

void BMVCameraControl::closeCamera()
{
    try {
        MV_CC_CloseDevice(m_devHandle); // 关闭相机
    } catch (...) {
        qDebug() << "closeCamera error !";
    }
}

void BMVCameraControl::startWork()
{
    // 判断相机是否处于连接状态
    if ( !MV_CC_IsDeviceConnected(m_devHandle) ) {
        return;
    }

    try {
        // 获取一帧数据的大小
        MVCC_INTVALUE stIntvalue;
        int ret = MV_CC_GetIntValue(m_devHandle, "PayloadSize", &stIntvalue);
        if ( ret != MV_OK ) { qDebug() << "GetIntValue failed !"; }

        m_size = stIntvalue.nCurValue; // 一帧数据大小
        m_data = (unsigned char*)malloc(m_size);
        memset(&m_frame_info, 0, sizeof(MV_FRAME_OUT_INFO_EX));

        ret = MV_CC_StartGrabbing(m_devHandle); // 开始采集图像
        if ( ret != MV_OK ) { qDebug() << "StartGrabbing failed !"; }
        m_timer.start();
    } catch (...) {
        qDebug() << "startWork error !";
    }
}

void BMVCameraControl::stopWork()
{
    try {
        if ( MV_CC_IsDeviceConnected(m_devHandle) ) {
            MV_CC_StopGrabbing(m_devHandle);    // 停止取流
            m_timer.stop();
        }
    } catch (...) {
        qDebug() << "stopWork error !";
    }
}

cv::Mat BMVCameraControl::takeAPic()
{
    // 判断相机是否处于连接状态
    if ( !MV_CC_IsDeviceConnected(m_devHandle) ) {
        return cv::Mat();
    }

    QMutexLocker locker(&m_mutex);

    try {
        int nRet = MV_CC_GetOneFrameTimeout(m_devHandle, m_data, m_size, &m_frame_info, 1000);
        if ( nRet == MV_OK ) {
            QImage image(static_cast<uchar*>(m_data),
                         m_frame_info.nWidth,
                         m_frame_info.nHeight,
                         QImage::Format_Grayscale8);

            QImage retImage = image.convertToFormat(QImage::Format_RGB888);
            cv::Mat mat = GlobalFun::convertQImageToMat(retImage);
            return mat.clone();
        } else {
            return cv::Mat();
        }
    } catch (...) {
        qDebug() << "takeAPic error !";
        return cv::Mat();
    }
}

QString BMVCameraControl::getCameraProperty(BMVCameraControl::BMVCameraProperty type)
{
    // 判断相机是否处于连接状态
    if ( !MV_CC_IsDeviceConnected(m_devHandle) ) {
        return "";
    }

    QString ret = "";
    MVCC_INTVALUE int_value;
    MVCC_FLOATVALUE float_value;
    MVCC_ENUMVALUE enum_value;

    try {
        switch (type) {
        case Width: {
            MV_CC_GetWidth(m_devHandle, &int_value);
            ret = QString::number(int_value.nCurValue);
        } break;
        case Height: {
            MV_CC_GetHeight(m_devHandle, &int_value);
            ret = QString::number(int_value.nCurValue);
        } break;
        case ExposureTime: {
            MV_CC_GetExposureTime(m_devHandle, &float_value);
            ret = QString::number(float_value.fCurValue);
        } break;
        case Brightness: {
            MV_CC_GetBrightness(m_devHandle, &int_value);
            ret = QString::number(int_value.nCurValue);
        } break;
        case FrameRate: {
            MV_CC_GetFrameRate(m_devHandle, &float_value);
            ret = QString::number(float_value.fCurValue);
        } break;
        case Gain: {
            MV_CC_GetGain(m_devHandle, &float_value);
            ret = QString::number(float_value.fCurValue);
        } break;
        case PixelFormat: {
            MV_CC_GetPixelFormat(m_devHandle, &enum_value);
            ret = QString::number(enum_value.nCurValue);
        } break;
        case TriggerMode: {
            MV_CC_GetTriggerMode(m_devHandle, &enum_value);
            ret = QString::number(enum_value.nCurValue);
        } break;
        default: ret = ""; break;
        }
    } catch (...) {
        qDebug() << "getCameraProperty error !";
    }

    return ret;
}

void BMVCameraControl::setCameraProperty(BMVCameraControl::BMVCameraProperty type, double value)
{
    // 判断相机是否处于连接状态
    if ( !MV_CC_IsDeviceConnected(m_devHandle) ) {
        return;
    }

    try {
        switch (type) {
        case Width: {
            MV_CC_SetWidth(m_devHandle, value);
        } break;
        case Height: {
            MV_CC_SetHeight(m_devHandle, value);
        } break;
        case ExposureTime: {
            MV_CC_SetExposureTime(m_devHandle, value);
        } break;
        case Brightness: {
            MV_CC_SetBrightness(m_devHandle, value);
        } break;
        case FrameRate: {
            MV_CC_SetFrameRate(m_devHandle, value);
        } break;
        case Gain: {
            MV_CC_SetGain(m_devHandle, value);
        } break;
        case PixelFormat: {
            MV_CC_SetPixelFormat(m_devHandle, value);
        } break;
        case TriggerMode: {
            MV_CC_SetTriggerMode(m_devHandle, value);
        } break;
        default: break;
        }
    } catch (...) {
        qDebug() << "setCameraProperty error !";
    }
}

void BMVCameraControl::updateFrame()
{
    QMutexLocker locker(&m_mutex);

    try {
        int nRet = MV_CC_GetOneFrameTimeout(m_devHandle, m_data, m_size, &m_frame_info, 1000);
        if ( nRet == MV_OK ) {
            QImage image(static_cast<uchar*>(m_data),
                         m_frame_info.nWidth,
                         m_frame_info.nHeight,
                         QImage::Format_Grayscale8);

            emit updateImage(image.convertToFormat(QImage::Format_RGB888));
        }
    } catch (...) {
        qDebug() << "updateFrame error !";
    }
}

其他请参考

评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值