当前位置: 首页 > 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可处理的图像对象。

http://www.lryc.cn/news/575936.html

相关文章:

  • 云计算与人工智能的融合:从弹性算力到智能云的IT新革命
  • 报道称CoreWeave洽谈收购Core Scientific,后者涨超30%
  • 内测开启!看海量化回测系统V2.0版本更新,基于miniQMT的回测系统问世!
  • Android 根据包名查看已安装应用的签名
  • 分布式session解决方案
  • 【Docker】解决:构建(docker build)或重新运行容器时,丢失apt-get update问题
  • 第三十一章 MCO——PA8从主频分频输出
  • 【数据挖掘】关联规则算法学习—Apriori
  • Gitee 持续集成与交付(CI/CD)篇
  • Solidity学习 - 断言失败
  • Java:链接mysql数据库报错:CommunicationsException: Communications link failure
  • MySQL Limit数量不满足时导致查询变慢
  • 深圳中青宝互动网络股份有限公司游戏运维工程师面试题(笔
  • 使用OpenCV进行3D重建:详细指南
  • OpenCV图像添加水印
  • word中如何保存高清图片,并保存为高质量的pdf文件(图像不失真)
  • 51c~嵌入式~PLC~西门子~合集1
  • GO 语言学习 之 语句块
  • 汉中农业服务——激活田野的希望,共绘乡村振兴图
  • Guava Cache 本地项目缓存
  • 昇腾910(NPU)安装paddlepaddle【自用版】
  • LinuxBridge的作用与发展历程:从基础桥接到云原生网络基石
  • 【Linux指南】压缩、网络传输与系统工具
  • 用 pnpm + TurboRepo,构建多项目高效开发体系
  • 人工智能-基础篇-4-人工智能AI、机器学习ML和深度学习DL之间的关系
  • 几种基于Doherty结构的GAN氮化镓功放设计方法介绍
  • Ehcache、Caffeine、Spring Cache、Redis、J2Cache、Memcached 和 Guava Cache 的主要区别
  • 算法-堆排序
  • 飞算科技依托 JavaAI 核心技术,打造企业级智能开发全场景方案
  • AIOps与人工智能的融合:从智能运维到自适应IT生态的革命