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 ...
随机推荐
- android视频录制、另一部手机实时观看方案
最近调研android视频录制.另一部手机实时观看,大致有以下几种思路. 1. android手机充当服务器,使用NanoHTTPD充当服务器,另一部手机或者pc通过输入http://手机的ip:80 ...
- with ffmpeg to encode video for live streaming and for recording to files for on-demand playback
We've been doing some experimentation with ffmpeg to encode video for live streaming and for recordi ...
- [记录]关于vertical-align单/多选框与说明文字对齐效果
效果图: 第一张使用label标签,第二张没有使用.. 使用label标签,middle对齐方式的单选框下降了1px 而没有使用label标签,sub对齐方式的 却 居 中 了 =_= 不太理解 ...
- Extjs 6 MVC开发模式(二)
1.Extjs MVC开发模式 在JS的开发过程中,大规模的JS脚本难以组织和维护,这一直是困扰前端开发人员的头等问题.Extjs为了解决这种问题,在Extjs4.x版本中引入了MVC开发模式,开始将 ...
- [转]用apache反向代理解决单外网ip对应内网多个web主机的问题
用apache反向代理解决单外网ip对应内网多个web主机的问题 转载一个有独立外网IP,需内网服务器对外发布的例子,是应用apache虚拟主机的. 来源地址:http://www.itshantou ...
- POJ 2594 - Treasure Exploration
一个星球上有很多点,点与点之间有很多单向路 问可重点的最小路径覆盖 利用floyd缩点后求二分图最大匹配 #include <iostream> #include <cstdio&g ...
- Dijkstra算法(迪杰斯塔拉算法)
算法描述: Dijkstra(迪杰斯特拉)算法是典型的最短路径路由算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.Dijkstra算法能得出最 ...
- java中静态代码块的用法 static用法详解
(一)java 静态代码块 静态方法区别一般情况下,如果有些代码必须在项目启动的时候就执行的时候,需要使用静态代码块,这种代码是主动执行的;需要在项目启动的时候就初始化,在不创建对象的情况下,其他程序 ...
- Chapter 01:创建和销毁对象
<一>考虑用静态工厂方法代替构造器 下面是Boolean类的一个简单示例: public final class Boolean implements java.io.Serializab ...
- HTML5 Mobile 适应移动端的屏幕<meta name='viewport' content='xxxx'>
网页手机wap2.0网页的head里加入下面这条元标签,在移动端的浏览器中页面将以原始大小显示,并不允许缩放. 加入 如下代码 即可自适应移动端的屏幕: <meta name="vie ...