學習OpenCV有一些小日子了,發現羣裏還有不少初學OpenCV的人像我當初同樣跌跌撞撞處處找資料,因此在這裏把學習筆記分享給你們,但願有志學習OpenCV進行計算機視覺活動的小夥伴們能少走一些彎路。 html
通過多方面查閱資料,瞭解到Qt開發平臺對OpenCV的支持很好,可是在網上這方面的資料不多,能查到的大部分的圖形交互設計都是基於OpenCV2.0以前的數據結構IplImage,而OpenCV如今官方已經更新到2.4.9版本了。偶然發現一本好書最近獲得了一本好書《 OpenCV 2 Computer Vision Application Programming Cookbook》,下載的連接爲http://ishare.iask.sina.com.cn/f/20485520.html?retcode=0, 2011年5月出版,全書都是基於OpenCV2.2版本的實現,採用了新的數據結構,該書如今已經有中文版《OpenCV2計算機視覺編程手冊》,2013年7月科學出版社出版。我這裏強烈建議利用C++開發的朋友們不要再使用老版本的數據結構了,實在影響開發效率。至於你們最熟悉的參考書《learning OpenCV》和《OpenCV教程——基礎篇》這兩本廣爲流傳的書,個人見解是已經遠遠不能知足OpenCV新版本的學習了。老版本的OpenCV頭文件的包含格式通常是: 編程
#include "cv.h" #include "highgui.h"
而2.2之後的版本頭文件包含通常爲:數據結構
#include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp>
爲了保持對以前版本的兼容,這些頭文件仍然可以使用,可是建議使用新的包含方式。函數
在Qt中,信號與槽是最重要的機制,這裏咱們能夠建立一個按鈕、或者菜單、工具條,來做爲發射信號的載體,用一個槽函數來接收打開這個動做。 工具
QPushButton OpenImageButton = new QPushButton( tr("Find Image") ); OpenImageButton->setDefault( false ); OpenImageButton->setEnabled( true );
void qttest1::on_OpenImage_clicked() { QString fileName = QFileDialog::getOpenFileName( this, tr( "Open Image" ), ".", tr("Image Files(*.png*.jpg*.jpeg*.bmp)")); image = cv::imread( fileName.toLocal8Bit().data()); cv::imshow("Source Image", image); }
上面的函數已經實現了打開並顯示圖片。咱們再添加一個按鈕,並定義一個函數來對圖片進行操做。學習
void qttest1::on_Process_clicked() { cv::flip(image, image, 1); cv::namedWindow("Output Image"); cv::imshow("Output Image", image); }
對於初學者,這些工做都作完以後,固然不要忘記鏈接信號與槽。ui
connect(OpenImageButton,SIGNAL(clicked()),SLOT(on_OpenImage_clicked()));
connect(ProcessButton,SIGNAL(clicked()),SLOT(on_Process_clicked()));
這些工做作完之後,就能夠打開並顯示圖片啦!this
固然,有些同窗可能會出現下面這樣的狀況,記得在你的析構函數裏釋放對象,spa
cvDestroyAllWindows(); 設計
按理說,OpenCV2是自動釋放對象的,樓主這裏尚未搞清楚,也請搞清楚的同窗留言,很是感謝。
單獨彈出一個窗口並顯示老是給人突兀的感受,下面實現Qt的窗體中顯示圖片,顯示的方法有不少,不一樣的顯示方法存在着效率等各方面的問題,這裏使用QImage轉QPixmap,而後用QLabel::setPixmap()來完成顯示,還有比較經常使用的方法是在paintEvent()中直接畫,具體的差別沒有去探究。
咱們寫一個小函數來實現:
void qttest1::displayMat(cv::Mat image) { cv::Mat rgb; QImage img; if(image.channels()==3) { //cvt Mat BGR 2 QImage RGB cv::cvtColor(image,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*)(image.data), image.cols,image.rows, image.cols*image.channels(), QImage::Format_RGB888); } imagelabel->setPixmap(QPixmap::fromImage(img)); imagelabel->resize(imagelabel->pixmap()->size()); }
最後的效果是這樣,是否是簡潔明瞭了不少?