当前位置: 首页 > news >正文

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

在现代工业自动化、机器人视觉、等领域,相机模块的作用至关重要。通过相机模块采集到的图像数据,我们能够进行一系列的图像处理和分析。为了高效地控制相机和处理图像,本篇文章将介绍如何使用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可处理的图像对象。

相关文章:

  • LeetCode 349题解 | 两个数组的交集
  • 洛谷P5021 [NOIP 2018 提高组] 赛道修建
  • kubesphere中搭建DevOps创建流水线
  • 关于SAP产品名称变更通知 SAP云认证实施商工博科技
  • 常用命令总结
  • 安全运营中的漏洞管理和相关KPI
  • HarmonyOS NEXT仓颉开发语言实现画板案例
  • HarmonyOS NEXT仓颉开发语言实战案例:简约音乐播放页
  • IPv4网络地址分类
  • Java 大视界 -- Java 大数据在智能安防视频监控系统中的目标轨迹预测与防范策略制定(325)
  • 机器学习6——线性分类函数
  • AI助力基因数据分析:用Python玩转生命密码的秘密
  • 操作系统面试知识点(1):操作系统基础
  • java枚举enum的使用示例
  • mac电脑安装vscode的力扣插件报错解决办法
  • 【Linux】基础开发工具(2)
  • 重定向攻击与防御
  • Docker 入门教程(二):Docker 的基本原理
  • 东芝e-STUDIO 2323AMW双面复印报计数器溢出故障
  • 《规则怪谈》合集