将Tesseract和Opencv添加到Android.mk(Android Studio)

4
我按照这里的说明成功添加了OpenCV。但是我已经尝试了几天,仍然无法将tesseract添加到Android.mk中。
我有一个使用tesseract的android.cpp文件,因此必须在我的Android.mk中包含该依赖项。我找到了这篇文章,它几乎有完全相同的问题,并通过将libtess.soliblept.so文件导入Android.mk来解决了它,但没有解释如何做到这一点。因此,我查找并找到了这篇文章,显示如何链接预构建库。基于此,我尝试了以下Android.mk:
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := liblept
LOCAL_SRC_FILES := ../libs/$(TARGET_ARCH_ABI)/liblept.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../../../../tess-two/jni
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := libtess
LOCAL_SRC_FILES := ../libs/$(TARGET_ARCH_ABI)/libtess.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../../../../tess-two/jni
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
OPENCV_PACKAGE_DIR:= /Users/danielsierraf/Documents/OpenCV-2.4.10-android-sdk/sdk
OPENCV_CAMERA_MODULES := off
include $(OPENCV_PACKAGE_DIR)/native/jni/OpenCV.mk

LOCAL_MODULE    := run_detection
LOCAL_SHARED_LIBRARIES := libtess
LOCAL_SRC_FILES := text_detect.cpp android.cpp
LOCAL_LDLIBS    += -landroid -llog -ldl

include $(BUILD_SHARED_LIBRARY)

并获得以下输出:

[armeabi-v7a] Prebuilt       : liblept.so <= src/main/jni/../libs/armeabi-v7a/
[armeabi-v7a] Install        : liblept.so => src/main/jniLibs/armeabi-v7a/liblept.so
[armeabi-v7a] Compile++ thumb: run_detection <= text_detect.cpp
In file included from src/main/jni/text_detect.h:4:0,
                 from src/main/jni/text_detect.cpp:10:
src/main/jni/../../../../tess-two/jni/com_googlecode_tesseract_android/src/api/baseapi.h:32:22: fatal error: platform.h: No such file or directory
 #include "platform.h"
                      ^
compilation terminated.

所以我猜测没有正确地链接libtess,如果您仔细查看,它根本没有安装libtess.so,似乎它只安装了liblept.so,然后跳到text_detect.cpp,忽略了这个部分:

include $(CLEAR_VARS)
LOCAL_MODULE := libtess
LOCAL_SRC_FILES := ../libs/$(TARGET_ARCH_ABI)/libtess.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../../../../tess-two/jni
include $(PREBUILT_SHARED_LIBRARY)

所以我试图通过将其放置在不同的文件中来强制安装 liblept libtess ,然后再继续进行。因此,我将文件的最后一部分放在另一个Android.mk中的另一个文件夹中,并尝试了 include $(call all-subdir-makefiles),然后它会完全安装 libtess liblept ,但忽略了 call all-subdir-makefiles
新的jni文件夹结构:
Android.mk
Application.mk
text_detect/
     Android.mk
     android.cpp
     text_detect.cpp
     text_detect.h

Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := liblept
LOCAL_SRC_FILES := ../libs/$(TARGET_ARCH_ABI)/liblept.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../../../../tess-two/jni
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := libtess
LOCAL_SRC_FILES := ../libs/$(TARGET_ARCH_ABI)/libtess.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../../../../tess-two/jni
include $(PREBUILT_SHARED_LIBRARY)

include $(call all-subdir-makefiles)

textdetect/Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

OPENCV_PACKAGE_DIR:= /Users/danielsierraf/Documents/OpenCV-2.4.10-android-sdk/sdk
OPENCV_CAMERA_MODULES := off
include $(OPENCV_PACKAGE_DIR)/native/jni/OpenCV.mk

LOCAL_MODULE    := run_detection
LOCAL_SHARED_LIBRARIES := libtess
LOCAL_SRC_FILES := text_detect.cpp android.cpp
LOCAL_LDLIBS    += -landroid -llog -ldl

include $(BUILD_SHARED_LIBRARY)

这是输出结果:

[armeabi-v7a] Prebuilt       : liblept.so <= src/main/jni/../libs/armeabi-v7a/
[armeabi-v7a] Install        : liblept.so => src/main/jniLibs/armeabi-v7a/liblept.so
[armeabi-v7a] Prebuilt       : libtess.so <= src/main/jni/../libs/armeabi-v7a/
[armeabi-v7a] Install        : libtess.so => src/main/jniLibs/armeabi-v7a/libtess.so
[armeabi] Prebuilt       : liblept.so <= src/main/jni/../libs/armeabi/
[armeabi] Install        : liblept.so => src/main/jniLibs/armeabi/liblept.so
[armeabi] Prebuilt       : libtess.so <= src/main/jni/../libs/armeabi/
[armeabi] Install        : libtess.so => src/main/jniLibs/armeabi/libtess.so
[mips] Prebuilt       : liblept.so <= src/main/jni/../libs/mips/
[mips] Install        : liblept.so => src/main/jniLibs/mips/liblept.so
[mips] Prebuilt       : libtess.so <= src/main/jni/../libs/mips/
[mips] Install        : libtess.so => src/main/jniLibs/mips/libtess.so
[x86] Prebuilt       : liblept.so <= src/main/jni/../libs/x86/
[x86] Install        : liblept.so => src/main/jniLibs/x86/liblept.so
[x86] Prebuilt       : libtess.so <= src/main/jni/../libs/x86/
[x86] Install        : libtess.so => src/main/jniLibs/x86/libtess.so

正如您所见,它完美地安装了第一个Android.mk中的所有内容,但它从未运行textdetect/Android.mk。

那么,我做错了什么?我该如何完成这个看起来很简单的任务?有更简单的方法吗?

编辑:

在@ph0b的回复后,我回到了我的初始设置,并添加了与原始Makefiles相同的LOCAL_EXPORT_C_INCLUDES(通过几个适应我的路径的变化),问题得到了解决。它找不到platform.h,因为它不知道在哪里寻找它。

现在,在我做出这个改变之后,我遇到了一个不同的错误No such file or directory #include "com_googlecode_tesseract_android/src/api/baseapi.h",我以为这是因为它没有编译tesseract,然后才是run_detection依赖于它。嗯,那不是问题,它仍然在编译tesseract之前编译run_detection,但这不是问题,问题非常简单,我为此花了太多时间感到很蠢。问题在于它找不到com_googlecode_tesseract_android/src/api/baseapi.h,因为我也没有提供该路径,所以我从tess-two中复制了com_googlecode_tesseract_androidcom_googlecode_leptonica_android,并将$(LOCAL_PATH)添加到LOCAL_EXPORT_C_INCLUDES中。这是我的最终解决方案:

jni文件夹结构:

Android.mk
Application.mk
text_detect.cpp
android.cpp
text_detect.h
com_googlecode_leptonica_android
com_googlecode_tesseract_android

Android.mk

LOCAL_PATH := $(call my-dir)

#leptonica
LEPTONICA_LOCAL := $(LOCAL_PATH)/com_googlecode_leptonica_android
LEPTONICA_PATH := $(LEPTONICA_LOCAL)/src

include $(CLEAR_VARS)

LOCAL_MODULE := liblept
LOCAL_SRC_FILES := ../libs/$(TARGET_ARCH_ABI)/liblept.so
LOCAL_EXPORT_C_INCLUDES := \
  $(LEPTONICA_LOCAL) \
  $(LEPTONICA_PATH)/src

include $(PREBUILT_SHARED_LIBRARY)

#tesseract
TESSERACT_LOCAL := $(LOCAL_PATH)/com_googlecode_tesseract_android
TESSERACT_PATH := $(TESSERACT_LOCAL)/src

include $(CLEAR_VARS)

LOCAL_MODULE := libtess
LOCAL_SRC_FILES := ../libs/$(TARGET_ARCH_ABI)/libtess.so
LOCAL_EXPORT_C_INCLUDES := \
  $(LOCAL_PATH) \
  $(TESSERACT_PATH)/api \
  $(TESSERACT_PATH)/ccmain \
  $(TESSERACT_PATH)/ccstruct \
  $(TESSERACT_PATH)/ccutil \
  $(TESSERACT_PATH)/classify \
  $(TESSERACT_PATH)/cube \
  $(TESSERACT_PATH)/cutil \
  $(TESSERACT_PATH)/dict \
  $(TESSERACT_PATH)/opencl \
  $(TESSERACT_PATH)/neural_networks/runtime \
  $(TESSERACT_PATH)/textord \
  $(TESSERACT_PATH)/viewer \
  $(TESSERACT_PATH)/wordrec \
  $(LEPTONICA_PATH)/src \
  $(TESSERACT_LOCAL)
LOCAL_SHARED_LIBRARIES := liblept

include $(PREBUILT_SHARED_LIBRARY)

#opencv
include $(CLEAR_VARS)
OPENCV_PACKAGE_DIR:= /Users/danielsierraf/Documents/OpenCV-2.4.10-android-sdk/sdk
OPENCV_CAMERA_MODULES := off
include $(OPENCV_PACKAGE_DIR)/native/jni/OpenCV.mk

LOCAL_MODULE    := run_detection
LOCAL_SRC_FILES := text_detect.cpp android.cpp
LOCAL_LDLIBS    += -landroid -llog -ldl
LOCAL_SHARED_LIBRARIES += libtess liblept

include $(BUILD_SHARED_LIBRARY)
1个回答

1
你最新的设置以奇怪的方式失败了,ndk-build至少应该尝试编译你的模块。也许在它之前定义了ndk模块时,all-subdir-makefiles中存在一个bug,并且它找不到你的模块的Android.mk文件。你可以尝试在顶级Android.mk中只包含include $(call all-subdir-makefiles)
无论如何,我认为你应该回到你的第一个设置,将你的模块直接放在jni根目录中。然后,你主要问题是正确声明包含路径。tess-two/jni中不包含任何头文件?它们在tess-two/jni/com_googlecode_*_android/src/*中。这意味着你需要在你的模块声明中列出这些,通过提供所有绝对路径给LOCAL_EXPORT_C_INCLUDES变量(像原始Makefile中一样:https://github.com/rmtheis/tess-two/blob/master/tess-two/jni/com_googlecode_tesseract_android/Android.mk#L33)。

您还需要为libtess添加对liblept的依赖关系: LOCAL_SHARED_LIBRARIES := liblept 放在libtess库声明内部。

如果仍然失败,还有另一种可能性: 不是使用生成的.so文件重新定义libtess和liblept模块,而是直接包含tess-two/jni/Android.mk并使用与tess-two相同的Application.mk(复制`tess-two/jni/Application.mk),它将已经正确定义了libtess和liblept模块。


你使用的NDK版本是哪个?在哪个操作系统下?输出是否仍然相同,缺少头文件?很奇怪它仍然不能工作...也许你可以检查libtess模块声明中的非ASCII字符、制表符和空格(我知道这是一个绝望的检查)。 - ph0b
输出结果并不完全相同,我已经更新了我的问题,并提供了解决方案。非常感谢@ph0b的帮助。 - Mauricio

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接