OpenCV简介以及向Android平台的移植

来源:互联网 发布:马列维奇 知乎 编辑:程序博客网 时间:2024/06/05 15:54
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\
        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/
LOCAL_LDLIBS := -L../../../3rdparty/flann/libs/armeabi-v7a/ -lflann -L../../../3rdparty/zlib/libs/armeabi-v7a/ -lzlib -L../../../3rdparty/lapack/libs/armeabi-v7a/ -llapack
include $(BUILD_SHARED_LIBRARY)
 
则cxcore编译成功。


下面编译cv:
cv编译中,遇到的最多的问题是某变量以下划线开头,后面只有一个字母. 需要将其加长.修改后就可以编译了.

其Android.mk如下:

LOCAL_PATH := $(call my-dir)
 
include $(CLEAR_VARS)
LOCAL_ARM_MODE := arm
LOCAL_MODULE := cv
LOCAL_SRC_FILES := cvaccum.cpp                  cvcontourtree.cpp    cvfundam.cpp     cvmatchcontours.cpp cvprecomp.cpp    cvstereogc.cpp\
cvapprox.cpp                 cvconvhull.cpp       cvgeometry.cpp   cvmodelest.cpp       cvpyramids.cpp        cvsubdivision2d.cpp\
cvcalccontrasthistogram.cpp  cvcorner.cpp         cvhaar.cpp       cvmoments.cpp        cvpyrsegmentation.cpp cvsumpixels.cpp\
cvcalcimagehomography.cpp    cvcornersubpix.cpp   cvhistogram.cpp  cvmorph.cpp          cvrotcalipers.cpp      cvsurf.cpp\
cvcalibinit.cpp              cvderiv.cpp          cvhough.cpp      cvmotempl.cpp        cvsamplers.cpp        cvtables.cpp\
cvcalibration.cpp            cvdistransform.cpp   cvimgwarp.cpp    cvmser.cpp           cvsegmentation.cpp    cvtemplmatch.cpp\
cvcamshift.cpp               cvdominants.cpp      cvinpaint.cpp    cvoptflowbm.cpp      cvshapedescr.cpp      cvthresh.cpp\
cvcanny.cpp                  cvemd.cpp            cvkalman.cpp     cvoptflowgf.cpp      cvsmooth.cpp          cvtriangulate.cpp\
cvcascadedetect.cpp          cvfeatureselect.cpp  cvkdtree.cpp     cvoptflowhs.cpp      cvsnakes.cpp          cvundistort.cpp\
cvcolor.cpp                  cvfeaturetree.cpp    cvlinefit.cpp    cvoptflowlk.cpp      cvspilltree.cpp        cvutils.cpp\
cvcondens.cpp                cvfilter.cpp         cvlkpyramid.cpp  cvpgh.cpp            cvstardetector.cpp\
cvcontours.cpp               cvfloodfill.cpp      cvlsh.cpp        cvposit.cpp          cvstereobm.cpp\
 
 
 
LOCAL_CXXFLAGS := -D_GLIBCXX_USE_WCHAR_T
LOCAL_CXXFLAGS += -I../../../include/opencv/ -I../../../3rdparty/flann/ -I../../../3rdparty/include/
 
LOCAL_LDLIBS := -L../../cxcore/libs/armeabi-v7a/ -lcxcore -L../../../3rdparty/flann/libs/armeabi-v7a/ -lflann -L../../../3rdparty/zlib/libs/armeabi-v7a/ -lzlib -L../../../3rdparty/lapack/libs/armeabi-v7a/ -llapack 
 
include $(BUILD_SHARED_LIBRARY)
 
 
 











总结下来:
OpenCV的编译过程如下:
先编译3rdparty/flann, 3rdparty/lapack, 3rdparty/zlib.
之后编译cxcore.它依赖于以上几个库。
最后编译cv. 它依赖于cxcore.
0 0