QT下对OpenCV抓取图片的显示

转载 2013年12月04日 17:08:52

1.背景

Opencv中通过摄像头捕捉到的每帧图像的数据结构是IplImage类型的,要把它显示到Qt窗口中就需要把它转化为QImage类型的图像。

2.代码

#include <QVector>
#include <cstring>

QImage MyThread::IplImageToQImage(const IplImage * iplImage,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 ", 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 ", 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 ", 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 ", iplImage->nChannels);
            }
            break;
            default:
                qDebug("IplImageToQImage: image format is not supported : depth=%d and %d channels ", 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 = QImage(qImageBuffer, width, height, QImage::Format_Indexed8).copy();
            qImage.setColorTable(vcolorTable);
        }
        else
        {
            qImage = QImage(qImageBuffer, width, height, QImage::Format_RGB32).copy();
        }
    free(qImageBuffer);
    return qImage;
}

上面完成的格式转换,接下来进行显示
摄像头获取每一帧IplImage*类型的图像,转化为QImage类型的图像,用update()发出一个paintEvent(QPaintEvent*)事件,如此不断更新图像。(IplImageToQImage中的mini和maxi默认初始化为0)

void ImageViewer::paintEvent(QPaintEvent *){
    QPainter painter(this);
    painter.drawImage(QPoint(0,0), *image);
}

bool ImageViewer::ShowImage(){
    IplImage *pImage = NULL;
    CvCapture *pCapture = NULL;
    if((pCapture = cvCaptureFromCAM(-1)) == NULL){
        cout << "Open camera failed! ";
        return false;
    }
    while((pImage = cvQueryFrame(pCapture)) != NULL){
        image = IplImageToQImage(pImage);
        update();
    }
    cvReleaseImage(&pImage);
    cvReleaseCapture(&pCapture);
    return true;
}



相关文章推荐

QT+opencv显示图片小程序窗体版

  • 2017年07月14日 15:40
  • 289KB
  • 下载

使用Qt显示openCV矩阵图片

  • 2013年05月29日 15:49
  • 5KB
  • 下载

在QT集成开发环境中用OpenCV读取一张图片并显示

在我的上一篇文章中已经配置好了OpenCV,接下来就要检验以下我们是否已经正确的配置了OpenCV。如果您还没有安装QT,在终端中直接输入下面的命令,便可以安装QT4。sudo apt-get ins...

QT+opencv显示图片小程序

  • 2017年07月14日 15:37
  • 33KB
  • 下载

用Qt5和OpenCV读取显示中文路径的图片

在进行相关编码前,请先设置好使用Qt(mingw版)下使用OpenCV的环境,具体过程可参考:http://blog.csdn.net/qiurisuixiang/article/details/86...

zynq-7000学习笔记(十五)——在QT上调用opencv加载图片并显示

PC平台:WINDOWS 10 64位 + 虚拟机Ubuntu 14.04 Xilinx设计开发套件:Xilinx_vivado_sdk_2015.4 开发板:Zed Board USB摄像头:...

OpenCV【2】---读取png图片显示到QT label上的问题

问题一:  操作图片test.png是一个365x365的PNG图片  通过OpenCV自带的GUI显示出来图像是没问题的,如下操作代码所示: QStringfileName=QFileDial...
  • FreeApe
  • FreeApe
  • 2015年12月24日 19:37
  • 2442

QT GUI界面的使用 opencv选择并显示图片于label中

QT GUI界面的使用 opencv选择并显示图片于label中

ubuntu11.04下QT4.7+OpenCV2.2开发环境搭建成功,成功打开并显示图片

0.前言       ubuntu11.04下qt4.7的安装可参考本人的博客,opencv2.2的安装可以参考这篇文章。如果qt和opencv都已经安装成功,那就往下看,否则还是先把两者都安装好了再...

谈一谈分别利用opencv、Qt、matlab动态显示图片的实现

最近遇到一个需要将图片进行动态显示的任务,图片的分辨率是320*2560,最开始的想法就是将图片看成一个320*2560大小的矩阵,然后定义一个320*320大小的小矩阵去遍历大矩阵,然后就用matl...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:QT下对OpenCV抓取图片的显示
举报原因:
原因补充:

(最多只允许输入30个字)