Install OpenCV Library for Qt Creator (update for 64bit)

Qt 是一個好用且完整的 GUI (Graphical User Interface) 開發程式,本身也提供一個 IDE (Integrated Development Environment) 『Qt Creator』來開發 C++ 專案。這裡要說明如何在 Qt Creator 上建置 OpenCV 的開發環境,讓 Qt 與 OpenCV 結合在一起。雖然 Qt 提供 Visual Studio 的 plug-in,可直接在 VC 上寫 GUI,但透過 Qt Creator 來設計 GUI 會比較快速且美觀。

大致流程可分為,1. Qt 安裝和 OpenCV 安裝;2. 用 mingw compiler 編譯 OpenCV library;3. Qt 專案上的環境設置。

1.Qt 安裝和 OpenCV 安裝

http://www.qt.io/download/ 點入 Qt download 頁面,回答一些問題及輸入基本資料後,Qt 會依據你的作業系統推薦安裝版本,只要按下 Download Now,就會開始安裝了。

2016-03-23_140954

安裝完後就可以使用 Qt Creator 來開發 C++ 專案了,但目前還無法使用 OpenCV。

2016-03-23_141158

接著到 http://opencv.org/ 安裝 OpenCV,選擇所屬的作業系統來安裝,安裝完後在 opencv 資料夾裡面會有兩個子資料夾,分別是C:\opencv\build 和 C:\opencv\sources。

2.compile OpenCV library for mingw/g++ compiler

(1) 到 https://cmake.org/download/ 下載 Cmake,且安裝至 C:\。將系統變數 Path 加入下列 Qt\bin 與 Cmake\bin 兩個路徑。(電腦>>內容>>進階系統設定>>環境變數>> path)

C:\Qt\Tools\mingw492_32\bin

C:\cmake-3.5.0-win32-x86\bin

(2) 新增資料夾 C:\opencv-mingw,開啟 cmake-gui.exe 設定 source code :C:/opencv/sources 和 build the binaries : C:\opencv-mingw。2016-03-23_142654

按下 Configure,選擇 MinGW Makefiles 與 Specify native compilers。2016-03-23_142849

選擇編譯器,到剛安裝 Qt 的資料夾裡面,找已經安裝好的 compiler mingw/g++。

2016-03-23_143359

接著就可以按下 Generate。將 WITH_QT 給打勾。打勾之後,再 Configure 一次,然後 Generate,這樣就完成了初步安裝。2016-03-23_143719

(3) 編譯 OpenCV library。打開 cmd console 到 C:\opencv-mingw,輸入 :  mingw32make。建置需要一些時間...2016-03-23_144230

完成後再輸入 : mingw32make install 2016-03-23_144605現在你已經完成 OpenCV 的建置了,可以在 Qt Creator 上 使用 OpenCV library。

3.在 Qt Creator 上新增專案

新增一個 Qt Widget Application,

2016-03-23_145305

在 pro 裡面設定 includepath 和 libraries location :

INCLUDEPATH += C:\\opencv-mingw\\install\\include
LIBS += -LC:\\opencv-mingw\\install\\x86\\mingw\\lib \
-llibopencv_core2412.dll \
-llibopencv_highgui2412.dll \
-llibopencv_imgproc2412.dll

2016-03-23_145747

接著就可以在 Qt IDE 上面寫 OpenCV 的 code 了,以下是簡單的 OpenCV image read & show 的程式。

#include "mainwindow.h"
#include <QApplication>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/imgcodecs/imgcodecs.hpp>

using namespace cv;

int main(int argc, char *argv[])
 {
 //QApplication a(argc, argv);
 //MainWindow w;
 //w.show();

//return a.exec();
 Mat3b in_img;
 in_img = imread("D://6_QT//lena_std.bmp",1);
 imshow("test", in_img);
 waitKey(0);

return 0;
 }

 

2016-03-23_150556

 

 

4. For Windows 64 bit 環境

在 64 bit 安裝與上述的步驟一樣,但有些要特別注意的地方。

第一,Qt Download 並沒有提供 64bit Source,所以到以下目錄去下載,

https://sourceforge.net/projects/qt64ng/files/qt/x86-64/5.4.1/mingw-4.9/sjlj/

並且安裝至 C:\Qt,除了安裝 64bit 外,還要至 Qt 官網下載 32bit 版本,在官網點選 install online 後,選擇一個版本(這裡以 5.6版為例) 和 Tools (Qtcreator & mingw492_32),一樣安裝至 C:\Qt 資料夾內。而 OpenCV 版本的話,我下載最新版本( OpenCV3.2.0, 2017/05)。

第二,資料都安裝妥當後,接下來設定電腦環境變數,除了在 32bit 所提到的

C:\Qt\Tools\mingw492_32\bin

C:\cmake-3.5.0-win32-x86\bin

還要加入以下兩個路徑,

C:\Qt\qt-5.4.1-x64-mingw492r1-sjlj-opengl-rev1\mingw64\bin (64bit 版本)

C:\Qt\Tools\mingw492_32\i686-w64-mingw32\bin

接下來重新開機後,就可以開始上述 2. CMake 的步驟了。

第三,mingw32-make install 完畢之後,將

C:\opencv-mingw\install\x86\mingw\bin

也加入系統環境變數裡。且在 pro 裡面設定 includepath 和 libraries location 時,

LIBS 多加入 -llibopencv_imgcodecs320.dll (因為 imread 在 OpenCV3 之後被定義到 imgcodecs 裡面)。

完成以上的步驟後,一樣可以在 64bit 環境下,用 QtCreator 寫 OpenCV 。


 

reference : 

http://www.laganiere.name/opencvCookbook/chap1s1_2.shtml

https://zahidhasan.wordpress.com/2014/08/19/qt-5-3-1-64-bit-mingw-windows/

reference for 64 bit :

https://wiki.qt.io/How_to_setup_Qt_and_openCV_on_Windows

http://stackoverflow.com/questions/34497099/opencv-undefined-reference-to-imread

Changing the icon of an exe in VC2008 & Qt Creator (執行檔圖示的更改)

在程式設計完成後,執行檔(.exe) 圖示永遠都長得一樣,只是替換不同名稱而已。程式越寫越多就想要更改 .exe 的 icon 來區別不同的執行檔。

更換執行檔的圖示基本上有兩個步驟,(1) 產出想要的 .ico 圖檔(2) 在 compile 之前完成 icon 的設定

(1) 產出 .ico 圖檔

基本上我們常見的 icon 都是簡單明瞭的二維圖像,這裡推薦兩個 icon 圖集,可以從這裡面下載 .png 來做修改,或直接下載 .ico 檔。(個人比較推薦 IconArchive,這裡面的 icon 內容比較生動活潑。)

Iconfinder :: https://www.iconfinder.com/

IconArchive :: http://www.iconarchive.com/

或者如果本身有設計好的圖檔,可以透過 http://convertico.com/ 將圖檔轉成 .ico 檔。

上圖說明就是將黑蝙蝠圖檔,改成藍色蝙蝠,再轉成 .ico 檔。

 

(2) 在 compile 前完成 icon 設定

<1> in VC2008

在 project 工作列表上 >> 檢視(V) >> 資源檢視(R);

在 project 名稱上按下右鍵  >> 加入 >> 資源(R);

點選 icon。此時你已經新增 icon1.ico 到你的 project 資料夾裡面了。

接著就把我剛剛的 bat-icon-blue.ico 檔案改成 icon1.ico ,並且複製到 project 資料夾裡覆蓋掉原本的 icon1.ico 就OK了,然後再重新 compile 後,就可以看到 .exe 執行檔的 icon 被改成蝙蝠的圖示了。

<2> in Qt Creator

在 project 上按右鍵 >> 新增檔案... >> General >> Empty File >> 輸入 test.rc 檔名;

接著會在其他檔案內看到新增的檔案,接著在 test.rc 裡面編輯:

IDI_ICON1 ICON DISCARDABLE "bat-icon-blue.ico"

接著回到 .pro 檔,在

DISTFILES += \

test.rc   下加入

RC_FILE += \

test.rc

 

然後再重新 compile 後,就可以看到 qtest.exe 執行檔的 icon 也順利被更換了。

 

QThread & Taipei101 Fireworks in OpenGL

2015-12-31_130012

在 2015 的最後一天,就用 Taipei101 Firework 這個程式來做個階段型的結尾吧~猶如降龍十八掌的第十八式,集結前面所學,所施展出來的招式。今天這個 Project 也是從之前所學到的繪製 2D & 3D Object、Texture Mapping、Quadric Object、Keyboard Control 到 Particle Engine 來完成的。但今天不再細說前面曾經提過的內容,今天主要是介紹 Qt 裡面的 QThread 來實現我的煙火特效。

● QThread

在 QThread 裡面有三個主要的 Public Slots 來控制 Thread 開始、結束和退出。分別是 void start(); void terminate(); void quit();;而 Thread 要執行的內容則是透過一個 protected function : void run(); 來實現,所以今天要求 Thread 做甚麼事情全都要寫在 run() 函式裡面。

class myThread : public QThread
{
 Q_OBJECT
public:
 myThread();
 ~myThread();
public slots:
 void start_mythread();
signals:
 void signal_firework();
protected:
 void run();
};

上面的 myThread 是我在 Taipei101 Firework 這個專案裡面所設定的 Thread。

void myThread::start_mythread()
{
 this->start();
}

start_mythread() 是一個 slots,作用就是啟動我的 Thread。

void myThread::run()
{
 double a = 0;
 while(1)
 {
 if(FIREWORK_UPDATE)
 {
 emit signal_firework();
 FIREWORK_UPDATE = false;
 }}}
connect(mythread, SIGNAL(signal_firework()),
        myqgl, SLOT(firework_update()));

接著在 run() 裡面就是指派我的 Thread 裡的工作,工作內容很簡單,就是在一個 while 迴圈內一直執行 emit signal_firework() 。這個 emit 指的是去發送 signal_firework() 訊號出去,讓接收到這個訊號的人做下一步的動作。例如我這裡將 mythread 訊號與我的 mygql 做連結(connect),所以當 myqgl 接收到 signla_firework() 訊號後,就會執行 firework_update() 的動作。特別注意到我這裡用 FIREWORK_UPDATE 來控制 emit 的動作,當我完成上一個 update 後,才會再發送下一次的 signal_firework(),作用是為了避免程式不停的發送 emit ,而使序列(queue) 裡面堆積太多的訊號要執行,到最後整個程式會因為有做不完的 update 而當掉。

 

 


● Taipei101 Fireworks

這個程式有三種形式的煙火,由三種不同的 Particle Engine 來實現,分別是迴旋式煙火、階段式煙火以及噴發式煙火。Particle Engine 的設定請看 L10

101_firework

最後 demo 影片效果囉。Happy New Year~~~

 

 


reference : http://doc.qt.io/qt-4.8/qthread.html

 

Rendering OpenGL Graphics in Qt

若今天不使用 GLUT 的視窗介面而改用 Qt 來 rendering (渲染) 3D 圖形時,則要藉由 QGLWidget 這個 Class 來實現。

QGLWidget 提供三個非常方便的虛擬函式( Virtual Function) ,分別是 initializeGL()resizeGL() paintGL()。所以在衍生類別的 function naming 要與上述的三個 function 相符合,不然無法 rendering OpenGL 的圖形。

initializeGL() :: 初始設定 rendering 的預設參數,在第一次使用 resizeGL() 和 paintGL() 之前,會先呼叫 initializeGL() 。執行順序是 initializeGL() --> resizeGL() --> paintGL() 。

resizeGL() :: 設定 OpenGL 的觀看位置、矩陣型態、視野角度以及 OpenGL drawing 的範圍...等等。除了第一次 widget 被 create 時會被呼叫,之後只要 widget 有被 resized 時都會重新被呼叫。

paintGL() :: Rendering OpenGL 的畫面,你所畫的物件都應該在這個 function 裡定義。

 


** Example **

class myQGL : public QGLWidget
{
	Q_OBJECT

public:
	myQGL(QWidget *parent = 0);
	~myQGL();

	// &gt;&gt;&gt; QGLWidget protected funs
	virtual void initializeGL();
	virtual void paintGL();
	virtual void resizeGL(int width, int height);
	// &lt;&lt;&lt; QGLWidget portected funs

	public slots:
		void GLupdate();
private:
};
void myQGL::initializeGL()
{
	glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // background ( R, G, B, Alpha)
	glClearDepth(1.0f);	//depth buffer setup
	glShadeModel(GL_SMOOTH); // enables smooth shading
	glEnable(GL_DEPTH_TEST); // enable depth testing
	glDepthFunc(GL_LEQUAL); // the type of depth test to do

	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
}

void myQGL::resizeGL(int width, int height)
{
	if(height == 0)
		height = 1;

	glViewport(0, 0, width, height); //reset the current view port
	glMatrixMode(GL_PROJECTION); //select the model view matrix
	glLoadIdentity(); // reset the model view matrix 

	//calculate the aspect ratio of the window
	gluPerspective(45, (GLfloat)width/height, 0.1f, 100.0f); //fovy : view angle, (0.1f, 100.0f) : drawing area
	glMatrixMode(GL_MODELVIEW); // select model view matrix
	glLoadIdentity();	// reset the model view matrix

}

void myQGL::paintGL()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();

	glTranslatef(-1.5, 0.0f, -6.0f);

	// draw a triagle
	glBegin(GL_TRIANGLES);
	glColor3f( 0.0f, 0.0f, 1.0f);
	glVertex3f( 0.0f, 1.0f, 0.0f); // x , y , z
	glColor3f( 0.0f, 1.0f, 0.0f);
	glVertex3f(-1.0f,-1.0f, 0.0f);
	glColor3f( 1.0f, 0.0f, 0.0f);
	glVertex3f( 1.0f,-1.0f, 0.0f);
	glEnd();
	glTranslatef(3.0f, 0.0f, 0.0f);// move right 3 units

	// draw a square
	glColor3f( 1.0f, 1.0f, 0.0f);
	glBegin(GL_QUADS);
	glVertex3f(-1.0f, 1.0f, 0.0f);
	glVertex3f( 1.0f, 1.0f, 0.0f);
	glVertex3f( 1.0f,-1.0f, 0.0f);
	glVertex3f(-1.0f,-1.0f, 0.0f);
	glEnd();
}

執行結果

triangle & squad                                                      [ Triangle and Square ]


 

reference : http://doc.qt.io/qt-4.8/qglwidget.html#details