OpenCV簡介以及向Android平臺的移植

OpenCV於1999年由Intel 建立,全稱:Open Source Computer Vision Library。
OpenCV是一個跨平臺計算機視覺庫,可以運行在Linux、Windows和Mac OS操作系統上。它輕量級而且高效——由一系列 C 函數和少量 C++ 類構成,同時提供了Python、Ruby、MATLAB等語言的接口。當前版本已經支持Android。 


當前,Sam需要在Android上使用OpenCV。 雖然OpenCV已經有了Android版本。但因爲當前代碼基於OpenCV2.0. 此版本沒有Android版本。所以,必須交叉編譯此版本。


0. 下載相關版本OpenCV Source Code:
http://opencv.org/downloads.html
下載For Linux Version。得到:OpenCV-2.0.0.tar.bz2


1. 使用NDK編譯之:
1.1:編譯Linux X86版本:
首先,Sam想通過正常x86_Linux 編譯,看看基本庫都包括哪些,以及這些庫是由哪些CPP文件組成的。有了以上信息,可以創建Android.mk。

$cd OpenCV-2.0.0
$./configure
$make

竟然出現錯誤:error: 'ptrdiff_t' does not name a type
於是在cxcore.h中添加一行:

#include < stddef.h >
又缺乏unlink. 
還是添加頭文件:#include

之後,又是HighGUI 缺乏cvCreateCameraCapture_V4L(int)
undefined reference to 'cvCreateCameraCapture_V4L(int)'

Sam查了Google, 看到最快的辦法是修改define.即讓代碼不進去。感覺有點不對,但不管了。先這麼來吧。反正HighGUI也不會真去用。
$gedit src/highgui/cvcap.cpp.
//#if defined(HAVE_CAMV4L) || defined(HAVE_CAMV4L2)
#if defined (HAVE_CAMV4L)



編譯通過。(記得上次編譯OpenCV2.0,沒這麼多問題啊,有點忘記了)
驗證:Sam編譯了一個OpenCV自帶例子:samples/c/squares.c
$g++ squares.c -o squares -I../../include/opencv/ -L../../src/.libs/ -lhighgui -lcv -lcxcore
編譯正常,說明編譯出的庫應該正常。


1.2:編譯爲Android NativeC版本庫
觀察前面編譯Linux-x86的過程,感覺需要編譯的模塊有:libcxcore.so, libcv.so等。至於highgui,它不是產品化的庫,所以可以不用。

從名字上聽,libcxcore.so應該是最基礎的庫。所以先編譯之:
1.2.1:創建Android.mk
首先說到Application.mk, 這個Sam一直用通用的。所以不用修改。這裏只生成Android.mk即可。


LOCAL_PATH := $(call my-dir)
 
include $(CLEAR_VARS)
LOCAL_ARM_MODE := arm
LOCAL_MODULE := cxcore
LOCAL_SRC_FILES := cxconvert.cpp \
        cxflann.cpp\
        cxpersistence.cpp\
        cxcopy.cpp\
        cximage.cpp\
        cxprecomp.cpp\
        cxlapack.cpp\
        cxrand.cpp\
        cxalloc.cpp\
        cxdatastructs.cpp\
        cxmathfuncs.cpp\
        cxstat.cpp\
        cxarithm.cpp\
        cxdrawing.cpp\
        cxmatmul.cpp\
        cxsystem.cpp\
        cxarray.cpp\
        cxdxt.cpp\
        cxmatrix.cpp\
        cxtables.cpp
 
 
 
LOCAL_CXXFLAGS := -D_GLIBCXX_USE_WCHAR_T
LOCAL_CXXFLAGS += -I../../../include/opencv/ -I../../../3rdparty/flann/ -I../../../3rdparty/include/
include $(BUILD_SHARED_LIBRARY)


此時,會有一個奇怪的錯誤出現:
home/sam/work/current/AM/Thirdparty/OpenCV/OpenCV-2.0/Linux_Version/OpenCV-2.0.0/src/cxcore/jni/cxlapack.cpp: In function 'bool cv::jacobi(const cv::Mat&, cv::Mat&, cv::Mat&, bool, Real)':
/home/sam/work/current/AM/Thirdparty/OpenCV/OpenCV-2.0/Linux_Version/OpenCV-2.0.0/src/cxcore/jni/cxlapack.cpp:759:9: error: expected unqualified-id before numeric constant
/home/sam/work/current/AM/Thirdparty/OpenCV/OpenCV-2.0/Linux_Version/OpenCV-2.0.0/src/cxcore/jni/cxlapack.cpp:760:18: error: no matching function for call to 'cv::Mat::copyTo(int) const'


Sam將 _S 全部修改爲 _S1即可。
Mat _S1(_S0.size(), _S0.type(), S);

還有幾個地方有類似問題。按此方法修改之。
網絡上有人說:
All uppercase names are often used for preprocessor macros, which
doesn't respect namespace scopes. Therefore such names should
generally be avoided for everything else.



編譯都過了,但鏈接時出現錯誤,應該是flann沒有編譯所致。
const:/home/sam/work/current/AM/Thirdparty/OpenCV/OpenCV-2.0/Linux_Version/OpenCV-2.0.0/src/cxcore/jni/cxflann.cpp:51: error: undefined reference to 'flann::Index::Index(flann::Matrixconst&, flann::IndexParams const&)'
編譯flann:
進入OpenCV-2.0.0/3rdparty/flann
$mkdir jni
copy all cpp and .h file to jni

create Application.mk and android.mk

Android.mk:
LOCAL_PATH := $(call my-dir)
 
include $(CLEAR_VARS)
LOCAL_ARM_MODE := arm
LOCAL_MODULE := flann
LOCAL_SRC_FILES := constants.h\
            flann.cpp\
            flann.hpp\
            dist.cpp\
            index_testing.cpp\
            logger.cpp\
            random.cpp\
            saving.cpp
             
             
 
 
 
LOCAL_CXXFLAGS := -D_GLIBCXX_USE_WCHAR_T
LOCAL_CXXFLAGS += -I../../include/flann/  -I../util/ -I../nn -I../algorithms
#include $(BUILD_EXECUTABLE)
include $(BUILD_SHARED_LIBRARY)


編譯libflann.so 成功。


再次編譯cxcore,又報錯:

/home/sam/work/current/AM/Thirdparty/OpenCV/OpenCV-2.0/Linux_Version/OpenCV-2.0.0/src/cxcore/jni/cxpersistence.cpp:257: error: undefined reference to 'gzclose'
/home/sam/work/current/AM/Thirdparty/OpenCV/OpenCV-2.0/Linux_Version/OpenCV-2.0.0/src/cxcore/jni/cxpersistence.cpp:233: error: undefined reference to 'gzputs'

查找之,發現是3rdparty/zlib沒有編譯。編譯之。

同樣,建立jni目錄。創建Android.mk .這個編譯很簡單.

再後來,發現lapack又沒有提供庫。再編譯之。

此時,將cxcore的Android.mk修改爲如下方式,即將剛纔編譯的幾個第三方庫加入。


LOCAL_PATH := $(call my-dir)
 
include $(CLEAR_VARS)
LOCAL_ARM_MODE := arm
LOCAL_MODULE := cxcore
LOCAL_SRC_FILES := cxconvert.cpp \
        cxflann.cpp\
        cxpersistence.cpp\
        cxcopy.cpp\
        cximage.cpp\
        cxprecomp.cpp\
        cxlapack.cpp\
        cxrand.cpp\
      
發佈了95 篇原創文章 · 獲贊 29 · 訪問量 34萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章