zoukankan      html  css  js  c++  java
  • OpenCV&Qt学习之二——QImage的进一步认识

    QImage的指针问题


    接着上一篇博客:OpenCV&Qt学习之一——打开图片文件并显示,实现基本的打开图片并转换显示之后接下来将函数在分别进行封装,便于下一步的处理。代码如下:

    #include "widget.h"
    #include "ui_widget.h"
    #include <QDebug>
    Widget::Widget(QWidget *parent) :
        QWidget(parent),
        ui(new Ui::Widget)
    {
        ui->setupUi(this);
    
    }
    
    Widget::~Widget()
    {
        delete ui;
    }
    
    void Widget::on_openButton_clicked()
    {
        QString fileName = QFileDialog::getOpenFileName(this,tr("Open Image"),
                                    ".",tr("Image Files (*.png *.jpg *.bmp)"));
        qDebug()<<"filenames:"<<fileName;
        image = cv::imread(fileName.toAscii().data());
        qimg = Widget::Mat2QImage(image);
        display(qimg);                      //display by the label
    }
    
    QImage Widget::Mat2QImage(const cv::Mat &mat)
    {
        QImage img;
        Mat rgb;
        if(mat.channels()==3)
        {
            //cvt Mat BGR 2 QImage RGB
            cvtColor(mat,rgb,CV_BGR2RGB);
            img =QImage((const unsigned char*)(rgb.data),
                        rgb.cols,rgb.rows,
                        rgb.cols*rgb.channels(),
                        QImage::Format_RGB888);
        }
        else
        {
            img =QImage((const unsigned char*)(mat.data),
                        mat.cols,mat.rows,
                        mat.cols*mat.channels(),
                        QImage::Format_RGB888);
        }
        return img;
    }
    
    void Widget::display(const QImage img)
    {
        ui->imagelabel->setPixmap(QPixmap::fromImage(img));
        ui->imagelabel->resize(ui->imagelabel->pixmap()->size());
    }

    相对于OpenCV&Qt学习之一——打开图片文件并显示 中间的代码,这里的改动有限,只是把转换的功能单独封装成为一个函数QImage Widget::Mat2QImage(const cv::Mat &mat) 通过返回的方式,再调用void Widget::display(const QImage img) 来显示,本来觉得应该非常简单的,但是一运行显示的不是全白就是全黑的图像,而把

    ui->imagelabel->setPixmap(QPixmap::fromImage(img));
        ui->imagelabel->resize(ui->imagelabel->pixmap()->size());

    直接放入return之前在函数中显示就没有任何问题,也就是说,img在函数内部没有问题,但是在通过函数调用传出来的时候丢了数据,我以为是由于设置成局部变量被释放的原因,各种尝试之后仍然不行,这个问题让我郁闷了一下午。

    由于之前做的多是单片机等嵌入式平台的程序开发,所  以涉及到的语言应用都比较基础,经过多方查找才发现可能是指针问题,这里先看QImage的定义:

    img =QImage((const unsigned char*)(rgb.data),
                        rgb.cols,rgb.rows,
                        rgb.cols*rgb.channels(),
                        QImage::Format_RGB888);

    QImage格式和Mat是在数据结构上有所不同,这里的img只是对Mat格式的rgb中的数据进行重新组织,其中数据部分还是(const unsigned char*)(rgb.data),是指向rgb的指针,而问题就出在rgb上,rgb是被定义为局部变量的,在函数调用结束后,虽然值能够被正常传递,但是指针指向的位置却被释放了,因此把rgb更改为全局变量问题解决。

    这个问题在大量指针的运用中非常容易出错,而且不易发现,看来指针的运用还需要加强学习。

  • 相关阅读:
    python ipython使用
    Django ORM 操作
    Django uwsgi 基础知识
    前端 vue router 传递参数
    观察者模式和发布订阅模式
    关于重绘和回流
    Vuex入门简单示例(五)
    Vuex入门简单示例(四)
    Vuex入门简单示例(三)
    Vuex入门简单示例(二)
  • 原文地址:https://www.cnblogs.com/emouse/p/2989592.html
Copyright © 2011-2022 走看看