QImage、cv::Mat 与 HalconCpp::HObject 之间的转换

在机器视觉应用中,不同的图像处理库和框架常使用不同的数据结构来表示图像。常用的库包括 Qt 的 QImage、OpenCV 的 cv::Mat 以及 Halcon 的 HObject。为了在这些库之间实现无缝的数据传递和处理,图像格式的转换成为必不可少的环节。本文将详细介绍如何在 QImagecv::MatHalconCpp::HObject 之间进行相互转换,并提供相应的代码实现。

1. QImage 到 cv::Mat 的转换

QImage 是 Qt 框架中表示图像的类,它支持多种格式(如 RGB32、RGB888、灰度等)。为了将 QImage 转换为 OpenCV 的 cv::Mat,需要根据 QImage 的格式构建不同类型的 cv::Mat。代码如下:

cv::Mat QImageToMat(const QImage& image) {switch (image.format()) {case QImage::Format_RGB32: {// 对于 Format_RGB32 格式,QImage 是 RGBA 格式,4 通道cv::Mat mat(image.height(), image.width(), CV_8UC4, const_cast<uchar*>(image.bits()), image.bytesPerLine());return mat.clone();  // 需要深拷贝,防止指针问题}case QImage::Format_RGB888: {// 对于 RGB888 格式,QImage 是 RGB 格式,3 通道cv::Mat mat(image.height(), image.width(), CV_8UC3, const_cast<uchar*>(image.bits()), image.bytesPerLine());return mat.clone();  // 深拷贝}case QImage::Format_Grayscale8: {// 对于 Grayscale8 格式,QImage 是灰度图,1 通道cv::Mat mat(image.height(), image.width(), CV_8UC1, const_cast<uchar*>(image.bits()), image.bytesPerLine());return mat.clone();  // 深拷贝}default:// 如果遇到不支持的格式,输出警告信息qWarning() << "不支持的 QImage 格式!";return cv::Mat();}
}

这段代码通过检测 QImage 的格式,将其正确地转换为相应的 cv::Mat 格式,并进行深拷贝以防止指针问题。

2. cv::Mat 到 QImage 的转换

在很多情况下,OpenCV 的 cv::Mat 是图像处理的核心数据结构。如果需要将 cv::Mat 转换为 QImage,则需要处理不同的通道数(如单通道灰度图、三通道 BGR 图像、四通道 RGBA 图像等)。以下是转换实现:

QImage MatToQImage(const cv::Mat& mat) {switch (mat.type()) {case CV_8UC1: {// 单通道灰度图return QImage(mat.data, mat.cols, mat.rows, mat.step, QImage::Format_Grayscale8).copy();  // 深拷贝}case CV_8UC3: {// 三通道彩色图像,OpenCV 默认是 BGR 格式,需要转换为 RGBreturn QImage(mat.data, mat.cols, mat.rows, mat.step, QImage::Format_RGB888).rgbSwapped().copy();  // 深拷贝}case CV_8UC4: {// 四通道 RGBA 图像return QImage(mat.data, mat.cols, mat.rows, mat.step, QImage::Format_ARGB32).copy();  // 深拷贝}default:qWarning() << "不支持的 cv::Mat 格式!";return QImage();}
}

在这段代码中,如果 cv::Mat 是三通道的 BGR 格式,必须先转换为 RGB 格式。深拷贝是为了避免数据被意外修改或释放。

3. cv::Mat 到 HalconCpp::HObject 的转换

Halcon 是工业机器视觉中广泛使用的库,其 HObject 是处理图像的基础数据结构。将 cv::Mat 转换为 HObject 时,需要分别处理单通道灰度图和三通道彩色图(需要从 BGR 转换为 RGB)。代码如下:

HalconCpp::HObject MatToHObject(const cv::Mat& mat) {HalconCpp::HObject hImage;if (mat.type() == CV_8UC1) {// 单通道灰度图像HalconCpp::GenImage1(&hImage, "byte", mat.cols, mat.rows, (Hlong)mat.data);} else if (mat.type() == CV_8UC3) {// 三通道彩色图像,OpenCV 中是 BGR 格式,需转换为 RGB 格式cv::Mat rgbMat;cv::cvtColor(mat, rgbMat, cv::COLOR_BGR2RGB);HalconCpp::GenImageInterleaved(&hImage, (Hlong)rgbMat.data, "rgb", rgbMat.cols, rgbMat.rows, -1, "byte", 0, 0, 0, 0, -1, 0);} else {qWarning() << "不支持的 cv::Mat 格式转换为 HalconCpp::HObject!";}return hImage;
}

通过此方法,我们可以将 OpenCV 的 cv::Mat 格式转化为 Halcon 的 HObject,并且保证彩色图像的通道顺序正确。

4. HalconCpp::HObject 到 cv::Mat 的转换

HObject 转换为 cv::Mat 也涉及到通道数的处理。以下是相应的代码:

cv::Mat HObjectToMat(const HalconCpp::HObject& hImage) {HTuple hChannels;HalconCpp::CountChannels(hImage, &hChannels);if (hChannels[0].I() == 1) {HTuple hWidth, hHeight;HalconCpp::GetImageSize(hImage, &hWidth, &hHeight);cv::Mat mat(hHeight.I(), hWidth.I(), CV_8UC1);HalconCpp::GetImagePointer1(hImage, nullptr, nullptr, &hWidth, &hHeight);memcpy(mat.data, (void*)hImage.GetDataPointer(), mat.total());return mat;} else if (hChannels[0].I() == 3) {HTuple hWidth, hHeight;HalconCpp::GetImageSize(hImage, &hWidth, &hHeight);cv::Mat mat(hHeight.I(), hWidth.I(), CV_8UC3);HalconCpp::GetImagePointer3(hImage, nullptr, nullptr, nullptr, &hWidth, &hHeight);memcpy(mat.data, (void*)hImage.GetDataPointer(), mat.total() * 3);cv::cvtColor(mat, mat, cv::COLOR_RGB2BGR);return mat;} else {qWarning() << "不支持的 HObject 格式转换为 cv::Mat!";return cv::Mat();}
}

此方法通过 Halcon 提供的 API 获取图像的指针,并将数据复制到 cv::Mat 对象中。对于彩色图像,需要将 RGB 格式转换为 OpenCV 的 BGR 格式。

结论

本文介绍了如何在 Qt 的 QImage、OpenCV 的 cv::Mat 和 Halcon 的 HObject 之间进行相互转换,这在图像处理和机器视觉应用中尤为重要。通过这些转换方法,不同库之间的图像处理功能可以被集成到同一个应用程序中,从而实现更强大的图像处理能力。

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

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

相关文章

再次进阶 舞台王者 第八季完美童模全球赛形象大使【许雅雯】赛场秀场超燃合集!

7月20-23日&#xff0c;2024第八季完美童模全球总决赛在青岛圆满落幕。在盛大的颁奖典礼上&#xff0c;一位才能出众的少女——许雅雯&#xff0c;迎来了她舞台生涯的璀璨时刻。 形象大使——许雅雯&#xff0c;以璀璨童星之姿&#xff0c;优雅地踏上完美童模盛宴的绚丽舞台&am…

玉米种子质量检测系统源码分享

玉米种子质量检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer…

掌握“问一问”策略,视频号流量轻松实现质的飞跃!

掌握“问一问”策略&#xff0c;视频号流量轻松实现质的飞跃&#xff01; 视频号新流量入口&#xff0c;微信问一问。如何玩转问一问功能&#xff0c;手把手操作教学。#视频号#微信#问一问#短视频#直播 市面上还有这么牛逼的一个流量隐藏入口&#xff0c;先看一下数据&#x…

微信自动回复设置真嘎嘎好用!

无论是商户、个人品牌还是普通用户&#xff0c;及时回应朋友和客户的信息至关重要。然而&#xff0c;手动一一回复既耗时又容易遗漏&#xff0c;这时&#xff0c;微信的自动回复功能就显得尤为重要。 今天&#xff0c;就教大家一招——通过个微管理系统&#xff0c;实现微信自…

2024年最新软件测试学习路线图(从入门到精通)

六维全息课程注重综合能力培养&#xff0c;从入学到职后一站式服务测试开发人才。2024年最新软件测试学习路线图&#xff0c;从入门到精通一应俱全。 9阶段专业课11大专项测试项目 适应互联网企业测试开发需求。 对于想入行学软件测试的新手来说&#xff0c;首先就需要一个高效…

如何用Docker运行Django项目

本章教程,介绍如何用Docker创建一个Django,并运行能够访问。 一、拉取镜像 这里我们使用python3.11版本的docker镜像 docker pull python:3.11二、运行容器 这里我们将容器内部的8080端口,映射到宿主机的80端口上。 docker run -itd --name python311 -p

在pycharm终端中运行pip命令安装模块时,出现了“你要如何打开这个文件”弹出窗口,是什么状况?

这种情况发生在Windows系统上&#xff0c;当在PyCharm终端中运行pip命令安装模块时&#xff0c;如果系统无法确定要使用哪个程序打开该文件&#xff0c;就会出现“你要如何打开这个文件”弹出窗口。 解决方法是&#xff1a; 选择“查找一个应用于此文件”的选项。在弹出的窗口…

Java语法1

注释 单行注释// 多行/* */ 字面量 同C \n \t不需要加单引号 数据的存储 十进制转二进制 除2取余法 数据在计算机中的最小存储单位字节1B8b KB MB GB TB 相邻的转换 2的10次方等于1024 字符存进去则存ASSIC编码对应的数,比如49对应’1’,65对应’A’,97对应’a’ 图片,声音…

电脑录屏不求人,9月必备免费录屏软件推荐!苹果电脑可用!

在当今这个信息爆炸的时代&#xff0c;电脑录屏软件已经成为了我们日常工作和生活中不可或缺的工具。无论是制作教学视频、录制在线课程、游戏直播&#xff0c;还是创建产品演示&#xff0c;一个好的录屏软件都能帮助我们更高效地完成任务。市场上的录屏软件琳琅满目&#xff0…

Kubernetes精讲之网络通信与调度

目录 一 k8s网络通信 1.1 k8s通信整体架构 1.2 flannel网络插件 1.2.1 flannel跨主机通信原理 1.2.2 flannel支持的后端模式 1.3 calico网络插件 1.3.1 calico简介&#xff1a; 1.3.2 calico网络架构 1.3.3 部署calico 二 k8s调度&#xff08;Scheduling&#xff09;…

yarn运行机制原理

1.客户端将任务提交给resourceManager 2.resourceManager接受任务请求 3.resourceManager在nodeManager上寻找一个比较空闲的节点&#xff0c; 通知启动一个appMaster&#xff0c;将任务信息发送给appMaster 等待appMaster启动成功 如果启动失败&#xff0c;认为当前任务直接报…

鱼类检测-目标检测数据集(包括VOC格式、YOLO格式)

鱼类检测-目标检测数据集&#xff08;包括VOC格式、YOLO格式&#xff09; 数据集&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1B4o8IgOmAWeQJDWpJWxqXg?pwdjaco 提取码&#xff1a;jaco 数据集信息介绍&#xff1a; 共有 2848 张图像和一一对应的标注文件 标注文…

Fake Location模拟定位,刷跑 “运动世界校园”

前言:"科技改变生活&#xff0c;如果本文章对你有帮助&#xff0c;别忘记留下你的点赞&#xff0c;以下我对环境特变刁钻的运动世界校园为实例&#xff0c;也是成功安全正常上传数据&#xff0c;如果遇到问题&#xff0c;请留言评论区&#xff0c;所有链接我会放在文章头部…

二叉树进阶——二叉搜索树

关于二叉树的基本概念与内容作者在之前的数据结果初阶系列均有讲解&#xff0c;需要的小伙伴可以去作者的往期博客里查看。本篇内容算是对二叉树内容部分的收尾。 一、什么是二叉搜索树 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树&#xff0c;或者是具有以下性质…

How to implement custom environment in keras-rl / OpenAI GYM?

题意&#xff1a;如何在 Keras-RL / OpenAI GYM 中实现自定义环境&#xff1f; 问题背景&#xff1a; Im a complete newbie to Reinforcement Learning and have been searching for a framework/module to easily navigate this treacherous terrain. In my search Ive come…

axure判断

在auxre中我们也可以实现判断的功能&#xff0c;当目标等于什么内容时则执行下方的功能。 一、判断输入框中是否有值 画布添加一个输入框、一个文本标签删除其中内容&#xff0c;添加一个按钮&#xff0c;输入框命名为【文本显示】文本标签命名为【提示】 给按钮新增一个交互…

缓存预热/雪崩/穿透/击穿

1. 缓存预热 预先将MySQL中的数据同步至Redis的过程 2. 缓存雪崩 Redis主机出现故障&#xff0c;或有大量的key同时过期大面积失效导致Redis不可用 Redis中key设置为永不过期&#xff0c;或者过期时间错开Redis缓存集群实现高可用多缓存结合预防雪崩服务降级 3. 缓存穿透 …

消息队列面试

一、基础实战 &#xff08;一&#xff09;MQ的作用&#xff1a;异步、解耦、流量削峰填谷 &#xff08;二&#xff09;MQ应用场景 传统的金融项目一般使用IBMMQ&#xff08;收费&#xff09;&#xff0c;比如某丰银行项目。ActiveMQ已经成为历史&#xff0c;因为现在很少使用…

Redis 篇-深入了解基于 Redis 实现消息队列(比较基于 List 实现消息队列、基于 PubSub 发布订阅模型之间的区别)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 消息队列的认识 2.0 基于 List 实现消息队列 2.1 基于 List 实现消息队列的优缺点 3.0 基于 PubSub 实现消息队列 3.1 基于 PubSub 的消息队列优缺点 4.0 基于 St…

Unity数据持久化 之 使用Excel.DLL读写Excel表格

本文仅作笔记学习和分享&#xff0c;不用做任何商业用途 本文包括但不限于unity官方手册&#xff0c;unity唐老狮等教程知识&#xff0c;如有不足还请斧正​​ 终于找到一个比较方便容易读表的方式了&#xff0c;以前用json读写excel转的cvs格式文件我怎么使用怎么别扭&#xf…