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更改為全局變量問題解決。
這個問題在大量指針的運用中非常容易出錯,而且不易發現,看來指針的運用還需要加強學習。