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读取一张图片显示在Qlabel上

开发环境:ubuntu Opencv3.0.0 QT4上一篇文章我们用OpenCV显示了一张图片,现在我们要将读取来的图片显示在QT的标签上。1首先新建一个工程 点击choose,然后一直下一步。 ...
  • Adorkable_yu
  • Adorkable_yu
  • 2017年04月15日 23:14
  • 1345

Qt中显示opencv生成图片

之前刚在QT里搭建好opencv环境时候,我想着再qt里嵌入opencv运行出来的图片,就是把opencv的运行结果放到qt界面指定的位置,不想是opencv自己独立的小窗口。运行效果(左边是open...
  • qq_25847123
  • qq_25847123
  • 2016年10月09日 00:43
  • 2288

Qt+OpenCV实时显示在地图空间中的位置

有个类似于自动行驶小车的项目,使用摄像头检测贴在地上的地标,并在上位机实时显示当前小车所处的位置,上位机是Ubuntu系统。     做上位机的界面用的是Qt,里面也配置好了OpenCV,用起来很方...
  • zilanpotou182
  • zilanpotou182
  • 2017年04月15日 19:47
  • 820

[OpenCV Qt教程] 在Qt图形界面中显示OpenCV图像的OpenGL Widget (第一部分)

本文译自:[OPENCV QT TUTORIAL] OPENGL WIDGET TO SHOW OPENCV IMAGES IN A QT GUI (FIRST PART) 此教程是关于在Qt图形界面...
  • howlclat
  • howlclat
  • 2017年02月21日 14:10
  • 1003

QT内label控件通过opencv显示图像

1.对pro进行配置,使其能够理解opencv。INCLUDEPATH+=d:\opencv249\include\opencv\ d:\opencv249\i...
  • superdont
  • superdont
  • 2014年05月18日 13:30
  • 11906

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

QT GUI界面的使用 opencv选择并显示图片于label中
  • qq_27901091
  • qq_27901091
  • 2017年07月15日 15:51
  • 838

QT 下OpenCV显示图片

OpenCV学习
  • linuxxiaolei
  • linuxxiaolei
  • 2015年07月14日 22:39
  • 1169

QT中使用opencv加载图片使用label显示

QString fileName=QFileDialog::getOpenFileName(this,tr("fileDialog"),"C:",tr("img(*png *jpg)")); ...
  • jialeheyeshu
  • jialeheyeshu
  • 2016年05月18日 17:42
  • 381

Qt对话框显示opencv读取的图像

opencv和Qt结合使用,既可以发挥opencv强大的图像处理能力,又能够发挥Qt优势使其有一个良好的交互界面。用 Qt对话框显示图片的核心,就是解决如何两种不同的图像数据类型Mat和QImage之...
  • cfqcfqcfqcfqcfq
  • cfqcfqcfqcfqcfq
  • 2016年10月19日 21:37
  • 667

(十)Qt对OpenCV支持效果很好

一直对MFC对OpenCV的支持不好而耿耿于怀,了解了Qt对OpenCV支持很好,但网上这方面的资料很少。大部分的图形交互的设计都是基于OpenCV2.0之前的数据结构lpImage进行的。最近得到了...
  • liulina603
  • liulina603
  • 2012年11月08日 14:15
  • 1677
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:QT下对OpenCV抓取图片的显示
举报原因:
原因补充:

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