使用 Qt 实现基于海康相机的图像采集和显示系统(不使用外部视觉库,如Halcon\OpenCv)[工程源码联系博主索要]

本文将梳理一个不借助外部视觉库(如 OpenCV/Halcon)的海康相机图像采集和显示 Demo。该程序直接使用 Qt GUI 来显示图像。通过海康 MVS SDK 实现相机的连接、参数设置、图像采集和异常处理等功能,并通过 Qt 界面展示操作结果。


在这里插入图片描述

1. 功能概述

该程序通过 Qt 的 GUI 作为界面,通过海康 MVS SDK 控制相机并显示实时图像。主要功能包括:

  • 相机连接和设置
  • 参数调整(如曝光时间和触发模式)
  • 图像采集与显示
  • 异常处理(如设备断开)

2. 初始化与 GUI 设置

MainWindow 的构造函数中进行界面初始化,包括设置按钮的可见性、启用状态等。 initStyle() 函数用于加载并应用界面的样式表。

MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow) {ui->setupUi(this);initStyle();// 设置初始 UI 状态ui->btn_Start->setEnabled(false);ui->btn_Stop->setEnabled(false);ui->btn_close->setEnabled(false);ui->btn_Grab->setVisible(false);ui->groupBox->setEnabled(false);
}

3. 相机连接与操作

3.1 枚举和连接相机

通过点击“搜索相机”按钮,程序调用 MV_CC_EnumDevices 枚举连接的相机设备,将可用的相机序列号显示在列表中供用户选择。

void MainWindow::on_btnSeachCamera_clicked() {ui->listWidget->clear();int nRet = MV_OK;bool isGige = ui->radioGIGE->isChecked();// 枚举连接的相机if (isGige) {nRet = MV_CC_EnumDevices(MV_GIGE_DEVICE, &cameraList);} else {nRet = MV_CC_EnumDevices(MV_USB_DEVICE, &cameraList);}if (nRet != MV_OK || cameraList.nDeviceNum == 0) {setLastErrorMsg(tc("未找到任何可用相机, 错误码: %1").arg(nRet));return;}// 添加相机序列号到列表中for (int i = 0; i < cameraList.nDeviceNum; i++) {const char *serial = isGige? reinterpret_cast<char *>(cameraList.pDeviceInfo[i]->SpecialInfo.stGigEInfo.chSerialNumber): reinterpret_cast<char *>(cameraList.pDeviceInfo[i]->SpecialInfo.stUsb3VInfo.chSerialNumber);ui->listWidget->addItem(serial);}
}
3.2 相机连接及初始化

点击“连接相机”按钮后,程序通过创建相机句柄并打开设备。设置默认曝光时间和注册图像采集、异常处理回调函数。

void MainWindow::on_btnconnect_clicked() {MV_CC_DEVICE_INFO cameraInfo;int nRet = MV_OK;// 创建句柄并打开相机memcpy(&cameraInfo, cameraList.pDeviceInfo[0], sizeof(MV_CC_DEVICE_INFO));if ((nRet = MV_CC_CreateHandle(&m_handle, &cameraInfo)) != MV_OK) {setLastErrorMsg(tc("相机初始化失败, 错误码: %1").arg(nRet));return;}if ((nRet = MV_CC_OpenDevice(m_handle, MV_ACCESS_Exclusive)) != MV_OK) {setLastErrorMsg(tc("相机打开失败, 错误码: %1").arg(nRet));return;}// 设置曝光时间并注册回调函数MV_CC_SetExposureTime(m_handle, ui->spinBox->value());MV_CC_RegisterImageCallBackEx(m_handle, ImageCallBack, this);MV_CC_RegisterExceptionCallBack(m_handle, ExceptionCallBack, this);// 更新 UI 状态ui->btn_Start->setEnabled(true);ui->btn_Stop->setEnabled(true);ui->btn_close->setEnabled(true);ui->btnconnect->setEnabled(false);ui->groupBox->setEnabled(true);
}

4. 图像采集与显示

4.1 图像采集回调

通过注册图像回调函数 ImageCallBack,将采集到的图像数据转换为 QImage 格式,以便在 Qt 的 QLabel 中显示。

void ImageCallBack(unsigned char *pData, MV_FRAME_OUT_INFO_EX *pFrameInfo, void *pUser) {MainWindow *camera = static_cast<MainWindow *>(pUser);QImage img;switch (pFrameInfo->enPixelType) {case PixelType_Gvsp_Mono8:// 单通道灰度图像转换img = QImage(pData, pFrameInfo->nWidth, pFrameInfo->nHeight, pFrameInfo->nWidth, QImage::Format_Grayscale8);break;case PixelType_Gvsp_RGB8_Packed:// RGB8 数据转换img = QImage(pData, pFrameInfo->nWidth, pFrameInfo->nHeight, QImage::Format_RGB888);break;case PixelType_Gvsp_BayerRG8:case PixelType_Gvsp_BayerBG8:// Bayer 格式转换img = QImage(pFrameInfo->nWidth, pFrameInfo->nHeight, QImage::Format_RGB888);for (int y = 0; y < pFrameInfo->nHeight - 1; y++) {for (int x = 0; x < pFrameInfo->nWidth - 1; x++) {int index = y * pFrameInfo->nWidth + x;uchar r, g, b;if (pFrameInfo->enPixelType == PixelType_Gvsp_BayerRG8) {r = pData[index];g = (pData[index + 1] + pData[index + pFrameInfo->nWidth]) / 2;b = pData[index + pFrameInfo->nWidth + 1];} else {b = pData[index];g = (pData[index + 1] + pData[index + pFrameInfo->nWidth]) / 2;r = pData[index + pFrameInfo->nWidth + 1];}img.setPixel(x, y, qRgb(r, g, b));}}break;default:qWarning("Unsupported pixel type");return;}// 显示图像camera->detect(img);
}void MainWindow::detect(const QImage &image) {ui->lab_image->setPixmap(QPixmap::fromImage(image).scaled(ui->lab_image->size()));
}
4.2 触发模式和曝光时间调整

根据用户选择的触发模式和曝光时间设置相机参数。Qt 的信号和槽机制使得切换触发模式和调整曝光时间变得直观。

void MainWindow::on_comboBox_activated(int index) {int nRet = MV_OK;switch (index) {case OpenContinue:nRet = MV_CC_SetEnumValue(m_handle, "TriggerMode", 0);break;case OpenSoftWare:nRet = MV_CC_SetEnumValue(m_handle, "TriggerMode", 1);nRet = MV_CC_SetEnumValue(m_handle, "TriggerSource", 7);break;case OpenHardWare:nRet = MV_CC_SetEnumValue(m_handle, "TriggerMode", 1);nRet = MV_CC_SetEnumValue(m_handle, "TriggerSource", 0);break;}if (nRet != MV_OK) setLastErrorMsg(tc("设置触发模式失败, 错误码: %1").arg(nRet));
}

5. 异常处理与资源释放

5.1 异常处理

程序注册了异常回调函数 ExceptionCallBack,用于处理如设备断开连接等异常情况,并将错误信息显示在界面上。

void ExceptionCallBack(unsigned int nMsgType, void *pUser) {if (nMsgType == MV_EXCEPTION_DEV_DISCONNECT) {MainWindow *camera = static_cast<MainWindow *>(pUser);camera->setLastErrorMsg(tc("相机连接断开"));}
}
5.2 资源释放

程序退出时,调用相机停止、关闭函数,释放资源以避免内存泄漏。

void MainWindow::on_btn_close_clicked() {on_btn_Stop_clicked();int nRet = MV_CC_CloseDevice(m_handle);if (nRet != MV_OK) {setLastErrorMsg(tc("关闭相机失败, 错误码: %1").arg(nRet));}
}

6. 总结

本代码实现了

基于 Qt 的海康相机图像采集和显示系统,直接通过 MVS SDK 进行图像数据处理和显示。Qt 的信号槽机制、MVS SDK 的相机控制 API,以及图像格式转换,使得整个系统操作简单高效。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/886499.shtml

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

相关文章

在Ubuntu22.04上源码构建ROS noetic环境

Ubuntu22.04上源码构建ROS noetic 起因准备环境创建工作目录并下载源码安装编译依赖包安装ros_comm和rosconsole包的两个补丁并修改pluginlib包的CMakeLists的编译器版本编译安装ROS noetic和ros_test验证 起因 最近在研究VINS-Mono从ROS移植到ROS2&#xff0c;发现在编写feat…

C++——类和对象(part2)

前言 本篇博客继续为大家介绍类与对象的知识&#xff0c;承接part1的内容&#xff0c;本篇内容是类与对象的核心内容&#xff0c;稍微有些复杂&#xff0c;如果你对其感兴趣&#xff0c;请继续阅读&#xff0c;下面进入正文部分。 1. 类的默认成员函数 默认成员函数就是用户…

matlab实现主成分分析方法图像压缩和传输重建

原创 风一样的航哥 航哥小站 2024年11月12日 15:23 江苏 为了研究图像的渐进式传输技术&#xff0c;前文提到过小波变换&#xff0c;但是发现小波变换非常适合传输缩略图&#xff0c;实现渐进式传输每次传输的数据量不一样&#xff0c;这是因为每次变换之后低频成分大约是上一…

【HarmonyOS】鸿蒙系统在租房项目中的项目实战(二)

从今天开始&#xff0c;博主将开设一门新的专栏用来讲解市面上比较热门的技术 “鸿蒙开发”&#xff0c;对于刚接触这项技术的小伙伴在学习鸿蒙开发之前&#xff0c;有必要先了解一下鸿蒙&#xff0c;从你的角度来讲&#xff0c;你认为什么是鸿蒙呢&#xff1f;它出现的意义又是…

Scala-字符串(拼接、printf格式化输出等)-用法详解

Scala 一、 使用 号连接字符串 在 Scala 中&#xff0c; 运算符实际上会调用 String 类的 concat 方法或者使用字符串的加法操作&#xff0c;生成一个新的字符串。 字符串是不可变的&#xff0c;每次拼接都会创建一个新的字符串。 Mr. yuTips&#xff1a; 性能相对较差&…

ISCTF2024

ezlogin 源码审计 先审源码,纯js题 const express require(express); const app express(); const bodyParser require(body-parser); var cookieParser require(cookie-parser); var serialize require(node-serialize); app.use(bodyParser.urlencoded({ e…

使用真实 Elasticsearch 进行更快的集成测试

作者&#xff1a;来自 Elastic Piotr Przybyl 了解如何使用各种数据初始化和性能改进技术加快 Elasticsearch 的自动化集成测试速度。 在本系列的第 1 部分中&#xff0c;我们探讨了如何编写集成测试&#xff0c;让我们能够在真实的 Elasticsearch 环境中测试软件&#xff0c;并…

MySQL:联合查询(2)

首先写一个三个表的联合查询 查询所有同学的每门课成绩&#xff0c;及同学的个人信息 1.我们首先要确定使用哪些表 学生表&#xff0c;课程表&#xff0c;成绩表 2.取笛卡尔积 select * from score,student,course; 3. 确定表与表之间的联合条件 select * from score,stud…

Vue3学习笔记(下)

文章目录 Vue3学习笔记&#xff08;下&#xff09;组合式API下的父子通信父传子子传父 模板引用defineExpose()provide和injectvue3新特性 - defineOptionsvue3新特性 - defineModelPiniaPinia异步写法 Vue3学习笔记&#xff08;下&#xff09; 组合式API下的父子通信 父传子…

CNN神经网络

CNN 一 基本概述二 基础知识三 经典案例 今天和大家聊聊人工智能中的神经网络模型相关内容。神经网络内容庞大,篇幅有限本文主要讲述其中的CNN神经网络模型和一些基本的神经网络概念。 一 基本概述 深度学习(Deep Learning)特指基于深层神经网络模型和方法的机器学习。它是在…

MySQL —— MySQL基础概念与常用功能介绍

文章目录 基本概念数据类型数据类型分类 约束主键约束&#xff08;PRIMARY KEY&#xff09;外键约束&#xff08;FOREIGN KEY&#xff09;使用非空约束&#xff08;not null&#xff09;使用唯一性约束&#xff08;UNIQUE&#xff09;使用默认约束&#xff08;DEFAULT&#xff…

如何在react中使用react-monaco-editor渲染出一个编辑器

一、效果展示 二、基于vite配置 1.首先安装react-monaco-editor和monaco-editor包 npm add react-monaco-editor npm i monaco-editor 2.其次创建一个单独的文件&#xff08;此处是tsx、直接用app或者jsx也行&#xff09; import { useState, useEffect } from react impo…

MySQL面试之底层架构与库表设计

华子目录 mysql的底层架构客户端连接服务端连接的本质&#xff0c;连接用完会立马丢弃吗解析器和优化器的作用sql执行前会发生什么客户端的连接池和服务端的连接池数据库的三范式 mysql的底层架构 客户端连接服务端 连接的本质&#xff0c;连接用完会立马丢弃吗 解析器和优化器…

【开源免费】基于Vue和SpringBoot的私人健身与教练预约管理系统(附论文)

本文项目编号 T 618 &#xff0c;文末自助获取源码 \color{red}{T618&#xff0c;文末自助获取源码} T618&#xff0c;文末自助获取源码 随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息…

JVM--内存结构

目录 1. PC Register&#xff08;程序计数器&#xff09; 1.1 定义 1.2 工作原理 1.3 特点 1.4 应用 2.虚拟机栈 2.1定义与特性 2.2内存模型 2.3工作原理 2.4异常处理 2.5应用场景 2.6 Slot 复用 2.7 动态链接详解 1. 栈帧与动态链接 动态链接的作用&#xff1a…

手机直连卫星NTN通信初步研究

目录 1、手机直连卫星之序幕 2、卫星NTN及其网络架构 2.1 NTN 2.2 NTN网络架构 3、NTN的3GPP标准化进程 3.1 NTN需要适应的特性 3.2 NTN频段 3.3 NTN的3GPP标准化进程概况 3.4 NTN的3GPP标准化进程的详情 3.4.1 NR-NTN 3.4.1.1 NTN 的无线相关 SI/WI 3.4.1.2…

【SpringBoot】什么是Maven,以及如何配置国内源实现自动获取jar包

前言 &#x1f31f;&#x1f31f;本期讲解关于Maven的了解和如何进行国内源的配置~~~ &#x1f308;感兴趣的小伙伴看一看小编主页&#xff1a;GGBondlctrl-CSDN博客 &#x1f525; 你的点赞就是小编不断更新的最大动力 &#x1f3…

阿里斑马智行 2025届秋招 NLP算法工程师

文章目录 个人情况一面/技术面 1h二面/技术面 1h三面/HR面 20min 个人情况 先说一下个人情况&#xff1a; 学校情况&#xff1a;211本中9硕&#xff0c;本硕学校都一般&#xff0c;本硕都是计算机科班&#xff0c;但研究方向并不是NLP&#xff0c;而是图表示学习论文情况&…

富士施乐DocuContre S2520报打开盖子A,取出纸张。代码077-900故障检修

故障描述: 一台富士施乐DocuContre S2520复印机开机报错:打开盖子A,取出纸张。代码077-900故障,用户之前经常卡纸,卡着、卡着就一直提示打开盖子A,取出纸张了;复印机屏幕提示如下图: 故障检修: 富士施乐DocuContre S2520复印机报打开盖子A,取出纸张。077-900的错误代…

【Ubuntu24.04】VirtualBox安装ubuntu-live-server24.04

目录 0 背景1 下载镜像2 安装虚拟机3 安装UbuntuServer24.044 配置基本环境5 总结0 背景 有了远程连接工具之后,似乎作为服务器的Ubuntu24.04桌面版有点备受冷落了,桌面版的Ubuntu24.04的优势是图形化桌面,是作为一个日常工作的系统来用的,就像Windows,如果要作为服务器来…