opencv2.4.13+tesseract4.1交叉编译arm64
1.下载安装包 ,git拉取源码
我使用的交叉编译工具是**gcc-linaro-5.5.0-2017.10-x86_64_aarch64-linux-gnu.tar.xz**
然后因为需要用到c++17所以还有一个7.5的版本的
就是5.5用来编译opencv,7.5用来编译tesseract
在准备编译tesseract之前还需要安装一个libtool
sudo apt-get install libtools
主要原因opencv2.4.13不支持高版本的交叉编译器,不过网上说可以改动代码,我想这直接用低版本编译算了
1.1opencv的依赖即源码
- zlib1.2
- jpeg9
- png16
- opencv2.4.13
其他我的项目中没有用到,如果有需要可以在cmake中选中它们,比如ffmpeg,operexr,tiff等
1.2tesseract的依赖及源码
-
tiff4.0
-
zlib1.2
-
jpeg9
-
png16
-
leptonica1.84
-
拉取leptonice1.84 我当前拉取是这个版本
https://github.com/DanBloomberg/leptonica.git
-
拉取tesseract4.1 我拉取的4.1版本的,不知道怎么的话可以查一下
https://github.com/tesseract-ocr/tesseract.git
由于jpeg和png,zlib1.2是共用的,就没有在tesseract中写出
2.编译opencv依赖
我的编译过程也是在网上找的,问题有很多,我会写一个基本的过程,然后会有一些错误的处理方式,我也是网上找到的错误处理方式,我这里只算是一个总结
编译之前需要在PATH中将我们编译器加入进去,我们使用export来加入,这样就不会破坏系统的环境
export PATH=/home/xxx/编译器文件夹/bin:$PATH
加入成功后应该可以使用aarch64这个Tab出来编译器的种类的
需要创建一个文件夹,主要用来存储依赖 /home/xxx/depend
为了方便,把他加入到环境变量中
export DEPEND_PATH=/home/xxx/depend
最好还是单独在这里面创建一个文件 最后可以将所有的依赖的头文件和库放到一个文件夹中 因为涉及到.pc文件
2.1编译zlib1.2
-
进入到zlib1.2中,需要如果下载的压缩包需要解压然后进入
###首先修改默认编译器 CC=aarch64-linux-gnu-gcc CXX=aarch64-linux-gnu-g++ ###然后使用./configure来生成Makefile文件 如果有兴趣可以使用./configure --help看一下他的选项,遇到问题可以进去进去看看 ./configure prefix=$DEPEND_PATH/zlib ###没有报错就下一波 make -j8 make installs ###我编译zlib没有碰到错误,如果你有碰到,那没办法只能去网上找了
2.2编译jpeg
- 进入jpeg目录
./configure --host=arm-linux --prefix=$DEPEND_PATH/jpeg --enable-sharet --enable-static
###需要修改Makefile文件
###在CFLAGS 上加上-fPIC
make -j8
make install
2.3编译png
- 进入png目录
###png和jpeg有点不一样,需要指定zlib的位置
###如果Tab不出来,可以执行一下./autogen.sh 生成一下
./configure --host=arm-linux --enable-sharet --enable-static --prefix=$DEPEND_PATH/png CFLAGS=-I$DEPEND_PATH/zlib/include CPPFLAGS=-I$DEPEND_PATH/zlib/include LDFLAGS=-L$DEPEND_PATH/zlib/lib CC=aarch64-linux-gnu-gcc
###在这里如果提示找不到zlib,就把zlib的头文件和lib文件放到交叉编译器的目录,然后修改CFLAGS为编译器的目录,还有CPPFLAGS
make -j8
###如果编译出现找不到zlib.h的情况就修改CPPFLAGS为编译器的头文件目录
make install
3.编译opencv
3.1cmake-gui选择编译器,以及生成目录
按照需要输入
- 输入Linux
- 选择交叉C语言编译器 gcc
- 选择交叉C++编译器 g++
- 选择它们的路径 bin
- 选择最长的那个,都寻找的意思
2.2选择关闭一些功能
这些功能有些没有用,如果你用的上可以不关
示例
- 关闭WITH_1394
- 关闭ffmpeg
- 关闭ENABLE_PRECOMPILED_HEADERS (我也不知道为啥要关,我看别人都关了)
- 关闭openex
- 打开BUILD_TIFF (主要是因为我没有整明白怎么去添加我自己编译的库,所以就直接使用opencv提供的算了,版本差不多)
然后就是检查我们编译的库在cmake中有没有被选中,类似这个名字BUILD_PNG的,这是使用opencv提供的库,他的版本和我们不一样,所以我需要修改为我们自己的编译的库
2.3修改一些地址
修改最后生成的库的位置
- 添加jpeg库位置
需要点击Add Entry添加 注意JPEG_LIBRARY需要选择FILEPATH,然后直接给上静态库位置
-
添加png
-
添加zlib类似
当都选择或填入完成后
依次点击
make -j8
###过程中会有很多警告,目前我使用来看,没有什么问题
make
到这里opencv就编译完成了
4.编译tesseract依赖
4.1编译leptonica
注意:在前面我们使用的5.5来编译我们所需的依赖库的,现在我们需要使用7.5来编译leptonica的依赖,就是说要重新编译zlib,jpeg,png,tiff
编译过程和前面一样,我就不演示了,主要是需要重新启动终端,然后换一个地址
export PATH=/home/xxx/编译器文件夹/bin:$PATH
export DEPEND_PATH=/home/xxx/depend_7.5/
-
进入到leptonica目录
###比较麻烦所以需要仔细看 下面可以不指定试试,把前面所有编译好的头文件,库文件都放到编译器的目录里面 ###指定zlib,jpeg,png,tiff库的pkgconfigu目录 export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:$DEPEND_PATH/zlib/lib/pkgconfig:$DEPEND_PATH/png/lib/pkgconfig:$DEPEND_PATH/jpeg/lib/pkgconfig:$DEPEND_PATH/tiff/lib/pkgconfig ###指定zlib,jpeg,png,tiff的库目录 export ZLIB_LIBS=$DEPEND_PATH/zlib/lib export JPEG_LIBS=$DEPEND_PATH/jpeg/lib export PNG_LIBS=$DEPEND_PATH/png/lib export TIFF_LIBS=$DEPEND_PATH/tiff/lib ###指定它们的头文件位置 export ZLIB_CFLAGS=$DEPEND_PATH/zlib/include/ export JPEG_CFLAGS=$DEPEND_PATH/jpeg/include/ export PNG_CFLAGS=$DEPEND_PATH/png/include/ export TIFF_CFLAGS=$DEPEND_PATH/tiff/include/ ###指定连接类型 export LDFLAGS="-L$DEPEND_PATH/zlib/lib -L$DEPEND_PATH/jpeg/lib -L$DEPEND_PATH/png/lib -L$DEPEND_PATH/tiff/lib" export CFLAGS="-I$DEPEND_PATH/zlib/include -I$DEPEND_PATH/jpeg/include -I$DEPEND_PATH/png/include -I$DEPEND_PATH/tiff/include" export LIBS="-ljpeg -lz -lpng -ltiff" ###如果config.log文件中出现错误,说明版本不对,可能交叉编译便混了,需要重新来 configure:2943: aarch64-linux-gnu-gcc -I/home/xxx/yyy/arm64-7.5/include -L/home/xxx/yyy/arm64-7.5/lib conftest.c -ljpeg -lz -lpng -ltiff >&5 /home/xxx/yyy/arm64-7.5/bin/../lib/gcc/aarch64-linux-gnu/7.5.0/../../../../aarch64-linux-gnu/bin/ld: skipping incompatible /home/xxx/yyy/arm64-7.5/lib/libz.so when searching for -lz /home/xxx/yyy/arm64-7.5/bin/../lib/gcc/aarch64-linux-gnu/7.5.0/../../../../aarch64-linux-gnu/bin/ld: skipping incompatible /home/xxx/yyy/arm64-7.5/lib/libz.a when searching for -lz /home/xxx/yyy/arm64-7.5/bin/../lib/gcc/aarch64-linux-gnu/7.5.0/../../../../aarch64-linux-gnu/bin/ld: cannot find -lz collect2: error: ld returned 1 exit status ###执行./configure 可以不设置前面的环境变量,直接将所有的库文件,头文件放到交叉编译器的目录中 ./configure --host=arm-linux CC=aarch64-linux-gnu-gcc CXX=aarch64-linux-gnu-g++ --prefix=$DEPEND_PATH/leptonica make -j8 make install
注意:make leptonice时可能会出现下面的错误
CC libversions.lo
In file included from alltypes.h:37:0,
from allheaders.h:35,
from jpegio.c:129:
environ.h:295:23: error: expected identifier before numeric constant
#define FALSE 0
^
/home/xxx/yyy/arm64-7.5/include/jmorecfg.h:263:16: note: in expansion of macro ‘FALSE’
typedef enum { FALSE = 0, TRUE = 1 } boolean;
^~~~~
aarch64-linux-gnu-gcc: warning: /home/xxx/depend_7.5//zlib/include/: linker input file unused because linking not done
aarch64-linux-gnu-gcc: warning: /home/xxx/depend_7.5//jpeg/include/: linker input file unused because linking not done
Makefile:757: recipe for target 'jpegio.lo' failed
make[2]: *** [jpegio.lo] Error 1
make[2]: *** 正在等待未完成的任务....
aarch64-linux-gnu-gcc: warning: /home/xxx/depend_7.5//zlib/include/: linker input file unused because linking not done
aarch64-linux-gnu-gcc: warning: /home/xxx/depend_7.5//jpeg/include/: linker input file unused because linking not done
In file included from alltypes.h:37:0,
from allheaders.h:35,
from libversions.c:40:
environ.h:295:23: error: expected identifier before numeric constant
#define FALSE 0
^
/home/xxx/yyy/arm64-7.5/include/jmorecfg.h:263:16: note: in expansion of macro ‘FALSE’
typedef enum { FALSE = 0, TRUE = 1 } boolean;
^~~~~
Makefile:757: recipe for target 'libversions.lo' failed
make[2]: *** [libversions.lo] Error 1
aarch64-linux-gnu-gcc: warning: /home/xxx/depend_7.5//zlib/include/: linker input file unused because linking not done
aarch64-linux-gnu-gcc: warning: /home/xxx/depend_7.5//jpeg/include/: linker input file unused because linking not done
make[2]: Leaving directory '/home/xxx/yyy/leptonica/src'
Makefile:533: recipe for target 'all-recursive' failed
make[1]: *** [all-recursive] Error 1
解决办法就是在jpeg的源目录中的jmorecfg.h文件修改,把它里面关于
typedef enum{FALSE = 0, TRUE =1}boolean;
这一整段移动到environ.h 的#defiine FALSE 0前面
这么修改
修改完成以后继续make
5.编译tesseract
5.1生成./configure
./autogen.sh
5.2编译
###因为刚编译好lettonica需要把他的目录加入进来,所有前面编译lettonica依赖的时候的环境变量都要来一遍
PKG_CONFIG_PATH=$PKG_CONFIG_PATH:$DEPEND_PATH/leptonica/lib/pkgconfig
export ZLIB_LIBS=$DEPEND_PATH/leptonica/lib
export ZLIB_CFLAGS=$DEPEND_PATH/leptonica/include/
export LDFLAGS=$LDFLAGS:"-L$DEPEND_PATH/leptonica/lib"
export CFLAGS=$CFIAGS:"-I$DEPEND_PATH/leptonica/include"
export LIBS="-ljpeg -lz -lpng -ltiff -lleptonica"
./configure --host=arm-linux --prefix=/home/xxx/tesseract_arm64
###可能会出现错误
checking for pkg-config... /usr/bin/pkg-config
checking pkg-config is at least version 0.9.0... yes
checking for LEPTONICA... no
configure: error: Leptonica 1.74 or higher is required. Try to install libleptonica-dev package.
###解决办法
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:$DEPEND_PATH/leptonica/lib/pkgconfig
###make
make -j8
###make时出现的错误
devanagari_processing.cpp: In member function ‘bool tesseract::ShiroRekhaSplitter::Split(bool, tesseract::DebugPixa*)’:
devanagari_processing.cpp:132:19: error: invalid use of incomplete type ‘struct Pixa’
Box* box = ccs->boxa->box[i];
^
In file included from /home/xxx/depend_7.5//leptonica/include/leptonica/alltypes.h:52:0,
from /home/xxx/depend_7.5//leptonica/include/leptonica/allheaders.h:35,
from devanagari_processing.cpp:25:
/home/xxx/depend_7.5//leptonica/include/leptonica/bmf.h:48:12: note: forward declaration of ‘struct Pixa’
struct Pixa *pixa; /*!< pixa of bitmaps for 93 characters */
^
###解决办法
###需要在leptonica/src/alltypes.h文件中加入一个头文件,alltypes.h #include "pix_internal.h"
###也可以升级tesseract到5.x版本这个是因为leptonica版本高了
###可以修改源文件,然后重新编译,也可以直接修改交叉编译器里面的alltypes.h文件和我们指定的目录下的alltypes.h
make clean
make install
到了这里编译就完成了
编译的最后,如果中间遇到什么问题,首先先检查输入的参数有没有问题,如果没有问题,就重新下载安装,重新编译依赖,编译项目
6.在cmake中使用它们
set(OpenCV_DIR ${CMAKE_CURRENT_SOURCE_DIR}/linux_arm64/opencv2.4.13/)
set(OPENCV_INC ${OpenCV_DIR}include CACHE INTERNAL "opencv include" )
set(CMAKE_PREFIX_PATH ${OpenCV_DIR}/share/OpenCV/)
if (NOT ${OpenCV_DIR} STREQUAL "")
#查找包路径
find_package(OpenCV REQUIRED)
endif()
target_include_directories(${PROJECT_NAME} PUBLIC ${OPENCV_INC})
target_link_libraries(${PROJECT_NAME} PUBLIC opencv)
set(DIR_ALL ${CMAKE_CURRENT_SOURCE_DIR}/linux_arm64/tesseract-5.3/)
set(Tesseract_DIR ${DIR_ALL}tesseract/)
set(Leptonica_DIR ${DIR_ALL}leptonica/)
set(Jpeg_DIR ${DIR_ALL}jpeg/)
set(Tiff_DIR ${DIR_ALL}tiff/)
set(Png_DIR ${DIR_ALL}png/)
set(Zlib_DIR ${DIR_ALL}zlib/)
set(Tesseract_INC ${Tesseract_DIR}include CACHE INTERNAL "Tesseract include" )
set(Leptonica_INC ${Leptonica_DIR}include CACHE INTERNAL "Leptonica include" )
set(Jpeg_INC ${Jpeg_DIR}include CACHE INTERNAL "Jpeg include" )
set(Jpeg_INC ${Tiff_DIR}include CACHE INTERNAL "Tiff include" )
set(Jpeg_INC ${Png_DIR}include CACHE INTERNAL "Png include" )
set(Zlib_INC ${Zlib_DIR}include CACHE INTERNAL "zlib include" )
##包含zlib库
include_directories( ${Zlib_DIR}/include)
link_directories( ${Zlib_DIR}/lib/libz.so )
target_link_libraries(${PROJECT_NAME} INTERFACE ${Zlib_DIR}/lib/libz.so )
##包含tiff库
include_directories( ${Tiff_DIR}/include)
link_directories(${Tiff_DIR}/lib/libtiff.so ${Tiff_DIR}/lib/libtiff.so )
target_link_libraries(${PROJECT_NAME} INTERFACE ${Tiff_DIR}/lib/libtiff.so ${Tiff_DIR}/lib/libtiff.so )
##包含png库
include_directories( ${Png_DIR}/include)
link_directories(${Png_DIR}/lib/libpng.so ${Png_DIR}/lib/libpng16.so)
target_link_libraries(${PROJECT_NAME} INTERFACE ${Png_DIR}/lib/libpng.so ${Png_DIR}/lib/libpng16.so)
##包含jpeg库
include_directories( ${Jpeg_DIR}/include)
link_directories(${Jpeg_DIR}/lib/libjpeg.so)
target_link_libraries(${PROJECT_NAME} INTERFACE ${Jpeg_DIR}/lib/libjpeg.so)
##包含leptonica库
include_directories( ${Leptonica_DIR}/include)
link_directories(${Leptonica_DIR}/lib/libleptonica.so)
target_link_libraries(${PROJECT_NAME} INTERFACE ${Leptonica_DIR}/lib/libleptonica.so)
#包含tesseract库
include_directories( ${Tesseract_DIR}/include)
link_directories(${Tesseract_DIR}/lib/libleptonica.so)
target_link_libraries(${PROJECT_NAME} INTERFACE ${Tesseract_DIR}/lib/libtesseract.so)
ca库
include_directories(
L
e
p
t
o
n
i
c
a
D
I
R
/
i
n
c
l
u
d
e
)
l
i
n
k
d
i
r
e
c
t
o
r
i
e
s
(
{Leptonica_DIR}/include) link_directories(
LeptonicaDIR/include)linkdirectories({Leptonica_DIR}/lib/libleptonica.so)
target_link_libraries(${PROJECT_NAME} INTERFACE ${Leptonica_DIR}/lib/libleptonica.so)
#包含tesseract库
include_directories( ${Tesseract_DIR}/include)
link_directories(${Tesseract_DIR}/lib/libleptonica.so)
target_link_libraries(${PROJECT_NAME} INTERFACE ${Tesseract_DIR}/lib/libtesseract.so)
实在是不想写了,如果你要是看不明白这个cmake可以直接粘贴到gpt上,让他分析,我这个是把第三库当作子模块使用的,不过直接用应该也能用