QImage 与 cv::Mat 之间的相互转换
近期做图像处理方面的项目比較多,非常多算法自己从头写的话太浪费时间,并且自己写的也不一定完好,早就听说OpenCV在图像处理算法方面功能非常强大,一直没时间学习,这次正好项目用到了。暂时抱佛脚学习些OpenCV入门知识。由于我的程序界面都是用Qt写的,因此也花了点时间研究了怎样将OpenCV 和Qt 融合在一起,协同工作。
Qt 中处理图像主要用的是QImage类。OpenCV中主要用的是cv::Mat类。以下的两个函数能够用来实现这两个类相互转换。
QImage cvMat2QImage(const cv::Mat& mat)
{
// 8-bits unsigned, NO. OF CHANNELS = 1
if(mat.type() == CV_8UC1)
{
QImage image(mat.cols, mat.rows, QImage::Format_Indexed8);
// Set the color table (used to translate colour indexes to qRgb values)
image.setColorCount(256);
for(int i = 0; i < 256; i++)
{
image.setColor(i, qRgb(i, i, i));
}
// Copy input Mat
uchar *pSrc = mat.data;
for(int row = 0; row < mat.rows; row ++)
{
uchar *pDest = image.scanLine(row);
memcpy(pDest, pSrc, mat.cols);
pSrc += mat.step;
}
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);
return image.rgbSwapped();
}
else if(mat.type() == CV_8UC4)
{
qDebug() << "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();
}
else
{
qDebug() << "ERROR: Mat could not be converted to QImage.";
return QImage();
}
}
cv::Mat QImage2cvMat(QImage image)
{
cv::Mat mat;
qDebug() << image.format();
switch(image.format())
{
case QImage::Format_ARGB32:
case QImage::Format_RGB32:
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;
}
return mat;
}
程序比較简单,就不多说明了。唯一须要注意的是cvMat 和QImage 对于RGBA 这四个分量的排列顺序是不同样的。转换的时候须要调换一下。可是Qt 的文档中说的非常明白,QImage内部数据存储的方式不能保证以后永远不变。
所以这个代码也不能保证一直是可用的。
以下是五个測试用例。基本上把各种常见情况都覆盖了。
void test1()
{
cv::Mat mat = cv::imread("Q:\\Koala.jpg", cv::IMREAD_UNCHANGED);
cv::cvtColor(mat, mat, CV_BGR2BGRA);
QImage image = cvMat2QImage(mat);
qDebug() << (mat.type() == CV_8UC4);
cvNamedWindow("cvMat2QImage RGB32", CV_WINDOW_AUTOSIZE);
imshow("cvMat2QImage RGB32", mat);
QLabel label;
label.setPixmap(QPixmap::fromImage(image));
label.show();
cv::waitKey(10000);
}
void test2()
{
cv::Mat mat = cv::imread("Q:\\Koala.jpg", cv::IMREAD_UNCHANGED);
cv::cvtColor(mat, mat, CV_BGR2GRAY);
QImage image = cvMat2QImage(mat);
cvNamedWindow("cvMat2QImage gray", CV_WINDOW_AUTOSIZE);
imshow("cvMat2QImage gray", mat);
QLabel label;
label.setPixmap(QPixmap::fromImage(image));
label.show();
cv::waitKey(10000);
}
void test3()
{
QImage image("Q:\\Koala.jpg");
image = image.convertToFormat(QImage::Format_RGB32);
cv::Mat mat = QImage2cvMat(image);
//cv::cvtColor(mat, mat, CV_BGR2RGB);
imshow("QImage2cvMat RGB32", mat);
cv::waitKey(10000);
} void test4()
{
QImage image("Q:\\Koala.jpg");
image = image.convertToFormat(QImage::Format_RGB888);
cv::Mat mat = QImage2cvMat(image);
imshow("QImage2cvMat RGB24", mat);
cv::waitKey(10000);
}
void test5()
{
QImage image("Q:\\Koala.jpg");
image = image.convertToFormat(QImage::Format_Indexed8);
cv::Mat mat = QImage2cvMat(image);
imshow("QImage2cvMat Indexed8", mat);
cv::waitKey(10000);
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//test1();
//test2();
//test3();
//test4();
//test5();
test1();
return a.exec();
}
QImage 与 cv::Mat 之间的相互转换的更多相关文章
- QImage与cv::Mat转换;
QImage主要格式有QImage::Format_RGB32, QImage::Format_RGB888, QImage::Format_Index8, 不同的格式有不同的排布: 格式部分可以参考 ...
- unity3d的Texture2D与opencv的Mat之间的相互转换
这里的opencv使用的是opencvsharp,它是c#语言对c++的opencv的一层封装,使得c#开发者可以更方便的使用opencv,而不必纠结于跨语言调用的问题. 因此,这里使用的opencv ...
- 【资料收集】Converting Between cv::Mat and QImage or QPixmap
参考: 方法一 Convert between cv::Mat and QImage 两种图片类转换 - Grandyang - 博客园 http://www.cnblogs.com/grandyan ...
- Qt QImage与OpenCV Mat转换
本系列文章由 @yhl_leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/51029382 应一个朋友的要求,整理总 ...
- OpenCV图片类cv::Mat和QImage之间进行转换(好多相关文章)
在使用Qt和OpenCV混合编程时,我们有时需要在两种图片类cv::Mat和QImage之间进行转换,下面的代码参考了网上这个帖子: //##### cv::Mat ---> QImage ## ...
- Convert between cv::Mat and QImage 两种图片类转换
在使用Qt和OpenCV混合编程时,我们有时需要在两种图片类cv::Mat和QImage之间进行转换,下面的代码参考了网上这个帖子: //##### cv::Mat ---> QImage ## ...
- Write cv::Mat to a file
如果我们想把OpenCV中的矩阵数据类型cv::Mat保存在一个文件中,可以使用如下的代码: void writeMatToFile(cv::Mat& m, const char* filen ...
- cv::mat转换成QImage的问题
在进行cv::mat转换为QImage过程中,经常出现问题: cv::Mat image; ...QImage img=QImage((const unsigned char*)(image.data ...
- cv::Mat转换QImage
cvtColor(img, img, CV_BGR2RGB); QImage image((uchar*)img.data,img.cols,img.rows,QImage::Format_RGB88 ...
随机推荐
- JavaScript面向对象精要(一)
数据类型 在JavaScript中,数据类型分为两类: 原始类型:保存一些简单数据,如true.5等.JavaScript共同拥有5中原始类型: boolean:布尔.值为true或false num ...
- python 笔记4-- 函数式编程
高阶函数 把函数作为参数传入,这样的函数称为高阶函数,函数式编程就是指这种高度抽象的编程范式. 在python中 函数也是一种变量 def add(x, y, f): return f(x) + f( ...
- css直接写出小三角
在开发移动端项目时,总是遇到很多小三角,之前一直用图片,感觉好麻烦,今天尝试了直接用CSS写出小三角!先看看如何写出各种小三角! /*箭头向上*/ .arrow-up { ; ; border-lef ...
- Android Studio自定义注释模板及生成JavaDoc
刚开始学习Android,使用了Android Studio IDE.为了将来生产JavaDoc,学习一下如何自定义注释模板. . 自定义注释模板 1. 通过 File –>Settings 或 ...
- 什么时候会刷新备库控制文件refresh the standby database control file?
通过合理的设置,对于Primary的绝大数操作,都是可以传递到Physical Standby,datafile的操作是通过STANDBY_FILE_MANAGEMENT参数来控制的,但是即使STAN ...
- CALayer CABasicAnimation
CALayer是UIView可以响应事件.一般来说,layer可以有两种用途:一是对view相关属性的设置,包括圆角.阴影.边框等参数:二是实现对view的动画操控. 因此对一个view进行core ...
- 解决升级Xcode后插件不能使用的问题
从Xcode 5开始,苹果要求加入UUID证书从而保证插件的稳定性.因此Xcode版本更新之后需要在插件的Info.plist文件中添加当前Xcode的UUID. 具体步骤如下: 1.获取Xcode的 ...
- NOIP2012模拟试题【奶牛晒衣服】
1.奶牛晒衣服(dry) [问题描述] 在熊大妈英明的带领下,时针和它的同伴生下了许多牛宝宝.熊大妈决定给每个宝宝都穿上可爱的婴儿装.于是,为牛宝宝洗晒衣服就成了很不爽的事情. 圣人王担负起了这个重任 ...
- C#传递参数大集合
方法的参数是个值得特别注意的地方.方法的参数传递有四种类型:传值(by value),传址(by reference),输出参数(by output),数组参数(by array).传值参数无需额外的 ...
- Kill命令模拟1
#include<sys/types.h> #include<signal.h> #include<stdio.h> #include<stdlib.h> ...