IplImage 与 QImage 相互转换

在使用Qt和OpenCV编程时,对于它们各自的图像类QImage和IplImage难以避免的需要互相之间的转换,下面我们就来看它们的相互转换。

1. QImage 转换为 IplImage

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, );
char *charTemp = (char *) charIplImageBuffer->imageData; for (int y = ; y < height; y++)
{
for (int x = ; x < width; x++)
{
int index = y * width + x;
charTemp[index] = (char) qGray(qImage->pixel(x, y));
}
}
return charIplImageBuffer;
}

2. IplImage 转换为 QImage

QImage *IplImageToQImage(const IplImage * iplImage)
{
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 == )
{
// IplImage 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 = ; y < height; y++)
{
// Copy line by line
memcpy(QImagePtr, iplImagePtr, width);
QImagePtr += width;
iplImagePtr += widthStep;
}
}
else if (iplImage->nChannels == )
{
// IplImage is stored with 3 byte color pixels (3 channels).
// We convert it to a 32 bit depth QImage.
qImageBuffer = (uchar *) malloc(width*height**sizeof(uchar));
uchar *QImagePtr = qImageBuffer;
const uchar *iplImagePtr = (const uchar *) iplImage->imageData; for (int y = ; y < height; y++)
{
for (int x = ; x < width; x++)
{
// We cannot help but copy manually.
QImagePtr[] = iplImagePtr[];
QImagePtr[] = iplImagePtr[];
QImagePtr[] = iplImagePtr[];
QImagePtr[] = ; QImagePtr += ;
iplImagePtr += ;
}
iplImagePtr += widthStep-*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 == )
{
// IplImage 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 = ; y < height; y++)
{
for (int x = ; x < width; x++)
{
// We take only the highest part of the 16 bit value.
// It is similar to dividing by 256.
*QImagePtr++ = ((*iplImagePtr++) >> );
}
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 == )
{
// IplImage 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 = ; y < height; y++)
{
for (int x = ; x < width; x++)
{
uchar p;
float pf = (*iplImagePtr++); if (pf < ) p = ;
else if (pf > ) p = ;
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 == )
{
// 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 = ; y < height; y++)
{
for (int x = ; x < width; x++)
{
uchar p;
double pf = * ((*iplImagePtr++) - mini) / (maxi - mini); if (pf < ) p = ;
else if (pf > ) p = ;
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;
if (iplImage->nChannels == )
{
QVector<QRgb> colorTable;
for (int i = ; i < ; 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);
} return qImage;
}

精简版:

QImage *IplImageToQImage(IplImage *image){
QImage *result;
if (image){
uchar * qImageBuffer = NULL;
int width = image->width;
int widthStep = image->widthStep;
int height = image->height;
QImage::Format format = QImage::Format_Invalid;
if (IPL_DEPTH_8U == image->depth && == image->nChannels){
qImageBuffer = (uchar *) malloc(width * height * * sizeof(uchar));
uchar *QImagePtr = qImageBuffer;
const uchar *iplImagePtr = (const uchar *) image->imageData;
format = QImage::Format_RGB32;
if (!qImageBuffer){
qDebug() << "Insufficient memory for image buffer!" << endl;
return result;
}
for (int y = ; y < height; y++)
{
for (int x = ; x < width; x++)
{
QImagePtr[] = iplImagePtr[];
QImagePtr[] = iplImagePtr[];
QImagePtr[] = iplImagePtr[];
QImagePtr[] = ; QImagePtr += ;
iplImagePtr += ;
}
iplImagePtr += widthStep-*width;
}
} else {
qDebug("Image format is not supported: depth=%d and %d channels\n", image->depth, image->nChannels);
return result;
}
if (qImageBuffer){
QImage *result = new QImage(qImageBuffer, image->width, image->height, format);
}
} else {
qDebug() << "Image pointer is NULL" << endl;
}
return result;
}
上一篇:Centos7 修改SSH 端口


下一篇:js中如何获取纯正的undefined?