您的位置:首页 > 其它

CvArr、Mat、CvMat、IplImage、BYTE;QPixmap和QImage

2017-04-13 13:00 411 查看

一. CvArr Mat CvMat IplImage

原文地址:

http://blog.csdn.net/wuxiaoyao12/article/details/7305848

他们之间转换过程如下图所示



其中:CVArr->CvMat->IplImage 三者的继承关系

1. IplImage pImg= IplImage(imgMat);
2. CvMat cvMat = imgMat;
3. IplImage* img = cvCreateImage(cvGetSize(mat),8,1);
cvGetImage(mat,img);
cvSaveImage("rice1.bmp",img);
4.Mat::Mat(const CvMat* m, bool copyData=false);
5.IplImage* pImg = cvLoadImage("lena.jpg");
Mat img(pImg,0);
6.
法1:CvMat mathdr, *mat = cvGetMat( img, &mathdr );
法2:CvMat *mat = cvCreateMat( img->height, img->width, CV_64FC3 );
cvConvert( img, mat );
7.BYTE* data= img->imageData;
8.
img= cvCreateImageHeader(cvSize(width,height),depth,channels);
cvSetData(img,data,step);


二 Qpixmap和QImage

原文地址:http://blog.sina.com.cn/s/blog_541348370100ui8e.html

1.Qpixmap和QImage的区别

(1)应用情况

QPixmap是专门为绘图而生,当需要绘制图片时你需要使用QPixmap;QImage则是为I/O,为图片像素访问以及修改而设计的。访问图片的像素或是修改图片像素,需要使用QImage,或者借助于QPainter来操作像素。

(2)硬件相关性

QPixmap:硬件相关的

QPixmap 存储在服务器端,如X11, Mac 以及 Symbian平台上。

QImage:硬件无关的

QImage存储在客户端

但是,在Windows平台上,QPixmap和QImage都是存储在客户端,并不使用任何的GDI资源。

(3)绘图速度

在X11, Mac 以及 Symbian平台上

QImage: 由于它存储在客户端,往QImage上绘图比较快,但显示它则比较慢。

QPixmap: 因为它是存储在服务器端,往QPixmap上绘图比较慢,但显示它则比较快。

Windows平台上一样的:原因是它们都存储在客户端。

2.其他的图片处理类

QBitmap和QPicture

QBitmap只是一个继承于QPixmap的简单类,它可以确保图片深度为1,提
4000
供单色图像,可以用来制作游标(QCursor)或者笔刷(QBrush)。

QPicture是一个绘画设备类,它记录了并可以重演QPainter的命令。你可以使用QPainter的begin()方法,指定在QPicture上绘图,使用end()方法结束绘图,使用QPicture的save()方法將QPainter所使用过的绘图指令存至档案。要重播绘图指令的话,建立一個QPicture,使用load()方法载入绘图指令的档案,然后在指定的绘图裝置上绘制QPicture

3. QImage与QPixmap完全解析

完成功能:使用Qt程序在手机上显示一幅图片

//dangerous should not be used, cannot display earth.png,
//but if we change earth.png to a smaller image e.g. apple.png, apple.png can be displayed
QPixmap pixmap;
pixmap.load( ":/pics/earth.png" );
label->setPixmap( pixmap );




//dangerous should not be used, cannot display earth.png,
//but if we change earth.png to a smaller image e.g. apple.png, apple.png can be displayed
QPixmap pixmap;
pixmap.load( ":/pics/earth.png" );
QPainter painter(this);
painter.drawPixmap(0,0, pixmap);


(1)两段代码并没有问题,但是会由于操作系统的原因出现问题。

在Windows操作系统上是没有问题的。问题是我们做的是Qt for Symbian!

手机上的资源本来就是比较紧缺的,所以我们使用的时候就需要更加注意。

(2)原因解释

QPixmap依赖于硬件

QPixmap的具体实现是依赖于系统的。在Symbian系统上QPixmap是被存放在Server端的。

目前的Qt会把QPixmap都存储在graphics memory中,这明显是依赖硬件的。因此我们对QPixmap的使用需要格外注意。这也正是以上两段代码存在问题的根源。

那么Qt为什么要这么做呢?很简单,设计之初QPixmap就是用来加速显示的,例如我们在paint的时候用QPixmap就会比用其他类的效果好许多。

(3)当使用上述代码显示较小图片的时候(比如例子程序中的background.png 和apple.png)是没有问题的,图片都能在手机上正确显示。

但是当我们把图片换成一副较大图片287KB,1058 x 1058的“earth.png”的时候就出现问题了,图片无法显示,程序的界面是一片空白。

据测算,“earth.png”被完全解码后存储在graphics memory中会占用大约4.3MB的空间。如果此时还有其他加载的窗口和QPixmap,很可能就没有空间了。

(4)正确处理方式

使用QImage加载后转换成QPixmap 显示

//correct and recommended way
QImage image;
image.load( ":/pics/earth.png" );

QPainter painter(this);
QPixmap pixmapToShow = QPixmap::fromImage( image.scaled(size(), Qt::KeepAspectRatio) );
painter.drawPixmap(0,0, pixmapToShow);


可以通过QImage 进行加载的原因:

QImage是独立于硬件的,它可以同时被另一个线程访问;

QImage是存储在客户端的,对QImage的使用是非常方便和安全的;

QImage 是一种QPaintDevice,因此我们可以在另一个线程中对其进行绘制,而不需要在GUI 线程中处理,使用这一方式可以很大幅度提高UI响应速度。

(5)

QPixmap pixmapToShow = QPixmap::fromImage( image.scaled(size(), Qt::KeepAspectRatio) );


Qt::KeepAspectRatio的使用,默认参数是Qt::IgnoreAspectRatio,如果我们在程序中这么写:

QPixmap pixmapToShow = QPixmap::fromImage( image.scaled(size(), Qt::IgnoreAspectRatio) );

我们也可以直接使用QImage做显示,而不转换成QPixmap ,这要根据我们应用的具体需求来决定,如果需要的话我们可以这么写:

//correct, some times may be needed
QImage image;
image.load( ":/pics/earth.png" );

QPainter painter(this);
painter.drawImage(0,0, image);


三 IplImage* -> QPixmap

将IplImage*转为QPixmap需要两步

(1)IplImage*->QImage

(2)QImage->QPixmap

IplImage* image;
QImage *img;
.....
//将IplImage* 转为QImage
img=iplImgToQImg(image);
//将QImage转为QPixmap
QPixmap pixmapToShow =QPixmap::fromImage(img->scaled(size(), Qt::KeepAspectRatio));


IplImage->QImage转化函数

QImage * MainWindow::iplImgToQImg(IplImage *cvimage)
{
if (!cvimage)
return 0;
QImage* desImage = new QImage(cvimage->width,cvimage->height,QImage::Format_RGB32);
/*对图像的像素操作*/
for(int i = 0; i < cvimage->height; i++)  //行数循环
{
for(int j = 0; j < cvimage->width; j++)   //列数循环
{
int r,g,b;

if(3 == cvimage->nChannels)
{
b=(int)CV_IMAGE_ELEM(cvimage,uchar,i,j*3+0);
g=(int)CV_IMAGE_ELEM(cvimage,uchar,i,j*3+1);
r=(int)CV_IMAGE_ELEM(cvimage,uchar,i,j*3+2);

}
else if(1 == cvimage->nChannels)
{
b=(int)CV_IMAGE_ELEM(cvimage,uchar,i,j);
g=b;
r=b;
}

desImage->setPixel(j,i,qRgb(r,g,b));
}
}
return desImage;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: