一. 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 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;
}