Android上使用OpenCV处理图像

注:本文采用的Eclipse+ADT的开发流程目前已经过时,请参考《在Android Studio上进行OpenCV 3.1开发》,使用Android Studio进行基于Android平台的OpenCV开发。


        本文会介绍在Android项目中使用OpenCV的一种方法,并会给出两个demo。

        文中涉及开发环境在《Windows下Android开发环境的配置》的基础之上进行搭建。


        在http://sourceforge.net/projects/opencvlibrary/files/opencv-android/2.4.8/下载OpenCV-2.4.8-android-sdk.zip。假定解压到目录D:\workspace\opencv-android-sdk。

        打开Eclipse,点击File->Import->General->Existing Projects into Workspace,找到D:\workspace\opencv-android-sdk,选择导入OpenCV Library,也可以再导入一两个sample,但最好不要全部导入,因为如果设置了自动编译,会降低每次打开Eclipse的速度。

        导入完成后,右击OpenCV Library,点击Properties->Android,选择合适的Build Project Target,即Android的API版本。

        可以尝试运行一下OpenCV sample项目,检查一下设置是否正确。

        仿照文章《Windows下Android开发环境的配置》的步骤创建一个新的Android项目。假定包名为net.johnhany.grayprocessjni。所需添加的文件及代码如下所示:

GrayProcess.java

ImageProcess.java

activity_gray_process.xml

res\values\strings.xml

把一张图片拷贝到tes\drawable-hdpi,假设图片名称为testpic1。

testpic1

        在项目目录里新建一个名为“jni”的文件夹,里面添加如下3个文件:

Android.mk

这个文件负责把cpp或c文件编译成可以被Android程序调用的.so库.

Application.mk

ImageProc.cpp

        这个cpp文件负责调用OpenCV函数进行图像处理。

        项目结构大致如图:

jni-00


        打开cmd.exe,输入:

        此时classes文件夹内会多出一个net_johnhany_grayprocessjni_ImageProc.h文件,把它拷贝到jni文件夹内,并把名字改为ImageProc.h。

h-file

        在Eclipse内点击Window->Preferences->C/C++->Build->Environment,增加一个环境变量:

变量名
NDKROOT D:\android-ndk

ndkroot


        右击项目名称,点击New->Other->C/C++->Convert to a C/C++ Project (Adds C/C++ Nature)。

jni-01

        选择C++ Project,工具链选择Makefile的Other Toolchain(由于我的项目已经转换过,所以没有显示在项目名称列表里)。

jni-02

        转换完成后会提示是否切换到C/C++视图,选择不切换。

        此时在代码文件内会有大量的错误,这是由于还没有包含进所需的C++库文件。

        右击项目名称,点击Refresh。

        再右击项目名称,点击Properties->Android,选择合适的Android API版本,点击Library中的Add,选择OpenCV Library。

jni-03

        点击C/C++ Build,把Builder Settings中的Build Command改为:

                ${NDKROOT}/ndk-build.cmd

jni-04

        Behaviour的设置如图:

jni-05

        点击C/C++ General->Paths and Symbols->Includes,在GNU C++中添加如下路径:

                ${NDKROOT}/platforms/android-15/arch-arm/usr/include

                ${NDKROOT}/sources/cxx-stl/gnu-libstdc++/4.6/include

                ${NDKROOT}/sources/cxx-stl/gnu-libstdc++/4.6/libs/armeabi-v7a/include

                ${ProjDirPath}/../OpenCV-2.4.8-android-sdk/sdk/native/jni/include

jni-06

        这里的路径最好用NDKROOT或ProjDirPath的相对路径表示,如果用带有盘符的绝对路径可能会由于编译工具和Windows系统的表示方式不同而造成无法编译(如Cygwin)。


        还要在安卓设备上安装OpenCV Manager。如果使用的是模拟器,打开cmd.exe,输入:

        如果使用的是手机,把D:\workspace\opencv-android-sdk\apk目录下的OpenCV_2.4.8_Manager_2.16_armv7a-neon.apk拷贝到手机中,在手机中手动安装。


        点击Run,会自动完成编译、打开模拟器、安装、启动运行等步骤;或者在编译之后把bin文件夹内的apk文件拷贝到手机里,手动安装,运行。

        运行效果如下,点击按钮,图片变成灰色:

gray-process-1

gray-process-2


        这里有另一个使用OpenCV的例子,支持的图像处理方法更多,可以切换图像,还可以用手指选择要作处理的区域:

                https://github.com/johnhany/AndroidProj/tree/master/ImageProcess

共有18条评论

  1. android项目老是提示这个警告Android NDK: WARNING:jni/Android.mk:native_sample: non-system libraries in linker flags: -lopencv_java3 
    哪位大神遇到过,求提示一下?官方案例

  2. 你好,博主,针对你说的   :转换完成后会提示是否切换到C/C++视图,选择不切换。此时在代码文件内会有大量的错误,这是由于还没有包含进所需的C++库文件。     我在进行下面的操作之后还是有错

    1. 你好,如果错误很多的话,可以检查一下C++的include目录是不是正确,检查之后clean或者refresh一下项目。

      如果只是单独的错误,可以把错误信息贴在这儿

  3. 博主:您好。我按照您的步骤创建了工程,编译的时候没有错误,但是加载到手机之后不能运行,一点击APP后就强制关闭。请问是怎么回事?我运行了sample中自带的人脸识别代码,可以运行,说明我的环境配置没有问题吧。。。您能帮助解答下?谢谢!!

    1. 可能是库版本不对应造成的吧。现在官方已经不推荐使用Eclipse+ANT进行Android开发了,所以说本文介绍的方法其实已经过时了:)

      1. cmd一直提示无法找到或加载主类是什么问题?

        明明我自己能在文件夹里找到

        E:\workspace\net.johnhany.grayprocessjni\bin\classes\com\example\net\johnhany\grayprocessjni\ImageProc.class

        1. 从你的类名来看可能是package名称有误了,完整的包名应该是net.johnhany.grayprocess,需要加载的类名是net.johnhany.grayprocess.ImageProc。文件路径里多了两层“com\example”。

          “无法找到或加载主类”一般是环境变量CLASSPATH没设置好,尤其要注意值结尾的分号“;”。在cmd中输入参数时要注意类名与文件路径匹配,还要注意大小写。

          我刚刚也出了类似的问题。我之前用的是jdk 8u20版本,自动更新到8u40后,javah就不能正常工作,只好重装了8u20。权当参考吧

  4. 你好博主,我在运行你github上的那个ImagePross程序时出现了Native method not found: com.example.opencvtools.OpencvJni.gray(Native Mothod)……也就是我出现了一按process!那个键的时候就停止运行,我想问一下这是不是意味着没有运行.cpp文件,我应该怎么解决呢

    1. 可以先检查一下OpencvJni.cpp和OpencvJni.hpp中函数的名称是否与Java代码中的包名和方法名对应,比如在你的代码里就应该是Java_com_example_opencvtools_OpencvJni_gray()。如果只改动了一些名称,并且名称之间都对应上,代码应该是没有问题的。如果还有问题可以把你的完整代码发到我的邮箱johnhany@163.com

      1. 博主,我给你发邮件了,并且也照你说的修改了一下,但是又出现了这样的问题,E/AndroidRuntime(1333): java.lang.UnsatisfiedLinkError: Native method not found: com.example.opencvtools.OpencvJni.gray:麻烦你帮我看一下,我是哪里出现了问题。谢谢!

      2. 楼主,你好,OpencvJni.cpp是指哪个文件,比如你写的这个工程师jni下的ImageProc.cpp吗?

        1. OpencvJni.cpp是在文章末尾给出的另一个例子中会用到的文件,链接:https://github.com/johnhany/AndroidProj/blob/master/ImageProcess/jni/OpencvJni.cpp

          而本文所用的全部代码在https://github.com/johnhany/AndroidProj/tree/master/GrayProcessJni

  5. 请问一下博主,Description    Resource    Path    Location    Type
    Invalid project path: Include path not found ( F:\Android_SDK\android-ndk-r10c\sources\cxx-stl\gnu-libstdc++\4.6\include).    GrayProcess        pathentry    Path Entry Problem

    这个是怎么回事?我现在在学习opencv的C++接口,然后想自己实现一下博主的代码,也就是完全“复制粘贴”了一下。但是出现了这个找不到路径的问题,但是我明明看了相应文件夹下是有这个文件的。

    问题的图片:链接:http://pan.baidu.com/s/1i347QPR 密码:g28p

    谢谢了!!!

    1. 我现在机器上没有安卓环境,所以只能胡猜几种解决方法:

      1.检查一下C++函数名称(Java_net_johnhany_grayprocessjni_ImageProc_grayProc)是否与Java的包名和类名相符。

      2.试一下Project -> Clean、Refresh和Re-build。

      3.Project -> Properties -> C/C++ General -> Preprocessor Include Paths, Macros, etc. -> Providers -> CDT GCC built-in compiler settings,取消选择“Use global provider shared between projects”。如果选择的用MinGW或Visual C++,可能还需要加编译器相关的头文件。

      4.Project -> Properties -> C/C++ -> Build -> Settings -> Discovery,点击“Clear Entries”,然后Rebuild工程。

      5.实在不行,按照文中的步骤重新建一个项目吧

发表评论

电子邮件地址不会被公开。 必填项已用*标注