Q2X 发表于 2018-4-3 14:07:47

Qt 用QLabel显示IplImage图像数据

我知道在Qt中想用QLabel显示IplImage图像数据需要先转化成QImage类型,但是我对转换的原理不是很清楚,图像数据的不同通道数、位深、相机的彩色黑白都应该怎么转换?
下面是我从网上找的的代码:
QImage* IplImage2QImage(IplImage *iplImg)
{
    int h = iplImg->height;
    int w = iplImg->width;
    int channels = iplImg->nChannels;

    QImage *qimg = new QImage(w, h, QImage::Format_RGB888);
    char *data = iplImg->imageData;

    for (int y = 0; y < h; y++, data += iplImg->widthStep)
    {
      for (int x = 0; x < w; x++)
      {
            char r, g, b, a = 0;
            if (channels == 1)
            {
                r = data;
                g = data;
                b = data;
            }
            else if (channels == 3 || channels == 4)
            {
                r = data;
                g = data;
                b = data;
            }

            if (channels == 4)
            {
                a = data;
                qimg->setPixel(x, y, qRgba(r, g, b, a));
            }
            else
            {
                qimg->setPixel(x, y, qRgb(r, g, b));
            }
      }
    }
    return qimg;

}

void Guider::GetSingleFrame()
{
    ImgData = (unsigned char *)malloc(length);
    memset(ImgData,0,length);
    ret = GetFrame(camhandle,&imagew,&imageh,&bpp,&channels,ImgData);
    if(ret == SUCCESS){
      IplImage *image = cvCreateImage(cvSize(imagew,imageh),bpp,channels);
      image->imageData = (char *)ImgData;

      IplImage *dst;
      CvSize dst_cvsize;

      dst_cvsize.width= ui->img_lpl->width();
      dst_cvsize.height = ui->img_lpl->height();

      dst = cvCreateImage(dst_cvsize,image->depth,image->nChannels);
      cvResize(image,dst,CV_INTER_LINEAR);

      qImg_capture = IplImage2QImage(dst);

      ui->img_lpl->setPixmap(QPixmap::fromImage(*qImg_capture));
      ui->img_lpl->show();
    }
}
这个只能显示8位一通道的黑白图像,显示其他的就会出问题。

shasidaran 发表于 2018-6-8 17:42:25

是在学OpenCv吧,
IplImage和cvMat都是C语言的结构体,操作起来是旧式C风格的 OpenCV的API;
OpenCV2.0后,都是C++风格了,现在建议用的是cv::Mat,这个是c++类,封装好很多

所以初学OpenCV,建议紧跟时代,用cv::Mat类

shasidaran 发表于 2018-6-8 17:50:03

然后回到你的问题,
Qt的QImage,
IplImage、cvMat、cv::Mat也好,组成大同小异,都是有一部分头成员(如图片数据尺寸、数据格式、图片数据内存空间的头指针)组成,还有就是对应的一片内存空间(实际像素值)组成。

所以这时候你的转换又分两种情况:
1、QImage和IplImage 因为是两个不同的结构,他们头可以赋值为相同的值,然后对应的像素使用同一片内存空间,这样的结果就是你改了QImage后,IplImage也会变(说白就是浅拷贝)
2、QImage和IplImage的图像数据,开辟的是两块内存空间,只是值一样,结果就是这是两个独立的图片(深拷贝)
页: [1]
查看完整版本: Qt 用QLabel显示IplImage图像数据