关于QImage和IplImage之间转换的实现 .

来源:互联网 发布:微软的人工智能 编辑:程序博客网 时间:2024/05/29 12:50

在嵌入式系统中实现qt和opencv的处理,最基础的就是QImage和IplImage之间的转换。这样两者就可以进行一起使用图像数据,从而达到利用qt显示和利用opencv处理的功能。

下面我将贴出代码:

头文件: IplImageToQImage.h

<code>#ifndef IPLIMAGETOQIMAGE_H

 #define IPLIMAGETOQIMAGE_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 // IPLIMAGETOQIMAGE_H 
 </code> 
  
 函数文件 IplImageToQImage.cpp 
  
 #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] = (unsigned char) qGray(qImage->pixel(x, y)); 
  } 
  } 
 
  return charIplImageBuffer; 
 } 
 
 
 
 QImage *IplImageToQImage(const IplImage * iplImage, uchar **data, double mini, double maxi) 
 { 
  uchar *qImageBuffer = NULL; 
 
  int width = iplImage->width; 
 
 
  int widthStep = iplImage->widthStep; 
  int height = iplImage->height; 
 
  switch (iplImage->depth) 
  { 
  case IPL_DEPTH_8U: 
  if (iplImage->nChannels == 1) 
  { 
   
 
  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) 
  { 
   
  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) 
  { 
   
  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) 
  { 
   
  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) 
  { 
   
  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; 
 } 

本篇文章来源于 Linux公社网站(www.linuxidc.com)  原文链接:http://www.linuxidc.com/Linux/2011-05/36480.htm

原创粉丝点击