OpenCV和Qt的图像格式互转
做图像处理的时候经常使需要用到opencv的,这应该是免费的图像处理库中用得最广泛而且最好用的库了吧。然后有时候想用界面来展示点东西的时候,我们就需要编写个界面,编写界面的方法千千万,弱水三千我只取一瓢饮,所以我用Qt来写界面,这个时候,就会想,如果我用OpenCV处理后的图像不会还要用OpenCV的GUI来显示吧,虽然完全可以这么做,但是既然都有个界面了,为啥我们还要用两个窗口来显示呢,于是就有了让OpenCV处理后的图像在Qt写的的界面上显示。
最简单粗暴无脑的方法就是把OpenCV处理后的图像保存到本地,然后用Qt加载进来,简单粗暴(23333...T_T!!!)。所以后来我找到一些别人的方法,然后我自己再修改一下,就成了我现在一直在用的方法,感觉上还可以,所以就直接上代码吧...等等,还是说一下Mat和QImage都有哪些格式吧。
首先是cv::Mat,cv::Mat是OpenCV的图像数据类型,是一个类,具体的内容可以参考OpenCV的关于cv::Mat的API,这里要注意几个地方:
1、指向图像数据的指针:
uchar* cv::Mat::data
2、图像的行跟列:
int cv::Mat::rows
int cv::Mat::cols
3、数据类型,这个比较重要,在转为QImage的时候需要用到它来辨别数据格式。
int cv::Mat::type() const
OpenCV的图像数据格式如下:
typedef uint32_t uint
typedef signed char schar
typedef unsigned char uchar
typedef unsigned short ushort
typedef int64_t int64
typedef uint64_t uint64
#define CV_BIG_INT(n) n##LL
#define CV_BIG_UINT(n) n##ULL
#define CV_CN_MAX 512
#define CV_CN_SHIFT 3
#define CV_DEPTH_MAX (1 << CV_CN_SHIFT)
#define CV_8U 0
#define CV_8S 1
#define CV_16U 2
#define CV_16S 3
#define CV_32S 4
#define CV_32F 5
#define CV_64F 6
#define CV_USRTYPE1 7
#define CV_MAT_DEPTH_MASK (CV_DEPTH_MAX - 1)
#define CV_MAT_DEPTH(flags) ((flags) & CV_MAT_DEPTH_MASK)
#define CV_MAKETYPE(depth, cn) (CV_MAT_DEPTH(depth) + (((cn)-1) << CV_CN_SHIFT))
#define CV_MAKE_TYPE CV_MAKETYPE
#define CV_8UC1 CV_MAKETYPE(CV_8U,1)
#define CV_8UC2 CV_MAKETYPE(CV_8U,2)
#define CV_8UC3 CV_MAKETYPE(CV_8U,3)
#define CV_8UC4 CV_MAKETYPE(CV_8U,4)
#define CV_8UC(n) CV_MAKETYPE(CV_8U,(n))
#define CV_8SC1 CV_MAKETYPE(CV_8S,1)
#define CV_8SC2 CV_MAKETYPE(CV_8S,2)
#define CV_8SC3 CV_MAKETYPE(CV_8S,3)
#define CV_8SC4 CV_MAKETYPE(CV_8S,4)
#define CV_8SC(n) CV_MAKETYPE(CV_8S,(n))
#define CV_16UC1 CV_MAKETYPE(CV_16U,1)
#define CV_16UC2 CV_MAKETYPE(CV_16U,2)
#define CV_16UC3 CV_MAKETYPE(CV_16U,3)
#define CV_16UC4 CV_MAKETYPE(CV_16U,4)
#define CV_16UC(n) CV_MAKETYPE(CV_16U,(n))
#define CV_16SC1 CV_MAKETYPE(CV_16S,1)
#define CV_16SC2 CV_MAKETYPE(CV_16S,2)
#define CV_16SC3 CV_MAKETYPE(CV_16S,3)
#define CV_16SC4 CV_MAKETYPE(CV_16S,4)
#define CV_16SC(n) CV_MAKETYPE(CV_16S,(n))
#define CV_32SC1 CV_MAKETYPE(CV_32S,1)
#define CV_32SC2 CV_MAKETYPE(CV_32S,2)
#define CV_32SC3 CV_MAKETYPE(CV_32S,3)
#define CV_32SC4 CV_MAKETYPE(CV_32S,4)
#define CV_32SC(n) CV_MAKETYPE(CV_32S,(n))
#define CV_32FC1 CV_MAKETYPE(CV_32F,1)
#define CV_32FC2 CV_MAKETYPE(CV_32F,2)
#define CV_32FC3 CV_MAKETYPE(CV_32F,3)
#define CV_32FC4 CV_MAKETYPE(CV_32F,4)
#define CV_32FC(n) CV_MAKETYPE(CV_32F,(n))
#define CV_64FC1 CV_MAKETYPE(CV_64F,1)
#define CV_64FC2 CV_MAKETYPE(CV_64F,2)
#define CV_64FC3 CV_MAKETYPE(CV_64F,3)
#define CV_64FC4 CV_MAKETYPE(CV_64F,4)
#define CV_64FC(n) CV_MAKETYPE(CV_64F,(n))
这里最最常见和默认的应该是:
#define CV_8U 0
#define CV_8UC1 CV_MAKETYPE(CV_8U,1)
#define CV_8UC3 CV_MAKETYPE(CV_8U,3)
然后因为有时候要用到浮点型数据,所以,可能我会用到:
#define CV_32F 5
#define CV_64F 6
#define CV_32FC1 CV_MAKETYPE(CV_32F,1)
#define CV_32FC3 CV_MAKETYPE(CV_32F,3)
#define CV_64FC1 CV_MAKETYPE(CV_64F,1)
#define CV_64FC3 CV_MAKETYPE(CV_64F,3)
然后是QImage是Qt提供的图像类型之一,其数据类型有:

但是,对应上面cv::Mat的类型如下:
//单通道灰度图
CV_8UC1 == QImage::Format_Grayscale8
CV_8U == QImage::Format_Grayscale8
//三通道图
CV_8UC3 == QImage::Format_RGB888
基本上,有这几个类型的转换就够了的,好了,类型说完了,该上代码了:
QImage mat2qimage(const cv::Mat &mat)
{
if (mat.type() == CV_8UC1 || mat.type() == CV_8U)
{
// 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_Grayscale8);
return image;
}
// 8-bits unsigned, NO. OF CHANNELS = 3
else if (mat.type() == 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);
// Because of the BGR order in opencv,
// here the rgbSwapped() function is needed.
return image.rgbSwapped();
}
}
如果要显示的是float或者fouble型的呢...那就转一下吧,应该,上面这两种会更常见一点吧。其实还有QImage转cv::Mat的方法的,但是我觉得...好像不是很有必要,毕竟我更倾向于用Open'CV做图像处理,然后用Qt带来显示。
草在结它的种子
风在摇它的叶子
我们站着,不说话
就十分美好
-- 顾城

OpenCV和Qt的图像格式互转的更多相关文章
- Opencv与Qt (一)之运行测试读取图片
刚刚在vs上装好了QT和Opencv,试一下效果把. 我简单的创建了一个label,然后使用Opencv导入图像,因为Opencv导入图像是MAT格式的,在使用Qt的时候我们要把导入的图像转换成Qim ...
- OpenCV与QT联合开发示例
1.OpenCV及QT开发环境搭建 windows基于vs2017的opencv安装 windows下安装QT并与visual studio 2017搭建开发环境 2.工程创建 1.导入Qt项目 选择 ...
- OpenCV支持Qt用户界面
在运行opencv程序的时候报下面的错误: ... The library is compiled without QT support in function ... 原因是在使用cmake安装op ...
- 使用opencv在Qt控件上播放mp4文件
文章目录 简介 核心代码 运行结果 简介 opencv是一个开源计算机视觉库,功能非常多,这里简单介绍一下OpenCV解码播放Mp4文件,并将图像显示到Qt的QLabel上面. 核心代码 头文件 #i ...
- ubuntu 安装 OpenCv 及其Qt的开发环境配置
ubuntu安装opencv (1)安装编译opencv的环境 sudo apt-get -y install build-essential cmake pkg-config (2)安装Image ...
- [OpenCV] Install openCV in Qt Creator
Learn openCV.pdf qmake: link with opencv (Key Point) QT += core gui greaterThan(QT_MAJOR_VERSION, 4) ...
- ubuntu下opencv在Qt中的使用
1. 编译安装OpenCV2.4.9 本博已有文章描述 2. 安装Qt和QtCreator 从qt-project.org 下载Qt安装文件 qt-opensource-linux-x64-5.4. ...
- OpenCV与QT联合编译 分类: Eye_Detection ZedBoard OpenCV shell ubuntu 2014-11-08 18:54 143人阅读 评论(0) 收藏
问题1:首先参考rainysky的博客,发现qmake时发生找不到目录,文件的错误,又找不到 qmake.conf 文件的写法.所以开始按照网上的程序修改 XXX.pro 文件. 问题2:使用QT C ...
- (GO_GTD_2)基于OpenCV和QT,建立Android图像处理程序
一.综述 如何采集图片?在windows环境下,我们可以使用dshow,在linux下,也有ffmpeg等基础类库,再不济,opencv自带的videocapture也是提供了基础的支撑.那么 ...
随机推荐
- IO流常用模式
主要运用2个设计模式,适配器和装饰者模式.
- 常见SQL语句杂谈(笔记)
SQL语句(总结,完整的select语句) select distinct * from 表名 where ...group by ... having ...order by ... limit s ...
- hibernate保存失败
报错:org.hibernate.jdbc.BdatchedTooManyRowsAffectedException: Batch update returned unexpected row cou ...
- 洛谷 三月月赛 B
搞出每一位与前一位的差,然后区间修改只是会影响区间的端点,所以只修改一下端点的值就好. %%%高一神犇线段树 #include<bits/stdc++.h> #define N 10000 ...
- 获得spring
这里 手动下载 各版本的发行包 这里是 官方项目地址 这里是在 GitHub上托管源代码 的地方 已知spring依赖的其他jar commons-logging-1[1].0.4.jar
- mybatis xml <if>判断字符串相等
mybatis 映射文件中,if标签判断字符串相等,两种方式: 因为mybatis映射文件,是使用的ognl表达式,所以在判断字符串sex变量是否是字符串Y的时候, <if test=" ...
- 球队“食物链”(DFS+剪枝)
某国的足球联赛中有N支参赛球队,编号从1至N.联赛采用主客场双循环赛制,参赛球队两两之间在双方主场各赛一场. 联赛战罢,结果已经尘埃落定.此时,联赛主席突发奇想,希望从中找出一条包含所有球队的“食物链 ...
- javaweb历史上最简单的使用Ajax判断用户名是否被注册(不跳转页面奥!)
关于前端: 使用jquery-3.3.1.js记得要导入奥---最后我会附加我的源码的 哎我也不多说了新手加菜鸟jquery真的不太懂!看代码吧!个别地方我会写上我对本程序的理解. 关于后台也就是se ...
- vue学习(二)Vue常用指令
2 Vue常用指令 1. vue的使用要从创建Vue对象开始 var vm = new Vue(); 2. 创建vue对象的时候,需要传递参数,是json对象,json对象对象必须至少有两个属性成员 ...
- 【转载】RobotFramework的Setup或Teardowm中执行多个关键字
有时候需要在setup和teardowm中执行多个关键字 以前的做法就是重新封装一个keyword,然后调用,It’s OK 这里介绍另外一个方法,使用Run Keywords来实现 用法其实非常的简 ...