手写选择题识别-实现android调用c++ oepncv项目

首先学习jni的基础:
参考深入理解android1:

jni = java native interface 即java 本地调用。本来java是一个跨平台的玩意,但是实际上到了不同的平台都需要调用本地,这样如果中间有这样的一个接口,java 和 native之间可以这样通信,就真正实现了跨平台。

jni实际上是一门技术,可以实现 java调用c或c++的函数(native),也可以实现c++程序中调用java函数。
之间的关系就是有一层jni连通java和c++。
手写选择题识别-实现android调用c++ oepncv项目_第1张图片

懂了这个之后,就是说要将两者建立连接,注册好让两者知道。然后就是两者之间的语言的转换。

opencv4android里面自带的native 有这样jni一个文件夹,里面有很多的abi-xxxx 架构文件,这些最好是单个加入配置文件里面去,然后再编译另一个。不同的不会出现覆盖现象,不要尝试 一次性 APP-Bi = :ALL
手写选择题识别-实现android调用c++ oepncv项目_第2张图片

里面同样的有一个文件是opencv.mk文件,这个是需要的,是在 android.mk 脚本文件中要引入 opencv C++库所要参照的文件。虽然看不懂,但是能够打开,先大致看看内容。
手写选择题识别-实现android调用c++ oepncv项目_第3张图片

在哪里有android.mk文件呢?
在jni文件夹(这个就是放置javah生成.h的头文件和cpp文件的文件夹)中 新建一个文件 名为android.mk(后面选择了一个打开方式为txt)。

手写选择题识别-实现android调用c++ oepncv项目_第4张图片
手写选择题识别-实现android调用c++ oepncv项目_第5张图片

有一个地方是添加opencv的路径的,很多是写没有导入进来的绝对路径,而我们现在已经导入进来 了 ,所以想着添加为相对路径。
需要改变的:


include ..\..\..\..\native\jni\OpenCV.mk
这个module名字表示编译出的.so文件名字
LOCAL_MODULE := HandWrtiterReg
LOCAL_SRC_FILES 后面添加一些需要编译的jni下的cpp源文件。多个 是以 \隔开?

LOCAL_SRC_FILES := com_example_yanguokai_handerwriterreg_CHandWriterReg.cpp  

这两个不知道加不加
OPENCV_CAMERA_MODULES:=on
OPENCV_INSTALL_MODULES:=on
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
OPENCV_LIB_TYPE:=STATIC
ifeq ("$(wildcard $(OPENCV_MK_PATH))","")

include ..\..\..\..\native\jni\OpenCV.mk
else
include $(OPENCV_MK_PATH)
endif
OPENCV_CAMERA_MODULES:=on
OPENCV_INSTALL_MODULES:=on

LOCAL_MODULE := ImgFun
LOCAL_SRC_FILES := ImgFun.cpp
LOCAL_LDLIBS += -lm -llog
include $(BUILD_SHARED_LIBRARY)

同样建立对Application.mk文件。

APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_ABI := armeabi-v7a       #这句是设置生成的cpu指令类型,提示,目前绝大部分安卓手机支持armeabi,libs下太多类型,编译进去 apk 包会过大
APP_PLATFORM := android-18   #这句是设置最低安卓平台,和min-sdk一致

有人说要配置这个local配置文件,将ndk.dir添加进去,也有人没有配置,始终不放心,所以打开看了一下啊。发现本身就有,那就可能是通过可视化界面添加ndk时自动添加的,另外还提示说不用更改这个文件。
手写选择题识别-实现android调用c++ oepncv项目_第6张图片

同样的还有一个文件,同上。
手写选择题识别-实现android调用c++ oepncv项目_第7张图片

这些都不用管了。

剩下的就是cpp文件如何修改 了。我现在只知道要实现头文件中的接口函数,以及对java 和native中相应的转换。我可以只写一两个接口,然后再调用我原来正常的c++函数吗?听说 还要全部放到extend “c”{}括号里面。

嗯,应该是要放在括号里。
手写选择题识别-实现android调用c++ oepncv项目_第8张图片

在jni文件夹里面 进行ndk-build命令 编译生成.so文件。
手写选择题识别-实现android调用c++ oepncv项目_第9张图片

这个问题是因为一开始没有配置ndk-bundle环境。我的是直接在android sdk中的。所以将它添加进去path中,然后重启as。感觉配的没有问题啊,就是一直提示没有。最后好了。

手写选择题识别-实现android调用c++ oepncv项目_第10张图片

手写选择题识别-实现android调用c++ oepncv项目_第11张图片

手写选择题识别-实现android调用c++ oepncv项目_第12张图片

有android-18配置的taigao 的警告。
这个opencv.mk路径的错误(因为一开始是复制别人的。没有具体配置。)
手写选择题识别-实现android调用c++ oepncv项目_第13张图片

哈哈 ,各种报错:
手写选择题识别-实现android调用c++ oepncv项目_第14张图片

代码中的情况:当时确实改乱了一个返回值

这里写图片描述
手写选择题识别-实现android调用c++ oepncv项目_第15张图片
手写选择题识别-实现android调用c++ oepncv项目_第16张图片

手写选择题识别-实现android调用c++ oepncv项目_第17张图片

手写选择题识别-实现android调用c++ oepncv项目_第18张图片

看别人代码里面的都有这个env 所以就直接用了,原来是参数传的值。
手写选择题识别-实现android调用c++ oepncv项目_第19张图片
手写选择题识别-实现android调用c++ oepncv项目_第20张图片

没有错误了:可以直接在接口文件里面调用正常的c++函数,暂时编译是过了,就不知到其他的问题了。
手写选择题识别-实现android调用c++ oepncv项目_第21张图片

生成的so文件,在一个新生成的libs文件夹中。那使用的时侯,要添加路径吗?
手写选择题识别-实现android调用c++ oepncv项目_第22张图片

果然是 想的问题 没有错。

手写选择题识别-实现android调用c++ oepncv项目_第23张图片

这个是我一开始写这个文件的时候就是个红色的,然后我生成.h文件 然后改造cpp文件…。本来一开始就是从这出发的,怎么就不能识别呢?
手写选择题识别-实现android调用c++ oepncv项目_第24张图片

手写选择题识别-实现android调用c++ oepncv项目_第25张图片

有说去掉ndk support,就好了。
手写选择题识别-实现android调用c++ oepncv项目_第26张图片

提示是没有提示了。但是我不是本身就是用到的ndk吗?
这里写图片描述

当时真机也没有连上,我想直接运行load so文件的那个java类,一直提示无法找到so文件在java lib库路径下,然后也将so文件复制到libs下,或者添加jnilibs路径等等,又生成了其他平台的so文件,该做的都做了 还是不能。
想了一下是不是不能够直接运行main函数,而是需要真机调试,来满足平台需求。

连接真机调试时,出现找不到设备。是因为某些软件与android使用的相同的接口,占用了adb。
在android中取消 usb device selected。这样的话在来调试运行会出现设备选择的选项。
手写选择题识别-实现android调用c++ oepncv项目_第27张图片
手写选择题识别-实现android调用c++ oepncv项目_第28张图片
连上之后,运行闪退。提示的是自己定义的print_string 没有实现。



java.lang.UnsatisfiedLinkError: 
No implementation found for java.lang.String com.example.yanguokai.handerwriterreg.CHandWriterReg.print_string() (tried Java_com_example_yanguokai_handerwriterreg_CHandWriterReg_print_1string and Java_com_example_yanguokai_handerwriterreg_CHandWriterReg_print_1string__

有一个原因是 当时我调用了另外的一个so文件来测试,没有改过来。
手写选择题识别-实现android调用c++ oepncv项目_第29张图片

嗯 换回来之后没有报同样的错。

couldn't find "libHanderWriterReg.so"
                      at java.lang.Runtime.loadLibrary(Runtime.java:367)
                      at java.lang.System.loadLibrary(System.java:1076)

手写选择题识别-实现android调用c++ oepncv项目_第30张图片

E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: com.example.yanguokai.handerwriterreg, PID: 28925
                  Theme: themes:{default=overlay:com.zui.theme.XuiSkin.pink, iconPack:com.zui.theme.XuiSkin.pink}
                  java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.example.yanguokai.handerwriterreg-1/base.apk"],nativeLibraryDirectories=[/data/app/com.example.yanguokai.handerwriterreg-1/lib/arm, /data/app/com.example.yanguokai.handerwriterreg-1/base.apk!/lib/armeabi, /vendor/lib, /system/lib]]] couldn't find "libHanderWriterReg.so"
                      at java.lang.Runtime.loadLibrary(Runtime.java:367)
                      at java.lang.System.loadLibrary(System.java:1076)
                      at com.example.yanguokai.handerwriterreg.CHandWriterReg.(CHandWriterReg.java:8)
                      at com.example.yanguokai.handerwriterreg.MainActivity.onCreate(MainActivity.java:65)
                      at android.app.Activity.performCreate(Activity.java:6285)
                      at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1109)
                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2402)
                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2521)
                      at android.app.ActivityThread.access$900(ActivityThread.java:153)
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1347)
                      at android.os.Handler.dispatchMessage(Handler.java:102)
                      at android.os.Looper.loop(Looper.java:148)
                      at android.app.ActivityThread.main(ActivityThread.java:5477)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Application terminated.

这个是我路径没有添加上去(ps:前面说的一样,当时也是在修改这些路径,然后导致以前那个tf的so文件也是同样的问题,所以当时又改回去了 。现在再添加好了。)
手写选择题识别-实现android调用c++ oepncv项目_第31张图片

然后就没有报错了,真机也能够正常加载main activity 了 ,虽然还没有试具体的部分,也是我自己的原因 只能够尝试 这个错了就改,这个没错就接受)

08/05 09:59:14: Launching app
$ adb push D:\AndroidStudioProjects\handerwriter\app\build\outputs\apk\app-debug.apk /data/local/tmp/com.example.yanguokai.handerwriterreg
$ adb shell pm install -r "/data/local/tmp/com.example.yanguokai.handerwriterreg"
    pkg: /data/local/tmp/com.example.yanguokai.handerwriterreg
Success


$ adb shell am start -n "com.example.yanguokai.handerwriterreg/com.example.yanguokai.handerwriterreg.MainActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER
Connected to process 30992 on device zuk-zuk_z1-54d64724
W/zipro: Error opening archive /data/resource-cache/com.zui.theme.XuiSkin.pink/icons/resources.apk: I/O Error
D/asset: failed to open Zip archive '/data/resource-cache/com.zui.theme.XuiSkin.pink/icons/resources.apk'


         [ 08-05 09:59:22.136 30969:30969 W/         ]
         Unable to open '/data/resource-cache/com.zui.theme.XuiSkin.pink/icons/resources.apk': No such file or directory
I/LoadedApk: No resource references to update in package com.zui.theme.XuiSkin.pink
I/LoadedApk: No resource references to update in package com.zui.theme.XuiSkin.pink
W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
I/SO_hand: test7.jpg
D/OpenGLRenderer: Use EGL_SWAP_BEHAVIOR_PRESERVED: true
I/Adreno-EGL: 379>: EGL 1.4 QUALCOMM build: Nondeterministic_AU_msm8974_LA.BF.1.1.3_RB1__release_AU (I741a3d36ca)
              OpenGL ES Shader Compiler Version: E031.29.00.00
              Build Date: 04/04/16 Mon
              Local Branch: mybranch19053788
              Remote Branch: quic/LA.BF.1.1.3_rb1.12
              Local Patches: NONE
              Reconstruct Branch: NOTHING
I/OpenGLRenderer: Initialized EGL, version 1.4

调用CHandWriterReg java类 ,运行成功:

成功运行:

I/OpenGLRenderer: Initialized EGL, version 1.4


I/TensorFlowInferenceInterface: Checking to see if TensorFlow native methods are already loaded
I/TensorFlowInferenceInterface: TensorFlow native methods already loaded
I/TensorFlowInferenceInterface: Model load took 1ms, TensorFlow version: 1.1.0-rc2
I/TensorFlowInferenceInterface: Successfully loaded model from 'file:///android_asset/cxq.pb'
I/TAG: button012.0
I/TAG: button014.0
I/TAG: button01test7.jpg

成功之后 再来看看具体的内部情况。

手写选择题识别-实现android调用c++ oepncv项目_第32张图片

手写选择题识别-实现android调用c++ oepncv项目_第33张图片

手写选择题识别-实现android调用c++ oepncv项目_第34张图片

手写选择题识别-实现android调用c++ oepncv项目_第35张图片

手写选择题识别-实现android调用c++ oepncv项目_第36张图片

这个是cpp原程序中的位置代码块,所以也就是说,我其他的都可以使用原来的代码,只要在接口函数中调用,然后在这个里面在进行 cpp 和 java 之间的类型转换。
手写选择题识别-实现android调用c++ oepncv项目_第37张图片

一个是opencv中原来的imshow应该是不能用了的 。

08-05 10:53:18.686 27928-27928/com.example.yanguokai.handerwriterreg E/cv::error(): OpenCV Error: Assertion failed (dims <= 2 && step[0] > 0) in void cv::Mat::locateROI(cv::Size&, cv::Point&) const, file /build/master_pack-android/opencv/modules/core/src/matrix.cpp, line 949

命令:javah (利用这个命令不需要先编译成.class文件,再利用.class文件 来生成头文件)

javah -d ../jni -jni com.example.yanguokai.handerwr
iterreg.CHandWriterReg

错误:

 E/cv::error(): OpenCV Error: Unspecified error (The function is not implemented. Rebuild the library with Windows, GTK+ 2.x or Carbon support.

存在一些windows下的弹窗显示图片导致的问题。 imshow 和namewindow 和waitkey。

手写选择题识别-实现android调用c++ oepncv项目_第38张图片

这里写图片描述

将上面的所有都完全注释后,调用运行成功。
这里写图片描述

将Pictures中的一张测试图片 路径 通过native 方法传入,然后c++ 调用opencv的图像加载进入mat,然后一系列的操作之后,在pictures中生成拆分的图片。

手写选择题识别-实现android调用c++ oepncv项目_第39张图片

手写选择题识别-实现android调用c++ oepncv项目_第40张图片

手写选择题识别-实现android调用c++ oepncv项目_第41张图片

手写选择题识别-实现android调用c++ oepncv项目_第42张图片

手写选择题识别-实现android调用c++ oepncv项目_第43张图片

你可能感兴趣的:(工具)