zoukankan      html  css  js  c++  java
  • OpenCV 中的图像结构IPLImage 和 Qt中QImage之间的转换源代码

    //IplImageToQImage.h


    #ifndef QTIPL_H
    #define QTIPL_H

    #include <iostream>
    #include <cstring>
    #include <qimage.h>
    #include "cv.h"
    #include <QVector>


    using std::string;
    using std::iostream;
    //const int QImage_IgnoreEndian = 2;

    QImage *IplImageToQImage(const IplImage * iplImage, uchar **data, double mini=0.0, double maxi=0.0);
    IplImage *QImageToIplImage(const QImage * qImage);

    #endif
    /////////////////////////

    //-------------------------------------------------------------------------
    //C++
    /*IplImageToQImage.cpp
    *
    * Creation : 23th april 2003
    * last modified : 2007.07.12
    * Author(s) : WEI Kun
    *
    * Contents: -Interface between qt Images and openCV Images
    *
    */

    //#include <stdint>
    #include "IplImageToQImage.h"

    inline int align(int size, int align)
    {
        return (size + align - 1) & -align;
    }

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


    /* Usage:
    QImage *qi = IplImageToQImage(iplCurrentImage, &data);
    QPixmap pix = QPixmap(*qi);
    delete qi;
    if(data)
    free(data);
    cvReleaseImage(&iplCurrentImage);
    */
    QImage *IplImageToQImage(const IplImage * iplImage, uchar **data, double mini, double maxi)
    {
        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)
            {
            /* OpenCV image 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)
            {
                /* OpenCV image 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)
            {
            /* OpenCV image 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 *);
                const unsigned int *iplImagePtr = (const unsigned int *)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(unsigned int)-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)
             {
            /* OpenCV image 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 = 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(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;
        QVector<QRgb> vcolorTable;
        if (iplImage->nChannels == 1)
        {
            // We should check who is going to destroy this allocation.
            QRgb *colorTable = new QRgb[256];
            for (int i = 0; i < 256; i++)
            {
               colorTable[i] = qRgb(i, i, i);
               vcolorTable[i] = colorTable[i];
            }
            qImage = new QImage(qImageBuffer, width, height, QImage::Format_Indexed8);
            qImage->setColorTable(vcolorTable);
        }
        else
        {
            qImage = new QImage(qImageBuffer, width, height, QImage::Format_RGB32);
        }
        *data = qImageBuffer;
        return qImage;
    }

  • 相关阅读:
    Brackets 前端编辑器试用
    java面试题之第一回
    java数据类型
    [转]JAVA标识符和关键字
    Servlet的几个关键知识点
    一个Servlet中可以有多个处理请求的方法
    基于java的聊天室/群发控制台程序
    java 创建string对象机制 字符串缓冲池 字符串拼接机制
    git 常用命令
    ajax axios 下载文件时如何获取进度条 process
  • 原文地址:https://www.cnblogs.com/wqj1212/p/1518596.html
Copyright © 2011-2022 走看看