IplImage 与 QImage 相互转换

在使用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, 1);
    char *charTemp = (char *) charIplImageBuffer->imageData;

    for (int y = 0; y < height; y++)
    {
        for (int x = 0; 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 == 1)
        {
            // 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 = 0; y < height; y++)
            {
                // Copy line by line
                memcpy(QImagePtr, iplImagePtr, width);
                QImagePtr += width;
                iplImagePtr += widthStep;
            }
        }
        else if (iplImage->nChannels == 3)
        {
            // IplImage is stored with 3 byte color pixels (3 channels).
            // We convert it to a 32 bit depth QImage.
            qImageBuffer = (uchar *) malloc(width*height*4*sizeof(uchar));
            uchar *QImagePtr = qImageBuffer;
            const uchar *iplImagePtr = (const uchar *) iplImage->imageData;

            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    // We cannot help but copy manually.
                    QImagePtr[0] = iplImagePtr[0];
                    QImagePtr[1] = iplImagePtr[1];
                    QImagePtr[2] = iplImagePtr[2];
                    QImagePtr[3] = 0;

                    QImagePtr += 4;
                    iplImagePtr += 3;
                }
                iplImagePtr += widthStep-3*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 == 1)
        {
            // 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 = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    // We take only the highest part of the 16 bit value.
                    // It is similar to dividing by 256.
                    *QImagePtr++ = ((*iplImagePtr++) >> 8);
                }
                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 == 1)
        {
            // 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 = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    uchar p;
                    float pf = (*iplImagePtr++);

                    if (pf < 0) p = 0;
                    else if (pf > 255) p = 255;
                    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 == 1)
        {
            // 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 = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    uchar p;
                    double pf = 255 * ((*iplImagePtr++) - mini) / (maxi - mini);

                    if (pf < 0) p = 0;
                    else if (pf > 255) p = 255;
                    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 == 1)
    {
        QVector<QRgb> colorTable;
        for (int i = 0; i < 256; 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 *QtVideoCapture::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 && 3 == image->nChannels){
            qImageBuffer = (uchar *) malloc(width * height * 4 * 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 = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    QImagePtr[0] = iplImagePtr[0];
                    QImagePtr[1] = iplImagePtr[1];
                    QImagePtr[2] = iplImagePtr[2];
                    QImagePtr[3] = 0;

                    QImagePtr += 4;
                    iplImagePtr += 3;
                }
                iplImagePtr += widthStep-3*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;
}
时间: 2024-11-05 12:12:06

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

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

在用opencv处理图片显示在qt label上的时候遇到不是问题 1. qt上要用qimage形式才能显示 IplImage转成 Qimage 彩色图像转换 IplImage  *fram; QImage image((const uchar*)fram->imageData, fram->width, fram->height, QImage::Format_RGB888); 在用opencv二值化以后你再转换发现出现label里面显示多个画面而且还有彩色的怎么回事 这时候得换参数

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

最近由于在项目中用到了Opencv库,但是为了更好的显示图像还是使用了Cximage库,它可以快捷地存取.显示.转换各种图像.Opencv库用于高级图像处理与识别.为了使Cximage图像与Opencv图像交互,写了个Cximage转换到IplImage的类. OpenCV2CXimage.h #pragma once /* * 类说明:OpenCV图像与CXimage图像互转 * 用于OpenCV的图像与CXimage图像格式互转进行封装. OpenCV的图像位数必须是大等于8的整数倍,支持B

QImage和IplImage转换总结

在arm中做图像处理,因为不支持GTK,一般都会用到QT来实现显示功能,所以不可避免的要涉及到QImage和IplImage两种图像格式之间的转换,下面总结一下转换的方法. (下面格式转换的代码都是网友写的,我这里只是归纳修改了一下) IplImage 转换为 QImage 方法1 [plain] view plain copy QImage *IplImageToQImage(const IplImage *img) { QImage *qmg; cvCvtColor(img,img,CV_B

【转】Mat、Ipllmage与 QImage 的相互转换

(1) cv::Mat ->  QImage OpenCV存储图片默认使用BGR顺序,而QImage使用RGB顺序,所以需要用cvtColor转换一下. 使用QImage如下构造函数:QImage(uchar * data, int width, int height, Format format) QImage mat2qimage(const Mat& mat) {      Mat rgb;      cvtColor(mat, rgb, CV_BGR2RGB);       retu

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

一直以来,我使用的方法都是shiqiyu在opencvchina上面提供的引入directshow,并且采用cvvimage和cameraDs的方法.这个方法虽然在xp/win7/win8下面都能够成果使用,但是一直以来我都没有动机去深入看一看这个方法.这次在知乎上面看到 jie wu 提出的“将Opencv窗口添加到PictureControl”中的方法,感到思路很好,进行了具体实现 http://pan.baidu.com/s/1nuixdhR 具体可以看代码,我帖一些主要代码 void C

opencv基础知识------IplImage, CvMat, Mat 的关系和相互转换

Mat,cvMat和IplImage这三种类型都可以代表和显示图像,但是,Mat类型侧重于计算,数学性较高,openCV对Mat类型的计算也进行了优化.而CvMat和IplImage类型更侧重于“图像”,opencv对其中的图像操作(缩放.单通道提取.图像阈值操作等)进行了优化.在opencv2.0之前,opencv是完全用C实现的,但是,IplImage类型与CvMat类型的关系类似于面向对象中的继承关系.实际上,CvMat之上还有一个更抽象的基类----CvArr,这在源代码中会常见. 一.

IplImage, CvMat, Mat 的关系和相互转换(转)

(看到的一篇非常好的文章,讲opencv内部类之间的关系的.) opencv中常见的与图像操作有关的数据容器有Mat,cvMat和IplImage,这三种类型都可以代表和显示图像,但是,Mat类型侧重于计算,数学性较高,openCV对Mat类型的计算也进行了优化.而CvMat和IplImage类型更侧重于“图像”,opencv对其中的图像操作(缩放.单通道提取.图像阈值操作等)进行了优化.在opencv2.0之前,opencv是完全用C实现的,但是,IplImage类型与CvMat类型的关系类似

IplImage 与 CBitmap类 的相互转换

 在VC中利用OpenCV做图像处理程序时,有时需要把IpImage 类型和CBitmap类型相互转换,这样就可以利用VC中的GDI+函数对图像进行某些特殊的显示和处理,非常方便.这里是本人项目中写的两个转换小函数,仅供参考,转载注明,这样方便发现问题的朋友联系我及时修改. IplImage转换为CBitmap类型 CBitmap *IplImage2CBitmap(const IplImage *pImage) { if( pImage && pImage->depth ==

FlyCapture2 fc2Image OpenCV IplImage Conversion 两种图像格式之间的转换

fc2Image是FlyCapture SDK的C语言库中的图片格式,由于在Windows上的MinGW无法编译FlyCapture2的C++库,只能使用C语言库,所以当我们在同时使用OpenCV的图像格式IplImage时,有时候就需要两种格式相互转换.如果需要FlyCapture2 Image和OpenCV IplImage之间的转换,可以参见我之前的博客OpenCV IplImage FlyCapture2 Image Conversion 两种图像类的相互转化.我们先来分别看看两种图像格