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

来源:互联网 发布:臭氧灯能除螨虫知乎 编辑:程序博客网 时间:2024/05/16 14:16

一. 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,提供单色图像,可以用来制作游标(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 displayedQPixmap 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 displayedQPixmap 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 wayQImage 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 neededQImage 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* 转为QImageimg=iplImgToQImg(image);//将QImage转为QPixmapQPixmap 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;}
0 0
原创粉丝点击