QT 框架中快速应用OpenCV 基于图片
2013-12-05 14:30
357 查看
1.显示图像
QWidget是QObject下的第一个子类,使用它显示图像会减少不必要的开销。首先定制一个自己需要的QWidget:
需要绘制一个图像,我重载paintEvent(QpaintEvent *e),我在这里面使用QPainter进行绘制。
rawImage(QPoint(5,5),qImg);的作用是将qImg绘制在左上顶点位于QPoint(5,5)处。
这里面有可能两个问题,第一个问题是要显示的图片太小,创建的Widget太大,最后显示比较丑陋。这时可以在此函数里面获得qImg的宽高,然后resize一下就好了。另外一个问题是:绘制的时候使用的是QImage,不是IplImage类型。关于这个问题论坛上有人专门写了IplImage <-> QImage的转换代码,我在这里不重复那个做法,一是有人已经做了,另外处于效率考虑,这里提供另一种方法。
通常同学们都是用cvLoadImage来读图片,保存在IplImage里面,在这里这个图片我们保存在img里面,然后通过img传进QWidget,然后我new一个QImage
我这里假设iplImg是RGB格式,且每个通道大小为8。然后创建一个IplImage 的文件头
此iplImage和QImage的不同之处在于QImage没有直接提供创建文件头的方法,可以通过如下方式创建只有文件头数据的QImage
另外两者的图像矩阵像素排列有点不同,比如IplImage中的BGR到了QImage中应该是RGB,当然单通道的灰度图是一样的,值得庆幸的是两者的像素矩阵都是形状相同的多维数组。这样我们可以通过指针共享这部分数据,一种方法如下:
将iplImg的图像矩阵指到qImg那里,以后我们只需要对IplImage运用opencv里面的函数进行处理,其实就直接在处理qImg里面的数据了。但是现在的图像数据还在img里面,首先得把数据搞到手,然后放到iplImg和qImg的共享区中去,另外将颜色排列以QImage中的RGB顺序为标准。
实际上只要做到这里图片就能显示了。如下图所示
给出myWidget.cpp完整代码
调用的代码很简单:
QWidget是QObject下的第一个子类,使用它显示图像会减少不必要的开销。首先定制一个自己需要的QWidget:
class myWidget : public QWidget { Q_OBJECT public: myWidget(const IplImage *img,QWidget *parent = 0); ~myWidget(); protected: void paintEvent(QPaintEvent *e); private: IplImage* iplImg; QImage *qImg; };
需要绘制一个图像,我重载paintEvent(QpaintEvent *e),我在这里面使用QPainter进行绘制。
void myWidget::paintEvent(QPaintEvent *e) { QPainter painter(this); painter.drawImage(QPoint(5,5),*qImg); }
rawImage(QPoint(5,5),qImg);的作用是将qImg绘制在左上顶点位于QPoint(5,5)处。
这里面有可能两个问题,第一个问题是要显示的图片太小,创建的Widget太大,最后显示比较丑陋。这时可以在此函数里面获得qImg的宽高,然后resize一下就好了。另外一个问题是:绘制的时候使用的是QImage,不是IplImage类型。关于这个问题论坛上有人专门写了IplImage <-> QImage的转换代码,我在这里不重复那个做法,一是有人已经做了,另外处于效率考虑,这里提供另一种方法。
通常同学们都是用cvLoadImage来读图片,保存在IplImage里面,在这里这个图片我们保存在img里面,然后通过img传进QWidget,然后我new一个QImage
qImg = new QImage(QSize(img->width,img->height),QImage::Format_RGB888);
我这里假设iplImg是RGB格式,且每个通道大小为8。然后创建一个IplImage 的文件头
iplImg = cvCreateImageHeader(cvSize(img.width(),img.height()),8,3);
此iplImage和QImage的不同之处在于QImage没有直接提供创建文件头的方法,可以通过如下方式创建只有文件头数据的QImage
qImg = new QImage(QSize(0,0),QImage::Format_RGB888);
另外两者的图像矩阵像素排列有点不同,比如IplImage中的BGR到了QImage中应该是RGB,当然单通道的灰度图是一样的,值得庆幸的是两者的像素矩阵都是形状相同的多维数组。这样我们可以通过指针共享这部分数据,一种方法如下:
iplImg->imageData = (char*)qImg.bits();
将iplImg的图像矩阵指到qImg那里,以后我们只需要对IplImage运用opencv里面的函数进行处理,其实就直接在处理qImg里面的数据了。但是现在的图像数据还在img里面,首先得把数据搞到手,然后放到iplImg和qImg的共享区中去,另外将颜色排列以QImage中的RGB顺序为标准。
if (img->origin == IPL_ORIGIN_TL) { cvCopy(img,iplImg,0); } else { cvFlip(img,iplImg,0); } cvCvtColor(iplImg,iplImg,CV_BGR2RGB);
实际上只要做到这里图片就能显示了。如下图所示
给出myWidget.cpp完整代码
#include "myWidget.h"
#include <QtGui\QPainter>
#include <QtCore\QPoint>
myWidget::myWidget(const IplImage *img,QWidget *parent /* = 0 */) : QWidget(parent)
{
qImg = new QImage(QSize(img->width,img->height),
QImage::Format_RGB888);
iplImg = cvCreateImageHeader(cvSize(img->width,img->height),
8,3);
iplImg->imageData = (char*)qImg->bits();
if (img->origin == IPL_ORIGIN_TL) { cvCopy(img,iplImg,0); } else { cvFlip(img,iplImg,0); } cvCvtColor(iplImg,iplImg,CV_BGR2RGB);this->resize(img->width,img->height);
}
myWidget::~myWidget()
{
cvReleaseImage(&iplImg);
delete qImg;
}
void myWidget::paintEvent(QPaintEvent *e)
{
QPainter painter(this);
painter.drawImage(QPoint(0,0),*qImg);
}
调用的代码很简单:
int main(int argc,char* argv[]) { QApplication app(argc,argv); IplImage *img = cvLoadImage("460.jpg",1); if (img) { myWidget *mw = new myWidget(img); mw->show(); } int re = app.exec(); cvReleaseImage(&img); return re; }
相关文章推荐
- QT框架中快速应用OpenCV——基于图片
- QT框架中快速应用OpenCV——基于视频播放
- QT 框架中快速应用OpenCV 基于视频播放
- QT 框架中快速应用OpenCV 基于视频播放
- QT 框架中快速应用OpenCV
- QT框架中快速应用OpenCV
- QT框架中快速应用OpenCV
- 【转】QT框架中快速应用OpenCV
- 基于QT和opencv的摄像头(本地图片)读取并输出程序
- 基于Qt与OpenCV的图片读取、保存,并利用Canny进行简单的边缘处理结果显示
- 基于元数据配置的asp.net数据库应用快速开发框架设计及实现
- 使用Acegi作为基于Spring框架的WEB应用的安全框架
- Java基于直方图应用的相似图片识别实例
- 导向滤波小结:从导向滤波(guided filter)到快速导向滤波(fast guide filter)的原理,应用及opencv实现代码
- Zedboardwebcam设计问题篇(三)-OpenCV+QT配置显示图片
- iOS快速开发框架Bee-Framework应用和解析(二) --- Bee framework架构概览
- 【Qt编程】基于Qt的词典开发系列<一>--词典框架设计及成品展示
- 基于MinGW的QT环境配置OpenCV
- 基于opencv3.3获取图片某点处RGB及HSV值完整工程
- [连载]基于消息驱动的面向对象通用C/S应用框架(九)