openCV图片显示到Qt控件QLabel
2017-08-16 15:49
585 查看
初入坑openCV,记录学习收获,如有错误还望指正。
关于Qt中配置openCV不再累述,在编程之前要加入外部库,首先在.pro中加入
注意具体的地址要依照储存位置而定。
依照惯例先贴代码
mattoimage.h
有两点需要注意需要加入命名空间CV,注意加入openCV2所需的头文件。
mattoimage.cpp
这次需要显示的图片
24位3通道彩图,需要从文件读取为Mat类型的图片,后转化为QImage类型显示到QLabel中。
注意Mat图有行和列,即cv::Mat中有公有成员变量cols和rows,注意,这里的cols就是图像的宽度width,rows就是图像的高度height。此处用int型保存下来。
声明一个QImage用于接收Mat类型,
确定了宽和高以及类型为24位RGB图片。双重循环将Mat矩阵的像素信息一一赋值给QImage。
注意这里先行后列的循环顺序,我们意想中的点阵储存是有行有列的二维形式,其实在计算机内存中,是将其以一维的形式,4的整倍数字节储存的。因此即使我们先列后行的储存,计算机也是一次读取一行,然后给你返回第二行同一列的元素。
这是一个模板类函数,将第i行的地址指针传给ptr,此时的ptr就是储存着第i行元素的首地址指针。由于该图片是24位3通道,即每三个字节去储存一个像素信息。bit()函数得到Image图片的首地址,bytesPerLine()函数得到一张图片每一行的字节数,乘以行数i,得到当前所需要遍历的行的首地址。然后每次3字节依次将Mat中颜色信息储存到Image中。
如果是32位4通道图片,就不需要使用bytesPerLine()去得出图片的宽度。比如下面的例子储存一个32位4通道的灰度图片。
有三点不同之处:①计算图片宽度的字节数可以直接用width*4,但在24位的图片中这只是理论的宽度,实际上计算机每一行的字节数都是4的整倍数,用每3字节去储存一个像素,在换行时若需要内存对齐,会用空格去补全。②4通道不同于3通道,会用一个字节去储存该像素透明度的问题,用0-1或0-255去表述透明度,此处默认透明度为255。③灰度图片不同于RGB图片,前三位的值都是相同。
此处只做教学之用,以后在需要用到图片宽度时,都只用bytesPerLine(),这样更保险。
最后说一下imread()函数。
函数原型:
Mat imread( const String& filename, int flags = IMREAD_COLOR );
第一个参数是图片的绝对地址
第二个参数表示图片读入的方式(flags可以缺省,缺省时flags=1,表示以彩色图片方式读入图片)
flags>0时表示以彩色方式读入图片
flags=0时表示以灰度图方式读入图片
flags<0时表示以图片的本来的格式读入图片
此处缺省flags,默认读取彩色图片。
关于Qt中配置openCV不再累述,在编程之前要加入外部库,首先在.pro中加入
INCLUDEPATH += $$PWD/../../Java/OpenCV3.2/install/include DEPENDPATH += $$PWD/../../Java/OpenCV3.2/install/include unix|win32: LIBS += -L$$PWD/../../Java/OpenCV3.2/install/x86/mingw/lib/ -llibopencv_core320.dll unix|win32: LIBS += -L$$PWD/../../Java/OpenCV3.2/install/x86/mingw/lib/ -llibopencv_highgui320.dll unix|win32: LIBS += -L$$PWD/../../Java/OpenCV3.2/install/x86/mingw/lib/ -llibopencv_imgproc320.dll unix|win32: LIBS += -L$$PWD/../../Java/OpenCV3.2/install/x86/mingw/lib/ -llibopencv_imgcodecs320.dll
注意具体的地址要依照储存位置而定。
依照惯例先贴代码
mattoimage.h
#ifndef MATTOIMAGE_H #define MATTOIMAGE_H #include <QMainWindow> #include "opencv2/core/core.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgcodecs/imgcodecs.hpp" namespace Ui { class matToImage; } using namespace cv; class matToImage : public QMainWindow { Q_OBJECT public: explicit matToImage(QWidget *parent = 0); ~matToImage(); private: Ui::matToImage *ui; }; #endif // MATTOIMAGE_H
有两点需要注意需要加入命名空间CV,注意加入openCV2所需的头文件。
mattoimage.cpp
#include <QImage> #include <QPixmap> #include "mattoimage.h" #include "ui_mattoimage.h" matToImage::matToImage(QWidget *parent) : QMainWindow(parent), ui(new Ui::matToImage) { ui->setupUi(this); Mat img = imread("D:\\QTproject\\matToImage\\pic\\timg.jpg"); int width=img.cols; int height=img.rows; int i,j; QImage *Image = new QImage(width,height,QImage::Format_RGB888); for(i=0;i<height;i++) { unsigned char *ptr = img.ptr<unsigned char>(i); //unsigned char *ptr = img.ptr<unsigned char>(i)[0]; for(j=0;j<width*3;j+=3) { Image->bits()[(Image->bytesPerLine()*i)+(j+2)] = ptr[j+2]; Image->bits()[(Image->bytesPerLine()*i)+(j+1)] = ptr[j+1]; Image->bits()[(Image->bytesPerLine()*i)+(j)] = ptr[j]; } } ui->imageLabel->setPixmap(QPixmap::fromImage(*Image).scaled(ui->imageLabel->size())); } matToImage::~matToImage() { delete ui; }
这次需要显示的图片
24位3通道彩图,需要从文件读取为Mat类型的图片,后转化为QImage类型显示到QLabel中。
注意Mat图有行和列,即cv::Mat中有公有成员变量cols和rows,注意,这里的cols就是图像的宽度width,rows就是图像的高度height。此处用int型保存下来。
声明一个QImage用于接收Mat类型,
QImage *Image = new QImage(width,height,QImage::Format_RGB888);
确定了宽和高以及类型为24位RGB图片。双重循环将Mat矩阵的像素信息一一赋值给QImage。
注意这里先行后列的循环顺序,我们意想中的点阵储存是有行有列的二维形式,其实在计算机内存中,是将其以一维的形式,4的整倍数字节储存的。因此即使我们先列后行的储存,计算机也是一次读取一行,然后给你返回第二行同一列的元素。
unsigned char *ptr = img.ptr<unsigned char>(i);
这是一个模板类函数,将第i行的地址指针传给ptr,此时的ptr就是储存着第i行元素的首地址指针。由于该图片是24位3通道,即每三个字节去储存一个像素信息。bit()函数得到Image图片的首地址,bytesPerLine()函数得到一张图片每一行的字节数,乘以行数i,得到当前所需要遍历的行的首地址。然后每次3字节依次将Mat中颜色信息储存到Image中。
如果是32位4通道图片,就不需要使用bytesPerLine()去得出图片的宽度。比如下面的例子储存一个32位4通道的灰度图片。
for(i=0;i<height;i++) { unsigned char *ptr = img.ptr<unsigned char>(i); for(j=0;j<width;j++) { ((uchar*)testdata->Image->bits())[(width*4*i)+(j*4)] = ptr[j]; ((uchar*)testdata->Image->bits())[(width*4*i)+(j*4+1)] = ptr[j]; ((uchar*)testdata->Image->bits())[(width*4*i)+(j*4+2)] = ptr[j]; ((uchar*)testdata->Image->bits())[(width*4*i)+(j*4+3)] = 255; } }
有三点不同之处:①计算图片宽度的字节数可以直接用width*4,但在24位的图片中这只是理论的宽度,实际上计算机每一行的字节数都是4的整倍数,用每3字节去储存一个像素,在换行时若需要内存对齐,会用空格去补全。②4通道不同于3通道,会用一个字节去储存该像素透明度的问题,用0-1或0-255去表述透明度,此处默认透明度为255。③灰度图片不同于RGB图片,前三位的值都是相同。
此处只做教学之用,以后在需要用到图片宽度时,都只用bytesPerLine(),这样更保险。
最后说一下imread()函数。
函数原型:
Mat imread( const String& filename, int flags = IMREAD_COLOR );
第一个参数是图片的绝对地址
第二个参数表示图片读入的方式(flags可以缺省,缺省时flags=1,表示以彩色图片方式读入图片)
flags>0时表示以彩色方式读入图片
flags=0时表示以灰度图方式读入图片
flags<0时表示以图片的本来的格式读入图片
此处缺省flags,默认读取彩色图片。
相关文章推荐
- 在QT集成开发环境中用OpenCV读取一张图片显示在Qlabel上
- Qt中用QLabel显示图片
- opencv+QT在嵌入式arm下显示图片
- Qt Qlabel显示图片新手教程
- OpenCV【2】---读取png图片显示到QT label上的问题
- (转载)Qt:拖拽图片到QLabel上并显示
- Zedboard摄像头获取视频设计问题篇(四)-OpenCV+QT配置显示图片
- Linux+qt+opencv显示图片
- ubuntu11.04下QT4.7+OpenCV2.2开发环境搭建成功,成功打开并显示图片
- OpenCV 2.2版本以上显示图片到 MFC 的 Picture Control 控件中
- Qt界面显示图片,Qt与opencv的联合运用
- opencv的图片显示到控件上坐标转换问题
- 我写的一个 Qt 显示图片的控件
- QT5.8+Opencv2.4.13导入图片并显示
- vs2015+opencv3.2+mfc读取摄像头显示在图片控件Picture Control
- zynq-7000学习笔记(十五)——在QT上调用opencv加载图片并显示
- 【C++ MFC+opencv】打开文件夹中的图片并在picture控件中显示
- 在Qt的QGraphicsView中显示OpenCV的iplimage图片
- Qt下调用opencv显示图片
- QT GUI界面的使用 opencv选择并显示图片于label中