Recientemente, mi proyecto ha encontrado una pared en su camino. Tenía que pasar una “IplImage” en escala de grises a una “QImage”.
Encontré esa página, donde había un completo método para cambiar de formato las imágenes.
OpenCV 中的图像结构IPLImage 和 Qt中QImage之间的转换源代码
El problema era que, cuando tenía que pasar la imagen de un solo canal a QImage. Por un motivo desconocido, no me aceptaba la imagen y salía un “Runtime Error”.
Aquí dejo el método que he utilizado para pasar las imágenes en escala de grises a QImage. No está comentado, pero es muy parecido al del link anterior.
Nota: Solo trata las imágenes en IPL_DEPTH_8U
void Webcam::getQtFrame(IplImage* parFrame)
{
unsigned char *qImageBuffer = NULL;
int width = parFrame->width;
int widthStep = parFrame->widthStep;
int height = parFrame->height;
QImage qImage;
QVector<QRgb> vcolorTable;
switch(parFrame->depth){
case IPL_DEPTH_8U:
if (parFrame->nChannels == 1) {
qImageBuffer = (unsigned char *) malloc(width*height*4*sizeof(unsigned char));
unsigned char *QImagePtr = qImageBuffer;
const unsigned char *iplImagePtr = (const unsigned char *) parFrame->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[0];
QImagePtr[2] = iplImagePtr[0];
QImagePtr[3] = 0;
QImagePtr += 4;
iplImagePtr += 1;
}
iplImagePtr += widthStep-1*width;
}
}
else if (parFrame->nChannels == 3) {
qImageBuffer = (unsigned char *) malloc(width*height*4*sizeof(unsigned char));
unsigned char *QImagePtr = qImageBuffer;
const unsigned char *iplImagePtr = (const unsigned char *) parFrame->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;
}
}
break;
}
qImage = QImage(qImageBuffer, width, height, QImage::Format_RGB32);
emit renderedImage(qImage);
}
Simplemente he cogido el método para pasar los 3 canales y he copiado el mismo canal en los otros dos restantes.
Sé que es un poco chapuza y poco optimo, así que si alguien tiene alguna idea será bien recibida.
Espero que sea de ayuda,
Ionthas.