OpenCV种的cv::Mat与Qt种的QImage类型相互转换

news2025/7/22 22:18:58

一、首先了解cv::Mat结构体

cv::Mat::step与QImage转换有着较大的关系。

step的几个类别区分:

  • step:矩阵第一行元素的字节数
  • step[0]:矩阵第一行元素的字节数
  • step[1]:矩阵中一个元素的字节数
  • step1(0):矩阵中一行有几个通道数
  • step1(1):一个元素有几个通道数(channel())
    cv::Mat cvmat(3, 4, CV_16UC4, cv::Scalar_<uchar>(1, 2, 3, 4));

    std::cout << cvmat<< std::endl;
    std::cout << "step:" << cvmat.step << std::endl;
    std::cout << "step[0]:" << cvmat.step[0] << std::endl;
    std::cout << "step[1]:" << cvmat.step[1] << std::endl;
    std::cout << "step1(0):" << cvmat.step1(0) << std::endl;
    std::cout << "step1(1):" << cvmat.step1(1) << std::endl;

运行结果:

分析:
创建了一个3∗4的16位4通道的矩阵;

每一个元素赋值为1,2,3,4;可以看到生成了3*4*4的矩阵;

因为创建的是16位的,所以每一个通道是2个字节数;

所以一行共有4*4*2=32个字节数,故step和step[0]都为32;

因为一个元素有4个通道,每个通道2个字节,所以1个元素的字节数step[1]为4*2=8;

一行是4个元素,每个元素是4个通道,所以一行的通道数,step1(0)为4*4=16,step1(1)为4;

二、cv::Mat转QImage

代码示例为拷贝转换:

QImage cvMat2QImage(const cv::Mat& mat) 
{
    if (mat.empty())
    {
        return QImage();
    }
    QImage image;
    switch (mat.type())
    {
    case CV_8UC1:
    {
        image = QImage((const uchar*)(mat.data),
            mat.cols, mat.rows, mat.step,
            QImage::Format_Grayscale8);
        return image.copy();
    }
    case CV_8UC2:
    {
        mat.convertTo(mat, CV_8UC1);
        image = QImage((const uchar*)(mat.data),
            mat.cols, mat.rows, mat.step,
            QImage::Format_Grayscale8);
        return image.copy();
    }
    case CV_8UC3:
    {
        // Copy input Mat
        const uchar *pSrc = (const uchar*)mat.data;
        // Create QImage with same dimensions as input Mat
        QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);
        return image.rgbSwapped();
    }
    case CV_8UC4:
    {
        // Copy input Mat
        const uchar *pSrc = (const uchar*)mat.data;
        // Create QImage with same dimensions as input Mat
        QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_ARGB32);
        return image.copy();
    }
    case CV_32FC1:
    {
        Mat normalize_mat;
        normalize(mat, normalize_mat, 0, 255, NORM_MINMAX, -1);
        normalize_mat.convertTo(normalize_mat, CV_8U);
        const uchar *pSrc = (const uchar*)normalize_mat.data;
        QImage image(pSrc, normalize_mat.cols, normalize_mat.rows, normalize_mat.step, QImage::Format_Grayscale8);
        return image.copy();
    }
    case CV_32FC3:
    {
        Mat normalize_mat;
        normalize(mat, normalize_mat, 0, 255, NORM_MINMAX,-1);
        normalize_mat.convertTo(normalize_mat, CV_8U);
        const uchar *pSrc = (const uchar*)normalize_mat.data;
        // Create QImage with same dimensions as input Mat
        QImage image(pSrc, normalize_mat.cols, normalize_mat.rows, normalize_mat.step, QImage::Format_RGB888);
        return image.rgbSwapped();
    }
    case CV_64FC1:
    {
        Mat normalize_mat;
        normalize(mat, normalize_mat, 0, 255, NORM_MINMAX, -1);
        normalize_mat.convertTo(normalize_mat, CV_8U);
        const uchar *pSrc = (const uchar*)normalize_mat.data;
        QImage image(pSrc, normalize_mat.cols, normalize_mat.rows, normalize_mat.step, QImage::Format_Grayscale8);
        return image.copy();
    }
    case CV_64FC3:
    {
        Mat normalize_mat;
        normalize(mat, normalize_mat, 0, 255, NORM_MINMAX, -1);
        normalize_mat.convertTo(normalize_mat, CV_8U);
        const uchar *pSrc = (const uchar*)normalize_mat.data;
        // Create QImage with same dimensions as input Mat
        QImage image(pSrc, normalize_mat.cols, normalize_mat.rows, normalize_mat.step, QImage::Format_RGB888);
        return image.rgbSwapped();
    }
    case CV_32SC1:
    {
        Mat normalize_mat;
        normalize(mat, normalize_mat, 0, 255, NORM_MINMAX, -1);
        normalize_mat.convertTo(normalize_mat, CV_8U);
        const uchar *pSrc = (const uchar*)normalize_mat.data;
        QImage image(pSrc, normalize_mat.cols, normalize_mat.rows, normalize_mat.step, QImage::Format_Grayscale8);
        return image.copy();
    }
    case CV_32SC3:
    {
        Mat normalize_mat;
        normalize(mat, normalize_mat, 0, 255, NORM_MINMAX, -1);
        normalize_mat.convertTo(normalize_mat, CV_8U);
        const uchar *pSrc = (const uchar*)normalize_mat.data;
        // Create QImage with same dimensions as input Mat
        QImage image(pSrc, normalize_mat.cols, normalize_mat.rows, normalize_mat.step, QImage::Format_RGB888);
        return image.rgbSwapped();
    }
    case CV_16SC1:
    {
        Mat normalize_mat;
        normalize(mat, normalize_mat, 0, 255, NORM_MINMAX, -1);
        normalize_mat.convertTo(normalize_mat, CV_8U);
        const uchar *pSrc = (const uchar*)normalize_mat.data;
        QImage image(pSrc, normalize_mat.cols, normalize_mat.rows, normalize_mat.step, QImage::Format_Grayscale8);
        return image.copy();
    }
    case CV_16SC3:
    {
        Mat normalize_mat;
        normalize(mat, normalize_mat, 0, 255, NORM_MINMAX, -1);
        normalize_mat.convertTo(normalize_mat, CV_8U);
        const uchar *pSrc = (const uchar*)normalize_mat.data;
        // Create QImage with same dimensions as input Mat
        QImage image(pSrc, normalize_mat.cols, normalize_mat.rows, normalize_mat.step, QImage::Format_RGB888);
        return image.rgbSwapped();
    }
    case CV_8SC1:
    {
        //Mat normalize_mat;
        //normalize(mat, normalize_mat, 0, 255, NORM_MINMAX, -1);
        mat.convertTo(mat, CV_8U);
        const uchar *pSrc = (const uchar*)mat.data;
        QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_Grayscale8);
        return image.copy();
    }
    case CV_8SC3:
    {
        mat.convertTo(mat, CV_8U);
        const uchar *pSrc = (const uchar*)mat.data;
        QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);
        return image.rgbSwapped();
    }
    default:
        mat.convertTo(mat, CV_8UC3);
        QImage image((const uchar*)mat.data, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);
        return image.rgbSwapped();
        return QImage();
        break;
    }
}

三、QImage转cv::Mat

示例代码为共享内存转换:

cv::Mat QImage2cvMat(QImage& image)
{
    cv::Mat mat;
    //qDebug() << image.format();
    switch (image.format())
    {
    case QImage::Format_ARGB32:
        mat = cv::Mat(image.height(), image.width(), CV_8UC4, (void*)image.constBits(), image.bytesPerLine());
        break;
    case QImage::Format_RGB32:
        mat = cv::Mat(image.height(), image.width(), CV_8UC3, (void*)image.constBits(), image.bytesPerLine());
        //cv::cvtColor(mat, mat, CV_BGR2RGB);
        break;
    case QImage::Format_ARGB32_Premultiplied:
        mat = cv::Mat(image.height(), image.width(), CV_8UC4, (void*)image.constBits(), image.bytesPerLine());
        break;
    case QImage::Format_RGB888:
        mat = cv::Mat(image.height(), image.width(), CV_8UC3, (void*)image.constBits(), image.bytesPerLine());
        //cv::cvtColor(mat, mat, CV_BGR2RGB);
        break;
    case QImage::Format_Indexed8:
        mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void*)image.constBits(), image.bytesPerLine());
        break;
    case QImage::Format_Grayscale8:
        mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void*)image.constBits(), image.bytesPerLine());
        break;
    }
    return mat;
}

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

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

相关文章

前端没有“秦始皇“,但可以做跨端的王[特殊字符]

前端各领域的 “百家争鸣” 框架之争&#xff1a;有 React、Vue、Angular 等多种框架。它们各有优缺点&#xff0c;开发者之间还存在鄙视链&#xff0c;比如 Vue 嫌 React 难用&#xff0c;React 嫌 Vue 不够灵活。样式处理&#xff1a; CSS 预处理器&#xff1a;像 Sass、Les…

mongodb源码分析session异步接受asyncSourceMessage()客户端流变Message对象

mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程&#xff0c;并且验证connection是否超过限制&#xff0c;ASIOSession和connection是循环接受客户端命令&#xff0c;状态转变流程是&#xff1a;State::Created 》 State::Source 》State::…

【数据分析】什么是鲁棒性?

引言 —— 为什么我们需要“抗折腾”的系统&#xff1f; 当你乘坐的飞机穿越雷暴区时机体剧烈颠簸&#xff0c;自动驾驶汽车在暴雨中稳稳避开障碍物&#xff0c;或是手机从口袋摔落后依然流畅运行——这些场景背后&#xff0c;都藏着一个工程领域的“隐形守护者”&#xff1a;…

Qt/C++学习系列之QGroupBox控件的简单使用

Qt/C学习系列之QGroupBox控件的简单使用 前言样式使用代码层面初始化控件事件过滤器点击事件处理 总结 前言 最近在练手一个项目&#xff0c;项目中有不同功能的划分&#xff0c;为了功能分区一目了然&#xff0c;我使用到QGroupBox控件&#xff0c;也是在界面排版布局中最常用…

如何轻松地将数据从 iPhone传输到iPhone 16

对升级到 iPhone 16 感到兴奋吗&#xff1f;恭喜&#xff01;然而&#xff0c;除了兴奋之外&#xff0c;学习如何将数据从 iPhone 传输到 iPhone 16 也很重要。毕竟&#xff0c;那些重要的联系人、笔记等都是不可或缺的。为了实现轻松的iPhone 到 iPhone 传输&#xff0c;我们总…

开源供应链攻击持续发酵,多个软件包仓库惊现恶意组件

近期在npm、Python和Ruby软件包仓库中相继发现多组恶意组件&#xff0c;这些组件能够清空加密货币钱包资金、安装后删除整个代码库并窃取Telegram API令牌&#xff0c;再次印证了开源生态系统中潜伏的多样化供应链威胁。 多平台恶意组件集中曝光 Checkmarx、ReversingLabs、S…

量子计算+AI:特征选择与神经网络优化创新应用

在由玻色量子协办的第二届APMCM“五岳杯”量子计算挑战赛中&#xff0c;来自北京理工大学的Q-Masterminds团队摘取了银奖。该团队由北京理工大学张玉利教授指导&#xff0c;依托玻色量子550计算量子比特的相干光量子计算机&#xff0c;将量子计算技术集成到特征选择和神经网络剪…

光伏功率预测新突破:TCN-ECANet-GRU混合模型详解与复现

研究背景 ​背景与挑战​ 光伏发电受天气非线性影响,传统方法(统计模型、机器学习)难以处理高维时序数据,预测误差大。​创新模型提出​ 融合时序卷积网络(TCN)、高效通道注意力(ECANet)和门控循环单元(GRU)的混合架构。​方法论细节​ TCN:膨胀因果卷积提取长时序特…

C# 用户控件(User Control)详解:创建、使用与最佳实践

在C#应用程序开发中&#xff0c;用户控件&#xff08;User Control&#xff09;是一种强大的工具&#xff0c;它允许开发者将多个标准控件组合成一个可复用的自定义组件。无论是Windows Forms还是WPF&#xff0c;用户控件都能显著提高UI开发的效率&#xff0c;减少重复代码&…

OpenWrt 搭建 samba 服务器的方法并解决 Windows 不允许访问匿名服务器(0x80004005的错误)的方法

文章目录 一、安装所需要的软件二、配置自动挂载三、配置 Samba 服务器四、配置 Samba 访问用户和密码&#xff08;可选&#xff09;新建 Samba 专门的用户添加无密码的 Samba 账户使用root账户 五、解决 Windows 无法匿名访问Samba方案一 配置无密码的Samba账户并启用匿名访问…

【 Redis | 完结篇 缓存优化 】

前言&#xff1a;本节包含常见redis缓存问题&#xff0c;包含缓存一致性问题&#xff0c;缓存雪崩&#xff0c;缓存穿透&#xff0c;缓存击穿问题及其解决方案 1. 缓存一致性 我们先看下目前企业用的最多的缓存模型。缓存的通用模型有三种&#xff1a; 缓存模型解释Cache Asi…

AI数据集构建:从爬虫到标注的全流程指南

AI数据集构建&#xff1a;从爬虫到标注的全流程指南 系统化学习人工智能网站&#xff08;收藏&#xff09;&#xff1a;https://www.captainbed.cn/flu 文章目录 AI数据集构建&#xff1a;从爬虫到标注的全流程指南摘要引言流程图&#xff1a;数据集构建全生命周期一、数据采…

AI破局:饿了么如何搅动即时零售江湖

最近&#xff0c;即时零售赛道打的火热&#xff0c;对我们的生活也产生了不少的影响。 美女同事小张就没少吐槽“他们咋样了我不知道&#xff0c;奶茶那么便宜&#xff0c;胖了五六斤不说&#xff0c;钱包也空了&#xff0c;在淘宝买奶茶的时候&#xff0c;换了个手机还买了不少…

04 APP 自动化- Appium toast 元素定位列表滑动

文章目录 一、toast 元素的定位二、滑屏操作 一、toast 元素的定位 toast 元素就是简易的消息提示框&#xff0c;toast 显示窗口显示的时间有限&#xff0c;一般3秒左右 # -*- codingutf-8 -*- from time import sleep from appium import webdriver from appium.options.an…

物流项目第十期(轨迹微服务)

本项目专栏&#xff1a; 物流项目_Auc23的博客-CSDN博客 建议先看这期&#xff1a; MongoDB入门之Java的使用-CSDN博客 物流项目第九期&#xff08;MongoDB的应用之作业范围&#xff09;-CSDN博客 业务需求 快递员取件成功后&#xff0c;需要将订单转成运单&#xff0c;用…

【数据库】关系数据理论--规范化

1.问题的提出 关系模式由五部分组成&#xff0c;是一个五元组&#xff1a; R(U, D, DOM, F) &#xff08;1&#xff09;关系名R是符号化的元组语义 &#xff08;2&#xff09;U为一组属性 &#xff08;3&#xff09;D为属性组U中的属性所来自的域 &#xff08;4&#xff09;DOM…

Oracle双平面适用场景讨论会议

4月28日&#xff0c;我在杭州组织召开了Oracle双平面会议讨论沙龙。在国产化数据库浪潮的今天&#xff0c;Oracle数据库作为国产数据库的应急库&#xff0c;在国产数据库发生故障或者性能下降时&#xff0c;如何更好的使用Oracle。会议主题如下&#xff1a; 1、背景与痛点速览&…

使用BERT/BiLSTM + CRF 模型进行NER进展记录~

使用代码处理数据集&#xff0c;发现了一些问题&#xff0c;以及解决办法~ 下载了一组数据集&#xff0c;数据存放在CSV中&#xff0c;GBK格式。如下&#xff1a; 首先对每一列直接进行NER抽取&#xff0c;结果非常不好&#xff1a; 几乎是乱抽取的&#xff0c;解决办法是自己创…

Web攻防-SQL注入高权限判定跨库查询文件读写DNS带外SecurePriv开关绕过

知识点&#xff1a; 1、Web攻防-SQL注入-高权限用户差异 2、Web攻防-SQL注入-跨库注入&文件读写&DNS带外 案例说明&#xff1a; 在应用中&#xff0c;数据库用户不同&#xff0c;可操作的数据库和文件读写权限不一&#xff0c;所有在注入过程中可以有更多的利用思路&a…

C语言数据结构笔记3:Union联合体+结构体取8位Bool量

本文衔接上文要求&#xff0c;新增8位bool量的获取方式。 目录 问题提出&#xff1a; Union联合体struct结构体(方式1)&#xff1a; Union联合体struct结构体(方式2)&#xff1a; BYTE方式读取&#xff1a; 问题提出&#xff1a; 在STM32单片机的编程中&#xff0c;无法定义Boo…