您的位置:首页 > 移动开发 > Android开发

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

2014-08-01 17:17 549 查看
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.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: