OpenCV integration

OpenCV integration

  1. is there someone out there working with both OpenCV and Qt 4.x already?
  2. How can I display the captured frames in a Qt application?
  3. Are there any recommendations as to which drawing functions should be used (e.g. which are faster?)
Basically you have two choices - either using or not using OpenGL. The first approach requires you to use QGLWidget and to display images by binding them as textures (using bindTexture()) and using those textures on a rectangle (preferably square one) which you display in the GL widget. With the other approach you will be displaying images on aQLabel object using QLabel::setPixmap(). The GL approach will be much faster but requires more coding.


// the individual channels for the IplImage
tchannel0 			= cvCreateImage(frame_size, IPL_DEPTH_8U, 1);
tchannel1 			= cvCreateImage(frame_size, IPL_DEPTH_8U, 1);
tchannel2 			= cvCreateImage(frame_size, IPL_DEPTH_8U, 1);
tchannel3 			= cvCreateImage(frame_size, IPL_DEPTH_8U, 1);
 
// set all elements in tchannel0 (alpha channel) to 255
cvSet(tchannel0,cvScalarAll(255),0);
 
// with cframe being the captured frame (3 channel RGB)
// and dframe the frame to be displayed
cvSplit(cframe, tchannel1, tchannel2, tchannel3, NULL);
cvMerge(tchannel1, tchannel2, tchannel3, tchannel0, dframe);
 
// point to the image data stored in the IplImage*
const unsigned char * data = (unsigned char *)(dframe->imageData);
 
// read other parameters in local variables
int width 			= ocv_image->width;
int height			= ocv_image->height;
int bytesPerLine 	= ocv_image->widthStep;
 
// imageframe is my QLabel object
qimage = QImage( data, width, height, bytesPerLine, QImage::Format_RGB32 );	
ui.imageframe->setPixmap(pixmap->fromImage(qimage, 0));



#ifdef OPCAMENABLE
 
#include "cv.h"
#include "highgui.h"
#include <stdio.h>
#include <ctype.h>
 
static QImage IplImageToQImage(const IplImage  *iplImage, uchar **data , bool mirroRimage = true )
{
  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 *)iplImage->imageData;
 
        for (int y = 0; y < height; ++y)
        {
          for (int x = 0; x < width; ++x)
            *QImagePtr++ = ((*iplImagePtr++) >> 8); // We take only the highest part of the 16 bit value. It is similar to dividing by 256.
          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)
      {
        /* 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)
            *QImagePtr++ = (uchar)(255 * ((*iplImagePtr++)));
          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)
            *QImagePtr++ = (uchar)(255 * ((*iplImagePtr++)));
          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);
    QImage gd0 = qImage->mirrored(false,mirroRimage);
    *data = qImageBuffer;
    QColor textColor = Qt::black;
    QColor fillrectcolor = Qt::red;
    QColor shapepicture = Qt::white;
    QImage gd = gd0.scaledToWidth(350);
    QDateTime now = QDateTime::currentDateTime ();
    QString selectionText = now.toString("dd.MM.yyyy hh:mm:ss");
    QPainter p(&gd);
    p.setRenderHint(QPainter::Antialiasing, true);
 
    QFontMetrics fm( qApp->font() );
    int stringWidth = fm.width(selectionText);
    int stringHeight = fm.ascent();
    const int sx = gd.width() - stringWidth - 5;
    QPen pen;
    pen.setStyle( Qt::SolidLine );
    pen.setWidth( 2 );
    pen.setColor( textColor );
    p.setPen( pen);
    p.drawText(QPointF(sx - 1 ,gd.height() - 2 - stringHeight - 1),selectionText);
    pen.setColor( fillrectcolor );
    p.setPen( pen);
    p.drawText(QPointF(sx,gd.height() - 2 - stringHeight),selectionText);
 
  return gd;
}
 
 
 
#endif




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值