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.pswp.cn/web/86996.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/86996.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第7篇:Gin模板引擎——服务端页面渲染

作者:GO兔 博客:https://luckxgo.cn 分享大家都看得懂的博客 引言 在Web开发中&#xff0c;服务端页面渲染(SSR)依然是构建动态网页的重要方式。Gin框架虽然以API开发见长&#xff0c;但也内置了强大的模板引擎支持&#xff0c;基于Go标准库的html/template包实现。本文将深入…

RagFlow 源码部署启动指南

一、环境准备 1. 安装 uv 和 pre-commit 如果已安装&#xff0c;可跳过。推荐使用官方方式安装&#xff0c;避免报错&#xff1a; pipx install uv pre-commit export UV_INDEXhttps://mirrors.aliyun.com/pypi/simple安装报错 使用清华源安装&#xff1a; pipx install uv…

【Python基础】12 闲谈分享:Python用于无人驾驶的未来

引言&#xff1a;一个程序员的自动驾驶梦想 还记得2016年的那个秋天&#xff0c;我第一次坐进特斯拉Model S的驾驶座&#xff0c;体验Autopilot功能。当方向盘开始自己转动&#xff0c;车辆在高速公路上自动跟随前车时&#xff0c;我的内心涌起了一种奇妙的感觉——这不就是我…

为什么js是单线程?

js单线程&#xff0c;同一时间只能做一件事 。js的单线程 主要与它的用途有关。作为浏览器脚本语言&#xff0c;js的主要用途是与用户互动&#xff0c;以及操作DOM。这决定了它只能是单线程&#xff0c;否则会带来很复杂的同步问题。如果js同时有两个线程&#xff0c;一个线程在…

DVWA靶场通关笔记-文件包含(Medium级别 9种渗透方法)

目录 一、文件包含 1、原因 2、危害 3、防范措施 二、代码审计&#xff08;Medium级别&#xff09; 1、渗透准备 &#xff08;1&#xff09;配置php.ini &#xff08;2&#xff09;file1.php &#xff08;3&#xff09;file2.php &#xff08;4&#xff09;file3.php…

飞云翻倍布林(翻倍密码系统四线布林版)双安全系统+均价趋势指标+日线周线MACD,组合操盘技术图文分享

如上图组合操盘套装指标&#xff0c;主图指标-翻倍密码系统四线布林版-飞云翻倍布林。副图指标1-均价趋势指标&#xff0c;跟踪市场均价走势和趋势&#xff1b;副图指标2-日线周线MACD指标&#xff0c;跟踪日线和周线两个级别的MACD多空走势以及共振与否。 主图指标-飞云翻倍布…

《汇编语言:基于X86处理器》第6章 条件处理(1)

本章向程序员的汇编语言工具箱中引入一个重要的内容&#xff0c;使得编写出来的程序具备作决策的功能。几乎所有的程序都需要这种能力。首先&#xff0c;介绍布尔操作&#xff0c;由于能影响CPU状态标志&#xff0c;它们是所有条件指令的核心。然后&#xff0c;说明怎样使用演绎…

【分治思想】归并排序 与 逆序对

归并排序 归并排序是一种分治算法&#xff0c;怎么分&#xff0c;怎么治&#xff1f; 分&#xff1a;通过递归不断把数组分成两半&#xff0c;直到每个子数组只剩 1 个元素&#xff08;天然有序&#xff09;治&#xff1a;把两个已经排好序的子数组合并成一个有序数组。 把问…

SQL参数化查询:防注入与计划缓存的双重优势

在数据库操作中&#xff0c;SQL参数化查询&#xff08;Parameterized Queries&#xff09;是一种非常有效的技术&#xff0c;它不仅可以防止SQL注入攻击&#xff0c;还可以提高数据库查询的效率&#xff0c;尤其是在与计划缓存&#xff08;Query Plan Caching&#xff09;结合使…

【你怕一E1】- 孰轻孰重如何断-组合问题的多种情形

摘要 本视频讲解了组合问题的多种情形,包括多选一、多选二、多选三以及分队问题的解题方法。首先介绍了从不同人数中选人的不同选择方式,如一百人中选一人有一百种选择。随后,详细讲解了有序思考方法在多选二问题中的应用,通过选队长的方式列举不同组合情况,并归纳出选择规…

nginx反向代理的bug

nginx反向代理的bug 问题呈现 当我们配置反向代理的时候查询error.log的时候我们发现以下的问题 2025/06/29 08:38:47 [error] 7#7: *2 open() “/usr/share/nginx/html/payed/notify” failed (2: No such file or directory), client: 192.168.98.1, server: localhost, r…

MyBatis 动态 SQL 与缓存机制深度解析

在Java持久层技术体系中&#xff0c;MyBatis凭借其灵活的SQL映射和强大的动态SQL能力&#xff0c;成为企业级应用开发的首选框架。本文从动态SQL核心语法、缓存实现原理、性能优化及面试高频问题四个维度&#xff0c;结合源码与工程实践&#xff0c;系统解析MyBatis的核心特性与…

Nuxt 3 中实现跨组件通信方式总结:使用 Pinia、Provide/Inject 或 Props

在开发复杂的 Web 应用时&#xff0c;跨组件通信是一个常见的需求。Nuxt 3 提供了多种方式来实现这一点&#xff0c;包括使用状态管理工具&#xff08;如 Pinia&#xff09;、Vue 的 provide/inject 机制以及传统的 props 传递。本文将详细介绍这三种方法&#xff0c;并通过一个…

Java ArrayList 扩容机制

一、ArrayList 简介 ArrayList 是 Java 集合框架中基于数组实现的可变长度列表&#xff0c;其核心特性是&#xff1a; 支持随机访问&#xff08;通过索引&#xff09;支持动态扩容插入/删除效率较低&#xff08;非尾部操作&#xff09; 二、底层数据结构 // JDK 11 transien…

C++面试题精讲系列之数组排序

数组排序是我们经常遇到的笔试题目&#xff0c;给大家盘一下这题到底想考察什么&#xff1f; // 考题如下 void main() {int arr[4] {26,28,24,11};// 请实现一个sortArray函数&#xff0c;对数组arr进行从小到大排序 }考点1&#xff1a;数组做函数参数如何传递参&#xff1f;…

Windows10/11 轻度优化 纯净版,12个版本!

系统介绍 镜像包均基于微软官方原版系统精心制作&#xff0c;确保系统的原汁原味与稳定性。Windows 10/11&#xff0c;都集成了最新的补丁。版本选对&#xff0c;一键安装到位&#xff0c;全自动无人值守安装模式。 系统特点 系统进行优化提供了12个系统版本集成了运行库、…

开发工具IDEA

开发工具IDEA 开发调试&#xff08;debug&#xff09;Maven配置三级目录 开发调试&#xff08;debug&#xff09; 史上最全的 IDEA Debug 调试技巧&#xff08;超详细案例&#xff09; Maven配置 idea全局Maven配置 IDEA中Maven配置详解 有些时候不要配置maven_home这些环境…

GitHub Actions与AWS OIDC实现安全的ECR/ECS自动化部署

引言 在现代云原生应用开发中,实现安全、高效的CI/CD流程至关重要。本文将详细介绍如何利用GitHub Actions和AWS OIDC(OpenID Connect)构建一个无需长期凭证的安全部署管道,将容器化应用自动部署到Amazon ECR和ECS服务。 架构概述 整个解决方案的架构包含三个主要部分:…

一、MongoDB安装-二进制安装

下载tar包 wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-7.0.21.tgz wget https://downloads.mongodb.com/compass/mongosh-2.5.3-linux-x64.tgz安装 解压 tar xf mongodb-linux-x86_64-rhel70-7.0.21.tgz cp mongodb-linux-x86_64-rhel70-7.0.21/bi…

学习日志03 ETF 基础数据可视化分析与简易管理系统

1 代码的选择和改进 import pandas as pd import matplotlib.pyplot as plt import seaborn as sns from ipywidgets import (AppLayout, Dropdown, Button, Output, VBox, HBox, Label, Layout, SelectMultiple,IntSlider, FloatSlider, Checkbox, Text, Select) from IPytho…