Issue
I followed the instructions from here and added OpenCV successfully. But I've been trying to add tesseract to the Android.mk as well, for a few days now, and haven't been able to do it.
I have an android.cpp that uses tesseract so I have to include the dependency in my Android.mk . I found this post that had almost the exact problem and he solved it importing libtess.so and liblept.so files into Android.mk, but didn't explain how to do that, so I looked and found this post that shows how to link prebuilt libraries. So based on that I tried this 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)
And got this output:
[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.
So I guess is not linking libtess correctly, and if you look closely, it doesn't ever install libtess.so, it looks like it installs liblept.so, and then jumps to text_detect.cpp, ignoring this part:
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)
So I tried to force it to install liblept and libtess completely before proceeding by putting it in different files. So I put the last part of the file in a different Android.mk in another folder and tried include $(call all-subdir-makefiles), and then it installs libtess and liblept completely, but ignores the call all-subdir-makefiles.
new jni folder structure:
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)
And this is the output:
[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
As you see it installs everything from the first Android.mk perfectly, but it never runs textdetect/Android.mk
So, what I'm I doing wrong? How can I achieve this task that seems so simple? Is there an easier way?
EDIT:
After @ph0b response I went back to my first setup and added the same LOCAL_EXPORT_C_INCLUDES
as the original Makefiles (with a couple of variations adapting it to my paths), and that solved it. It couldn't find platform.h
because it didn't know where to look for it.
Now, after I did this change I had a different error No such file or directory #include "com_googlecode_tesseract_android/src/api/baseapi.h"
and I thought this was because it didn't compile tesseract before run_detection
that depends on it. Well that wasn't the problem, it still compiles run_detection
before tesseract but that wasn't the issue, it was so much simpler and I feel so stupid for having spent so much time on this error. The problem was it didn't find com_googlecode_tesseract_android/src/api/baseapi.h
because I didn't provide the path for that either, so I copied com_googlecode_tesseract_android
and com_googlecode_leptonica_android
from tess-two and added $(LOCAL_PATH)
to LOCAL_EXPORT_C_INCLUDES
. This is my final solution:
jni folder structure:
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)
Solution
Your latest setup is failing in a weird way, ndk-build should at least try to compile your module. Maybe there is a bug in all-subdir-makefiles
when there are ndk modules defined before it, and it doesn't find your module's Android.mk. You can try having only include $(call all-subdir-makefiles)
inside your top level Android.mk.
Anyway, I think you should go back to your first setup, with your module directly in the jni root folder. Then, your main issue is the proper declaration of includes paths. tess-two/jni doesn't contain any headers ? They're in tess-two/jni/com_googlecode_*_android/src/*
. That means you need to list these in your module declarations, by giving all the absolute paths to LOCAL_EXPORT_C_INCLUDES
variables (like from the original Makefiles: https://github.com/rmtheis/tess-two/blob/master/tess-two/jni/com_googlecode_tesseract_android/Android.mk#L33)
You also need to add the dependency on liblept for libtess: LOCAL_SHARED_LIBRARIES := liblept
inside libtess library declaration.
If it still fails, there is also another possibility: instead of redefining libtess and liblept modules using the generated .so files, you can directly include tess-two/jni/Android.mk
and use the same Application.mk than tess-two (copy `tess-two/jni/Application.mk). It will already properly define libtess and liblept modules.
Answered By - ph0b
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.