Qt 与 Halcon 联合开发六:基于海康SDK设计完整的相机类【附源码】

发布于:2025-06-29 ⋅ 阅读:(24) ⋅ 点赞:(0)

在现代工业自动化、机器人视觉、等领域,相机模块的作用至关重要。通过相机模块采集到的图像数据,我们能够进行一系列的图像处理和分析。为了高效地控制相机和处理图像,本篇文章将介绍如何使用QtHalcon联合开发一个相机模块,帮助开发者掌握如何在视觉上位机中应用相机模块。

项目下载
通过网盘分享的文件:Qt-Halcon联合开发六:基于海康SDK封装相机模块
链接: https://pan.baidu.com/s/14qEf-5HOHe1W8Yqv_hTX_Q?pwd=jkcf 提取码: jkcf

1. 相机模块的开发与重要性

相机模块通常作为视觉上位机的关键组件之一,负责采集图像数据并进行传输。这一模块是整个视觉系统的核心,不仅直接影响到图像数据的质量,还决定了后续图像处理、分析和识别的效果。在开发复杂的视觉系统时,相机模块需要具备以下功能:

  1. 设备控制:控制相机的开关、参数设置、图像采集等。
  2. 数据采集:实时采集图像数据并进行回调处理。
  3. 数据传输:将采集到的图像数据传输给图像处理平台(如Halcon)。
  4. 错误反馈:处理相机的连接、采集过程中的错误,确保系统稳定运行。

开发一个高效的相机模块对于实现精准的图像分析至关重要,尤其是在复杂的自动化检测、机器人视觉等场景中。通过与Halcon集成,我们可以借助Halcon强大的图像处理能力,进行更加高效的图像分析和数据处理。


2. 项目背景与开发工具

本项目结合了QtHalcon两个强大的开发工具:

  • Qt:Qt是一款跨平台的开发框架,适用于开发桌面应用程序和GUI应用。它可以非常方便地与硬件设备进行交互,特别适合用于相机控制和用户界面开发。
  • Halcon:Halcon是一款强大的工业级图像处理库,提供了丰富的图像处理算法,支持多种图像格式与设备接口,能够快速处理和分析图像数据。

在这篇文章中,我们将使用这两个工具联合开发一个相机模块,利用Qt控制相机的操作,利用Halcon进行图像处理。


3. 相机模块的设计

我们将开发一个名为HikCamera的相机类,来实现与相机的交互和图像数据的处理。该类主要负责以下任务:

  • 打开相机设备
  • 设置相机参数
  • 开始和停止图像采集
  • 执行软触发操作
  • 处理采集到的图像数据

3.1 完整的HikCamera类定义

#ifndef HIKCAMERA_H
#define HIKCAMERA_H

#include <QString>
#include <QDebug>
#include <QDateTime>
#include <QSettings>
#include "MvCameraControl.h"

// 将字符数组转换为QString
#define tc(a) QString::fromLocal8Bit(a)
// 图像回调函数
void __stdcall ImageCallBack(unsigned char* pData, MV_FRAME_OUT_INFO_EX* pFrameInfo, void* pUser);
// 异常回调函数
void __stdcall ExceptionCallBack(unsigned int nMsgType, void* pUser);
class HikCamera
{
    // 定义相机连接模式
    enum OpenCameraWay
    {
        OpenContinue,       ///< 连续采集
        OpenSoftWare,       ///< 软触发采集
        OpenHardWare,       ///< 硬触发采集
    };

    /**
      * @enum ImageFormat
      * @brief 枚举相机的图像数据格式
     */
    enum class ImageFormat
    {
        Mono8,          ///< 黑白图像
        RGB8,           ///< RGB8图像格式
        BayerRG8,       ///< BayerRG8图像格式
    };

    // 定义相机类型
    enum class CameraType
    {
        GIGE,        ///< 网口相机
        USB3,        ///< USB3相机
        CL,          ///< CameraLink相机
    };

public:
    /**
      * @brief 构造函数,初始化相机对象
      * @param[in] index 相机索引
      * @param[in] ip 相机IP地址
     */
    HikCamera(const int index, const QString& ip);

    /**
      * @brief 析构函数,销毁相机对象
     */
    ~HikCamera();

    /**
      * @brief 打开相机
      * @return 是否成功打开相机
     */
    bool openCamera();

    /**
      * @brief 设置相机参数
      * @param[in] ExposureTime 曝光时间
      * @param[in] Gain 增益
      * @param[in] TriggerDelay 触发延时
      * @param[in] Width 图像宽度
      * @param[in] Height 图像高度
      * @param[in] offSetX 偏移量X
      * @param[in] offSetY 偏移量Y
      * @return 是否成功设置相机参数
     */
    bool setCameraParameters(float ExposureTime, float Gain, float TriggerDelay, int Width, int Height, int offSetX, int offSetY);

    /**
      * @brief 开始图像采集
      * @return 是否成功开始采集
     */
    bool startGrabbing();

    /**
      * @brief 停止图像采集
      * @return 是否成功停止采集
     */
    bool stopGrabbing();

    /**
      * @brief 关闭相机
      * @return 是否成功关闭相机
     */
    bool closeCamera();

    /**
      * @brief 判断相机是否已打开
      * @return 相机是否打开
     */
    bool isOpen() const;

    /**
      * @brief 判断是否正在采集图像
      * @return 是否正在采集
     */
    bool isGrabbing() const;

    /**
      * @brief 执行软触发
      * @return 是否成功执行软触发
     */
    bool executeSoftTrigger();

    /**
      * @brief 更新相机内部的最新错误信息
      * @param[in] msg 错误信息
     */
    void setLastErrorMsg(const QString& msg) { m_lastErrorMsg = msg; }

    /**
      * @brief 将IP地址转换为整数
      * @param[in] ip IP地址
      * @return 转换后的整数
     */
    unsigned int ipAddressToInt(const QString& ip);

    /**
      * @brief 设置相机类型
      * @param[in] type 相机类型,默认为GIGE
     */
    void setCameraType(const CameraType type = CameraType::GIGE) { m_type = type; }

    /**
      * @brief 获取相机类型
      * @return 相机类型
     */
    CameraType getCameraType() const { return m_type; }

    /**
      * @brief 设置相机图像格式
      * @param[in] format 图像格式,默认为Mono8
     */
    void setCameraImageFormat(const ImageFormat format = ImageFormat::Mono8) { m_imageFormat = format; }

    /**
      * @brief 获取相机图像格式
      * @return 图像格式
     */
    ImageFormat getCameraImageFormat() const { return m_imageFormat; }

public:
    /**
      * @brief 设置触发模式
      * @param[in] way 触发方式
      * @return 是否成功设置触发模式
     */
    bool setTriggerMode(OpenCameraWay way);

    /**
      * @brief 发送错误信息
      * @param[in] msg 错误信息
     */
    void sendErrorsMsgs(const QString& msg);

    /**
      * @brief 发送信息消息
      * @param[in] msg 信息消息
     */
    void sendInforMsgs(const QString& msg);

public:
    // 定义相机句柄类型
    typedef void* HikCameraHandle;

    HikCameraHandle m_handle;  ///< 相机句柄
    bool m_isOpen;             ///< 相机是否已打开
    bool m_isGrabbing;         ///< 是否正在采集图像
    int m_num;                 ///< 相机编号
    int m_i;                   ///< 相机编号索引
    QString m_ip;              ///< 相机IP地址
    int m_cameraIndex;         ///< 相机索引
    QString m_lastErrorMsg;    ///< 最新的错误信息

    ImageFormat m_imageFormat; ///< 图像格式
    CameraType m_type;         ///< 相机类型
};



#endif // HIKCAMERA_H

3.2 核心功能接口总结

  • 构造函数与析构函数

    • HikCamera::HikCamera(const int index, const QString& ip):用于初始化相机对象,接收相机的索引和IP地址作为参数。
    • HikCamera::~HikCamera():析构函数,在对象销毁时关闭相机并销毁相机句柄。
  • 相机控制接口

    • openCamera():打开相机,查找连接的设备,并初始化设备句柄。
    • closeCamera():关闭相机,停止图像采集并关闭设备连接。
    • startGrabbing():开始图像采集。
    • stopGrabbing():停止图像采集。
    • executeSoftTrigger():执行软触发操作。
  • 相机参数设置

    • setCameraParameters():设置相机的参数,如曝光时间、增益、图像分辨率等。
  • 状态与错误反馈

    • isOpen():检查相机是否已打开。
    • isGrabbing():检查是否正在采集图像。
    • setLastErrorMsg():设置最新的错误信息。
    • sendErrorsMsgs():输出错误信息,帮助开发人员排查问题。

3.3 示例代码分析

打开相机 (openCamera)
bool HikCamera::openCamera()
{
    int nRet = MV_OK;
    m_isOpen = false;

    // 枚举设备
    MV_CC_DEVICE_INFO_LIST cameraList;
    unsigned int i = 0;
    if (MV_OK != (nRet = MV_CC_EnumDevices(MV_GIGE_DEVICE, &cameraList)))
    {
        sendErrorsMsgs(tc("无法找到可用的网口相机, 错误码: %1").arg(nRet));
        return false;
    }

    // 选择设备并创建句柄
    MV_CC_DEVICE_INFO cameraInfo;
    memcpy(&cameraInfo, cameraList.pDeviceInfo[i], sizeof(MV_CC_DEVICE_INFO));
    if (MV_OK != (nRet = MV_CC_CreateHandle(&m_handle, &cameraInfo)))
    {
        sendErrorsMsgs(tc("相机初始化失败, 错误码: %1").arg(nRet));
        return false;
    }

    if (MV_OK != (nRet = MV_CC_OpenDevice(m_handle, MV_ACCESS_Exclusive)))
    {
        sendErrorsMsgs(tc("无法打开相机, 错误码: %1").arg(nRet));
        return false;
    }

    return (m_isOpen = (MV_OK == nRet));
}

功能说明

  • openCamera()函数首先枚举所有连接到PC的相机设备,然后根据指定的设备类型(如GIGE设备),创建相机句柄并尝试打开相机设备。
  • 若设备打开失败,函数会输出错误信息并返回false
设置相机参数 (setCameraParameters)
bool HikCamera::setCameraParameters(float ExposureTime, float Gain, float TriggerDelay, int Width, int Height, int offSetX, int offSetY)
{
    // 设置曝光时间
    if (ExposureTime >= 0)
        if (MV_OK != MV_CC_SetExposureTime(m_handle, ExposureTime))
            return false;

    // 设置增益
    if (Gain >= 0)
        if (MV_OK != MV_CC_SetGain(m_handle, Gain))
            return false;

    // 设置图像分辨率与偏移量
    if (Width >= 0 && MV_OK != MV_CC_SetWidth(m_handle, static_cast<unsigned int>(Width)))
        return false;
    if (Height >= 0 && MV_OK != MV_CC_SetHeight(m_handle, static_cast<unsigned int>(Height)))
        return false;

    return true;
}

功能说明

  • setCameraParameters()函数用于设置相机的曝光时间、增益、图像分辨率和ROI区域的偏移量。
  • 每个参数的设置都会通过SDK的API进行调用,若设置失败,返回false

4. 集成Halcon进行图像处理

相机模块采集到图像后,我们将图像数据传递给Halcon进行后续处理。Halcon能够进行复杂的图像分析、模式识别和检测任务,是工业视觉中广泛使用的工具。

4.1 图像数据回调
void ImageCallBack(unsigned char* pData, MV_FRAME_OUT_INFO_EX* pFrameInfo, void* pUser)
{
    HikCamera* camera = static_cast<HikCamera*>(pUser);
    HalconCpp::HObject ho_Image;
    int imageWidth = pFrameInfo->nWidth;
    int imageHeight = pFrameInfo->nHeight;

    switch (pFrameInfo->enPixelType)
    {
    case PixelType_Gvsp_Mono8:
        HalconCpp::GenImage1(&ho_Image, "byte", imageWidth, imageHeight, reinterpret_cast<Hlong>(pData));
        break;
    case PixelType_Gvsp_RGB8_Packed:
        HalconCpp::GenImageInterleaved(&ho_Image, reinterpret_cast<Hlong>(pData), "rgb", imageWidth, imageHeight, -1, "byte", 0, 0, 0, 0, -1, 0);
        break;
    // 其他图像格式转换...
    }
}

功能说明

  • 图像数据通过回调函数ImageCallBack传递给Halcon进行处理。根据图像的像素类型,选择合适的图像生成方法。
  • HalconCpp::GenImage1HalconCpp::GenImageInterleaved函数将原始图像数据转化为Halcon可处理的图像对象。


网站公告

今日签到

点亮在社区的每一天
去签到