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 - 示例程序源代码

海康威视相机介绍

海康威视相机的文档特别清晰,特别是示例代码非常详细,可以非常快速的上手并使用。安装了海康威视相机驱动也可以使用巴斯勒的相机,博主感觉海康威视相机像是对巴斯勒相机做了包装和拓展,博主查看了源代码,其中 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

自定义 BMVCamerControl 相机控制类

#ifndef BMVCAMERCONTROL_H
#define BMVCAMERCONTROL_H

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

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

    explicit BMVCamerControl(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(BMVCamerControl::BMVCamerProperty type);                  // 获取相机参数
    void setCameraProperty(BMVCamerControl::BMVCamerProperty type, double value = 0.0); // 设置相机参数

public slots:
    void updateFrame();

private:
    void *m_devHandle;
    unsigned char* m_data;
    const int m_size = 1280 * 1024 * 3;
    MV_FRAME_OUT_INFO_EX m_frame_info;
};

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

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

void BMVCamerControl::initCamera()
{
    m_devHandle = nullptr;
    m_data = new unsigned char[m_size];
}

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

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

void BMVCamerControl::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_CreateHandle(&m_devHandle, pstDevList.pDeviceInfo[0]);    // 创建设备句柄
                MV_CC_OpenDevice(m_devHandle);                                  // 打开设备

                // 探测网络最佳包大小(只对GigE相机有效)
                int nPacketSize = MV_CC_GetOptimalPacketSize(m_devHandle);
                MV_CC_SetIntValue(m_devHandle, "GevSCPSPacketSize", nPacketSize);

                MV_CC_SetPixelFormat(m_devHandle, PixelType_Gvsp_Mono8);        // 设置像素格式
            }
        }
    } catch (...) {
        qDebug() << "openCamera erroer !";
    }
}

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

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

    try {
        MV_CC_StartGrabbing(m_devHandle);   // 开始取流
        m_timer.start();
    } catch (...) {
        qDebug() << "startWork erroer !";
    }
}

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

cv::Mat BMVCamerControl::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 erroer !";
        return cv::Mat();
    }
}

QString BMVCamerControl::getCameraProperty(BMVCamerControl::BMVCamerProperty 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 erroer !";
    }

    return ret;
}

void BMVCamerControl::setCameraProperty(BMVCamerControl::BMVCamerProperty 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 erroer !";
    }
}

void BMVCamerControl::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 erroer !";
    }
}

其他请参考

猜你喜欢

转载自blog.csdn.net/qq_34139994/article/details/107706251