在使用Qt和OpenCV编程时,对于它们各自的图像类QImage和IplImage难以避免的需要互相之间的转换,下面我们就来看它们的相互转换。

1. QImage 转换为 IplImage

IplImage *QImageToIplImage(const QImage * qImage)
{
int width = qImage->width();
int height = qImage->height();
CvSize Size;
Size.height = height;
Size.width = width; IplImage *charIplImageBuffer = cvCreateImage(Size, IPL_DEPTH_8U, );
char *charTemp = (char *) charIplImageBuffer->imageData; for (int y = ; y < height; y++)
{
for (int x = ; x < width; x++)
{
int index = y * width + x;
charTemp[index] = (char) qGray(qImage->pixel(x, y));
}
}
return charIplImageBuffer;
}

2. IplImage 转换为 QImage

QImage *IplImageToQImage(const IplImage * iplImage)
{
uchar *qImageBuffer = NULL;
int width = iplImage->width; // Note here that OpenCV image is stored so that each lined is
// 32-bits aligned thus * explaining the necessity to "skip"
// the few last bytes of each line of OpenCV image buffer.
int widthStep = iplImage->widthStep;
int height = iplImage->height; switch (iplImage->depth)
{
case IPL_DEPTH_8U:
if (iplImage->nChannels == )
{
// IplImage is stored with one byte grey pixel.
// We convert it to an 8 bit depth QImage.
qImageBuffer = (uchar *) malloc(width*height*sizeof(uchar));
uchar *QImagePtr = qImageBuffer;
const uchar *iplImagePtr = (const uchar *)iplImage->imageData;
for (int y = ; y < height; y++)
{
// Copy line by line
memcpy(QImagePtr, iplImagePtr, width);
QImagePtr += width;
iplImagePtr += widthStep;
}
}
else if (iplImage->nChannels == )
{
// IplImage is stored with 3 byte color pixels (3 channels).
// We convert it to a 32 bit depth QImage.
qImageBuffer = (uchar *) malloc(width*height**sizeof(uchar));
uchar *QImagePtr = qImageBuffer;
const uchar *iplImagePtr = (const uchar *) iplImage->imageData; for (int y = ; y < height; y++)
{
for (int x = ; x < width; x++)
{
// We cannot help but copy manually.
QImagePtr[] = iplImagePtr[];
QImagePtr[] = iplImagePtr[];
QImagePtr[] = iplImagePtr[];
QImagePtr[] = ; QImagePtr += ;
iplImagePtr += ;
}
iplImagePtr += widthStep-*width;
}
}
else
{
qDebug("IplImageToQImage: image format is not supported:\
depth=8U and %d channels\n", iplImage->nChannels);
}
break; case IPL_DEPTH_16U:
if (iplImage->nChannels == )
{
// IplImage is stored with 2 bytes grey pixel.
// We convert it to an 8 bit depth QImage.
qImageBuffer = (uchar *) malloc(width*height*sizeof(uchar));
uchar *QImagePtr = qImageBuffer;
const uint16_t *iplImagePtr = (const uint16_t *)iplImage->imageData; for (int y = ; y < height; y++)
{
for (int x = ; x < width; x++)
{
// We take only the highest part of the 16 bit value.
// It is similar to dividing by 256.
*QImagePtr++ = ((*iplImagePtr++) >> );
}
iplImagePtr += widthStep/sizeof(uint16_t)-width;
}
}
else
{
qDebug("IplImageToQImage: image format is not supported:\
depth=16U and %d channels\n", iplImage->nChannels);
}
break; case IPL_DEPTH_32F:
if (iplImage->nChannels == )
{
// IplImage is stored with float (4 bytes) grey pixel.
// We convert it to an 8 bit depth QImage.
qImageBuffer = (uchar *) malloc(width*height*sizeof(uchar));
uchar *QImagePtr = qImageBuffer;
const float *iplImagePtr = (const float *) iplImage->imageData; for (int y = ; y < height; y++)
{
for (int x = ; x < width; x++)
{
uchar p;
float pf = (*iplImagePtr++); if (pf < ) p = ;
else if (pf > ) p = ;
else p = (uchar) pf; *QImagePtr++ = p;
}
iplImagePtr += widthStep/sizeof(float)-width;
}
}
else
{
qDebug("IplImageToQImage: image format is not supported:\
depth=32F and %d channels\n", iplImage->nChannels);
}
break; case IPL_DEPTH_64F:
if (iplImage->nChannels == )
{
// OpenCV image is stored with double (8 bytes) grey pixel.
// We convert it to an 8 bit depth QImage.
qImageBuffer = (uchar *) malloc(width*height*sizeof(uchar));
uchar *QImagePtr = qImageBuffer;
const double *iplImagePtr = (const double *) iplImage->imageData; for (int y = ; y < height; y++)
{
for (int x = ; x < width; x++)
{
uchar p;
double pf = * ((*iplImagePtr++) - mini) / (maxi - mini); if (pf < ) p = ;
else if (pf > ) p = ;
else p = (uchar) pf; *QImagePtr++ = p;
}
iplImagePtr += widthStep/sizeof(double)-width;
}
}
else
{
qDebug("IplImageToQImage: image format is not supported:\
depth=64F and %d channels\n", iplImage->nChannels);
}
break; default:
qDebug("IplImageToQImage: image format is not supported: depth=%d\
and %d channels\n", iplImage->depth, iplImage->nChannels);
} QImage *qImage;
if (iplImage->nChannels == )
{
QVector<QRgb> colorTable;
for (int i = ; i < ; i++)
{
colorTable.push_back(qRgb(i, i, i));
}
qImage = new QImage(qImageBuffer, width, height, QImage::Format_Indexed8);
qImage->setColorTable(colorTable);
}
else
{
qImage = new QImage(qImageBuffer, width, height, QImage::Format_RGB32);
} return qImage;
}

精简版:

QImage *IplImageToQImage(IplImage *image){
QImage *result;
if (image){
uchar * qImageBuffer = NULL;
int width = image->width;
int widthStep = image->widthStep;
int height = image->height;
QImage::Format format = QImage::Format_Invalid;
if (IPL_DEPTH_8U == image->depth && == image->nChannels){
qImageBuffer = (uchar *) malloc(width * height * * sizeof(uchar));
uchar *QImagePtr = qImageBuffer;
const uchar *iplImagePtr = (const uchar *) image->imageData;
format = QImage::Format_RGB32;
if (!qImageBuffer){
qDebug() << "Insufficient memory for image buffer!" << endl;
return result;
}
for (int y = ; y < height; y++)
{
for (int x = ; x < width; x++)
{
QImagePtr[] = iplImagePtr[];
QImagePtr[] = iplImagePtr[];
QImagePtr[] = iplImagePtr[];
QImagePtr[] = ; QImagePtr += ;
iplImagePtr += ;
}
iplImagePtr += widthStep-*width;
}
} else {
qDebug("Image format is not supported: depth=%d and %d channels\n", image->depth, image->nChannels);
return result;
}
if (qImageBuffer){
QImage *result = new QImage(qImageBuffer, image->width, image->height, format);
}
} else {
qDebug() << "Image pointer is NULL" << endl;
}
return result;
}

IplImage 与 QImage 相互转换的更多相关文章

  1. Qt OpenCV::Mat与Qt::QImage相互转换

    Mat转QImage QImage mat2qim(Mat & mat) { cvtColor(mat, mat, COLOR_BGR2RGB); QImage qim((const unsi ...

  2. qt中使用opencv处理图片 QImage 和 IplImage 相互之间转换问题

    在用opencv处理图片显示在qt label上的时候遇到不是问题 1. qt上要用qimage形式才干显示 IplImage转成 Qimage 彩色图像转换 IplImage  *fram; QIm ...

  3. 【转】OpenCV与CxImage转换(IplImage)、IplImage QImage Mat 格式互转

    最近由于在项目中用到了Opencv库,但是为了更好的显示图像还是使用了Cximage库,它可以快捷地存取.显示.转换各种图像.Opencv库用于高级图像处理与识别.为了使Cximage图像与Openc ...

  4. 更快地从IplImage转换成QImage

    转:http://blog.sina.com.cn/s/blog_5c70dfc80100qzif.html 在Qt平台上使用OpenCV肯定会遇到从IplImage到QImage的转换问题,找了很多 ...

  5. QImage和IplImage转换总结

    在arm中做图像处理,因为不支持GTK,一般都会用到QT来实现显示功能,所以不可避免的要涉及到QImage和IplImage两种图像格式之间的转换,下面总结一下转换的方法. (下面格式转换的代码都是网 ...

  6. 关于QImage和IplImage之间转换的实现

    在嵌入式系统中实现qt和opencv的处理,最基础的就是QImage和IplImage之间的转换.这样两者就可以进行一起使用图像数据,从而达到利用qt显示和利用opencv处理的功能. 下面我将贴出代 ...

  7. 知乎上有一个问题“在mfc框架中,有上面方法能直接将opencv2.0库中的Mat格式图片传递到Picture Control”中显示?

    一直以来,我使用的方法都是shiqiyu在opencvchina上面提供的引入directshow,并且采用cvvimage和cameraDs的方法.这个方法虽然在xp/win7/win8下面都能够成 ...

  8. 简易视频播放器2 (基于Qt、opencv)

    因项目需要,需要实现一个对以保存的监测视频快速查看功能. 查询网上一些资料,初步简易的实现了一下. 实际效果图: 该程序基于Qt5.4,opencv248,开发环境为win8.1 结构为: video ...

  9. openCV(二)---iOS中使用openCV的图片格式转换

    可以实现将UIImage和IplImage类型实现相互转换 //由于OpenCV主要针对的是计算机视觉方面的处理,因此在函数库中,最重要的结构体是IplImage结构. - (IplImage *)C ...

随机推荐

  1. jquery优势

    1.轻量 2.开源 3.选择器出色 可以支持几乎 css1到css3 的所有选择器 4.简单的修改页面    不同的浏览器对于css的支持程度是不同的,jquery通过封装javascript的代码, ...

  2. Win7下虚拟机个人使用小结:Virtual PC,VMware和VirtualBox

    想来用了很多年的虚拟机了,换了Win7之后,种种原因又需要使用虚拟机,这里就简单介绍和比较一下. 点击小图看大图. Virtual PC: 如果想做Windows虚拟机的话,Virtual PC在之前 ...

  3. codeforces 483B Friends and Presents 解题报告

    题目链接:http://codeforces.com/problemset/problem/483/B 题目意思:有两个 friends,需要将 cnt1 个不能整除 x 的数分给第一个friend, ...

  4. 奇怪的梦境(codevs 2833)

    题目描述 Description Aiden陷入了一个奇怪的梦境:他被困在一个小房子中,墙上有很多按钮,还有一个屏幕,上面显示了一些信息.屏幕上说,要将所有按钮都按下才能出去,而又给出了一些信息,说明 ...

  5. Eclipse 中Tomcat 启动 与直接启动Tomcat的区别

    这段时间不用Java 了突然发现在用的时候出问题了. 首先现在Eclipse和Tomcat,解压后 如图1所示: 图1: 进入里面的bin文件目录后发现有 如图2所示包含了startup.bat,st ...

  6. js 在myeclipse中报错

    转myeclipse中的js文件报错   整理一下,希望帮到 遇到此问题的哥们.姐们. 方法一:myeclipse9 很特殊 和 myeclipse10 不一样,所以myeclipse9 不能使用该方 ...

  7. snmp监控磁盘

    http://www.it165.net/os/html/201209/3438.html https://sourceforge.net/p/net-snmp/mailman/message/168 ...

  8. 如何清除sql server日志

    1.打开查询分析器,输入命令 DUMP TRANSACTION 数据库名 WITH NO_LOG 2.再打开企业管理器--右键你要压缩的数据库--所有任务--收缩数据库--收缩文件--选择日志文件-- ...

  9. 用DTD约束XML详解及示例

    文档类型定义(DTD)可定义合法的XML文档构建模块.它使用一系列合法的元素来定义文档的结构. dtd的三种引入方式    (1)引入外部的dtd文件 <!DOCTYPE 根元素名称 SYSTE ...

  10. org.apache.flume.FlumeException: NettyAvroRpcClient { host: xxx.xxx.xxx.xxx, port: 41100 }: RPC

    2014-12-19 01:05:42,141 (lifecycleSupervisor-1-1) [WARN - org.apache.flume.sink.AbstractRpcSink.star ...