OpenCV2 && Qt4 chapter1:Playing with images

1. OpenCV2 幾個主要模塊


2. loading,display,saving image.

效果圖:

頭文件:  cv::Mat image; private型的。

cpp文件:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFileDialog>
#include <QMessageBox>
#include <QImage>
#include <QPixmap>
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{

    ui->setupUi(this);

    ui->btn2->setEnabled(false);
    ui->btn3->setEnabled(false);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_btn1_clicked()
{
    // the path can not in chinese
    QString fileName = QFileDialog::getOpenFileName(this,"Open_image_caption","/root/Desktop/photos"
                                                    ,"image file(*.bmp *.jpg *.jpeg *.png)");
    QMessageBox::information(this,"title",fileName.toAscii().data());
    image = cv::imread( fileName.toAscii().data());
    if( !image.data )
    {
         QMessageBox::information(this,"title","failed in imread...returned..");
         return ;
    }
    cv::namedWindow("wzy_window");
    cv::imshow("wzy_window",image);
    ui->btn2->setEnabled(true);
    ui->btn3->setEnabled(true);

    //display in label.. QImage->QPixmax->QLabel
    QImage img((uchar *)image.data,image.cols,image.rows,QImage::Format_RGB888);
    ui->label->setPixmap(QPixmap::fromImage(img));
    ui->label->resize(ui->label->pixmap()->size());


    return ;

}

void MainWindow::on_btn2_clicked()
{

    // transformation the image.
    cv::flip(image,image,-1);// positive for horizontal
                                         // 0 for vertical,
                                  // negative for both
    cv::namedWindow("output_window");
    cv::imshow("output_window",image);

    QImage img((uchar *)image.data,image.cols,image.rows,QImage::Format_RGB888);
    ui->label->setPixmap(QPixmap::fromImage(img));
    ui->label->resize(ui->label->pixmap()->size());
}

void MainWindow::on_btn3_clicked()
{
    cv::imwrite("/tmp/output.bmp",image);
}


OpenCV2 總結:

1.學會經常切換到頭文件或實現文件去看一些聲明和定義。

cv 命名空間  cv::Mat 一個矩形的數據結構 

2. cv::Mat 圖像 讀取,顯示,保存

cv::imread()  傳的參數是string型的,QString型不行。 QString -> string   qstr.toAscii().data    (中文處理見下面。)

image=cv::imread("img.jpg");
if (!image.data) {
// no image has been created…
}       image.data 是個uchar*的指針。。It is simply set to 0 when no image has been read.

讀取: cv::imread()

顯示: cv::namedWindow() cv::imshow()

保存:cv::imwrite()      // 這個經常出錯,以後做好判斷或者異常處理

3. cv::flip 函數。   對圖像進行簡單的轉換。

cv::flip(image,result,-1);// positive for horizontal    0 for vertical           negative for both

4. 淺複製 與 深複製。cv::Mat對象。

cv::Mat image2, image3;
image2= result; // the two images refer to the same data   淺複製
result.copyTo(image3); // a new copy is created   深複製


image2,result的地址值一樣, 只有當此地址上所有對象都銷燬時,這個空間纔會被銷燬。

類中不應該返 cv::Mat對象。因爲返回的是地址,而不是值。。

class T
{
private:
cv::Mat ima;
public:
cv::Mat method() { return ima; }                                 //not good.
};



Qt總結:

1.打開一個文件對話框。

QFileDialog::getOpenFileName(this,"Open_image_caption","/root/Desktop/photos"
                                                    ,"image file(*.bmp *.jpg *.jpeg *.png)");   

2. 彈出一個消息框。

QMessageBox::information(this,"title",fileName.toAscii().data());

3. QLabe 可以顯示 QPixmap, QPixmap可以由 QImage構造, QImage可以由 cv::Mat構造。

QImage img((uchar *)image.data,image.cols,image.rows,QImage::Format_RGB888);
    ui->label->setPixmap(QPixmap::fromImage(img));
    ui->label->resize(ui->label->pixmap()->size());


4. 中文路徑的問題。(轉)

http://blog.sina.com.cn/s/blog_6923201d0100zrjp.html

1. QT中文路徑亂碼問題
QT中的string使用的是QString類,C++中字符串爲string或者char*,在使用OpenCV的imread讀取QFileDialog打開的文件目錄時,如果文件路徑含有中文編碼,使用imread讀取圖片的時候,會出現異常。我使用一下方法順利的解決了這一問題:

void Test::on_bt_openImage_clicked()
{
     QTextCodec* codec=QTextCodec::codecForName("GB2312");
    QTextCodec::setCodecForCStrings(codec);
     QTextCodec::setCodecForTr(codec);
    QTextCodec::setCodecForLocale(codec);
     QString fileName =QFileDialog::getOpenFileName(this,
          tr("Open Image"),".",
          tr("Image Files(*.png *.jpg *.jpeg *.bmp)"));
     if(!fileName.isEmpty())
     {
          image=cv::imread(fileName.toAscii().data());
          cv::namedWindow("OriginalImage");
          cv::imshow("OriginalImage", image);
     }
}

2.在發佈程序的時候,在一臺沒有配置任何編譯環境的“裸機”上運行發佈後的程序時,雖然在中文字符串前面加了tr,但是中文還是會變成亂碼,一種比較簡單可行的解決方案就是,在main.cpp文件中加入下面這部分代碼
     QTextCodec* codec=QTextCodec::codecForName("System");
     QTextCodec::setCodecForCStrings(codec);
     QTextCodec::setCodecForTr(codec);
     QTextCodec::setCodecForLocale(codec);
在發佈程序的
說明:其實問題1,中的"GB2312" 同樣可以用"System"代替

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章