最近的我們已經將整個項目搭起來了,項目比較復雜。由於我們做的是檢索系統,所以我們用asp.net(c#)做了網頁,但是算法的實現是在matlab下,所以我們不得不用matlab生成動態鏈接庫dll,然后用c#調用matlab,單單這個配置問題就搞了我們一個多星期,不過還是順利解決了,解決方法以后有時間再寫個博客出來。
雖然我們整個項目已經能在c#下跑通了,但是檢索效果真不理想,檢查各種可能出現問題的地方,首先自然是特征的問題。我們做的是偏圖像的檢索,有些現成的特征提取算法是在opencv下實現的,需要借助opencv來實現特征的提取,因此我們要利用matlab來調用opencv。
上次的那個博客已經說了如何用mex來實現混合編程,同樣如果c++代碼中調用了opencv庫的話,用mex編譯的時候就不再像之前那么簡單。由於手頭上有MacOS和Windows兩個系統,下面我分別對此講述如何利用mex編譯帶opencv調用的c++代碼。
首先我用的matlab版本是matlab2012a 64bit,opencv的版本是用homebrew安裝的(具體版本忘記了)
MacOS
在蘋果系統下,我是參考這位同學的工作:http://vision.is.tohoku.ac.jp/~kyamagu/software/mexopencv/,但是由於OS X的環境會和matlab自帶的庫沖突。In OS X environment, runtime error can happen when the version of your system library conflicts with matlab's internal library. 我的沖突就是DCHAR16_T的重復宏定義,因此我和那篇文章的配置方法略有不同。
OS X 10.9 and XCode 5
Due to the change in the default C++ runtime in OS X 10.9, you probably need to tweak a few configurations in mexopts.sh
to avoid compile issues. If you haven't run mex -setup
in Matlab, please do so first and edit mexopts.sh
and change a few variables. Following shows an example.
上面這段話是原封不動的復制與粘貼,然后他給出的辦法是修改/Applications/matlab/MATLAB_R2012a.app/bin/mexopts.sh文件(這段路徑是我自己的),如何修改這個文件,他給出了一個辦法,但是這里我的修改略和他不同,請注意。首先打開mexopts.sh文件,並且找到maci64,如圖:
然后將里面的一些變量如下修改(圖中的是已經修改過的):
CC='clang' CXX='clang++' SDKROOT='/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/' MACOSX_DEPLOYMENT_TARGET='10.9' CLIBS="$CLIBS -lc++" CXXFLAGS="-fno-common -no-cpp-precomp -fexceptions -arch $ARCHS -isysroot $SDKROOT -mmacosx-version-min=$MACOSX_DEPLOYMENT_TARGET -std=c++11 -stdlib=libc++" #注意這里和他的不同在我刪除了-DCHAR16_T,這個東西保留會宏定義沖突 CXXLIBS="$MLIBS -lc++"
這樣就配置好MacOS下的編譯環境了,然后打開Matlab,在command window下輸入mex -setup。按照步驟進行設置mex的編譯配置,如圖:
但是上面這樣只是配置好了編譯環境,只能夠利用Mex來編譯純C/C++的代碼,如果要編譯含opencv函數的代碼,需要再參照下面這篇博客:http://blog.csdn.net/raodotcong/article/details/8785358。我是這樣做的,因為我通過homebrew安裝opencv的,安裝路徑在/usr/local/Cellar/opencv下,所以當我用mex編譯是應該如下輸入:例如我要編譯途中的cpp文件(調用了opencv庫的代碼):
然后在matlab下輸入:
mex bofGabor.cpp cvgabor.cpp Image.cpp Retriever.cpp -I/usr/local/Cellar/opencv/2.4.9/include -L/usr/local/Cellar/opencv/2.4.9/lib/ -lopencv_highgui.2.4.9 -lopencv_core.2.4.9 -lopencv_imgproc.2.4.9
稍微解釋一下上面的命令,
mex bofGabor.cpp cvgabor.cpp Image.cpp Retriever.cpp 是將四個文件鏈接起來一起生成Mex文件。
-I/usr/local/Cellar/opencv/2.4.9/include 是告訴編譯器去哪尋找頭文件。
-L/usr/local/Cellar/opencv/2.4.9/lib/ 是告訴編譯器去哪尋找庫文件
-lopencv_highgui.2.4.9 -lopencv_core.2.4.9 -lopencv_imgproc.2.4.9 最后這三個是將用到的庫鏈接起來。
最后就會生成如圖的bofGabor.mexmaci64文件了~~~
Windows
在Windows下其實和macOS下類似,只是少了修改那個mexopts.sh文件的步驟。首先是安裝opencv,對於vs2010,我轉這篇文章備忘,因為我經常用到這個教程:http://wiki.opencv.org.cn/index.php/VC_2010%E4%B8%8B%E5%AE%89%E8%A3%85OpenCV2.4.4。 下面我就將他的配置Opencv方法轉到我的博客中。
- 去Opencv官網下載 OpenCV for Windows(我的版本是opencv2.4.10)。
- 將 OpenCV-2.4.4.exe 解壓並放到某個目錄下,例如E:\opencv\opencv (本人的解壓目錄)。解壓后的目錄結構如下圖。
3. 右鍵單擊我的電腦→屬性→高級→環境變量。
4. 選中PATH,單擊編輯。在PATH的末尾添加以下路徑:E:\opencv\opencv\build\x86\vc10\bin
。
5. 新建用戶變量,單擊新建,在彈出的對話框中,將變量名和變量值分別設置為OpenCV和E:\opencv\opencv\build。
6. 設置環境變量完畢,重啟電腦,將會生效。
上面配置好了系統環境,下面要對vs2010進行配置:
1、打開VS2010,新建項目→win32控制台項目→附加選項選擇空項目→完成。
2、左側打開工程屬性頁
3、修改可執行文件目錄、包含目錄與庫目錄,分別添加對應的路徑。
對應的路徑如下:
1)可執行文件目錄
E:\opencv\opencv\build\x86\vc10\bin
2)包含目錄
E:\opencv\opencv\build\include
E:\opencv\opencv\build\include\opencv
E:\opencv\opencv\build\include\opencv2
3)庫目錄
E:\opencv\opencv\build\x86\vc10\lib
4、附加依賴項單擊“鏈接器”→“輸入”→“附加依賴項”,如下圖所示。
opencv_calib3d2410.lib
opencv_calib3d2410d.lib
opencv_contrib2410.lib
opencv_contrib2410d.lib
opencv_core2410.lib
opencv_core2410d.lib
opencv_features2d2410.lib
opencv_features2d2410d.lib
opencv_flann2410.lib
opencv_flann2410d.lib
opencv_gpu2410.lib
opencv_gpu2410d.lib
opencv_highgui2410.lib
opencv_highgui2410d.lib
opencv_imgproc2410.lib
opencv_imgproc2410d.lib
opencv_legacy2410.lib
opencv_legacy2410d.lib
opencv_ml2410.lib
opencv_ml2410d.lib
opencv_nonfree2410.lib
opencv_nonfree2410d.lib
opencv_objdetect2410.lib
opencv_objdetect2410d.lib
opencv_ocl2410.lib
opencv_ocl2410d.lib
opencv_photo2410.lib
opencv_photo2410d.lib
opencv_stitching2410.lib
opencv_stitching2410d.lib
opencv_superres2410.lib
opencv_superres2410d.lib
opencv_ts2410.lib
opencv_ts2410d.lib
opencv_video2410.lib
opencv_video2410d.lib
opencv_videostab2410.lib
opencv_videostab2410d.lib
上面就是所有的opencv在vc2010下的配置過程,只是為了備忘。
測試代碼:
#include <highgui.h> #include <iostream> using namespace cv; void main() { IplImage *src = cvLoadImage("lena.jpg"); //這里將lena.jpg和lena.cpp文件放在同一個文件夾下 cvNamedWindow("lena",CV_WINDOW_AUTOSIZE); cvShowImage("lena",src); cvWaitKey(0); cvDestroyWindow("lena"); cvReleaseImage(&src); }
后面要用matlab編譯C++(含opencv調用)的代碼的流程和MacOS的一樣,也是先Mex -setup設置編譯器,然后編譯的時候就按照本文紅色加粗字那樣給出相應路徑即可編譯成功。
例子:
mex bofGabor.cpp cvgabor.cpp Image.cpp Retriever.cpp -IE:\opencv\opencv\build\include\ -LE:\opencv\opencv\build\x86\vc10\lib -lopencv_highgui2410 -lopencv_core2410 -lopencv_imgproc2410