Tesseract是一个开源的OCR(Optical Character Recognition,光学字符识别)引擎,可以识别多种格式的图像文件并将其转换成文本。Tesseract最初由HP公司开发,后来由Google维护,目前Google开源到Github上。
如果想在ios开发中使用该引擎,就需要对源代码进行交叉编译。最近有该方向的需求,边查资料,边整理如下:
首先在Mac上编译需要安装一些依赖库和编译工具。
1.安装m4
curl -O http://mirrors.kernel.org/gnu/m4/m4-latest.tar.gz tar -xzvf m4-latest.tar.gz cd m4-1.4.17 ./configure --prefix=/usr/local make sudo make install
m4 是一种宏处理器,它扫描用户输入的文本并将其输出,期间如果遇到宏就将其展开后输出。宏有两种,一种是内建的,另一种是用户定义的,它们能接受任意数量的参数。 除了做展开宏的工作之外,m4 内建的宏能够加载文件,执行 Shell 命令,做整数运算,操纵文本,形成递归等等。m4 可用作编译器的前端,或者单纯作为宏处理器来用 。貌似是个很古老,很牛逼的东西,暂时接触不到,不深研究。
验证是否安装成功的方法如下:
在任意文件夹[vi hello.m4] 创建文件 hello.m4。
内容如下:
divert(0) define(say_hello_world, Hello World!) say_hello_world
保存后,执行如下命令:
$ m4 hello.m4 Hello World! //屏幕输出结果
安装成功!
2.安装autoconf
curl -O http://mirrors.kernel.org/gnu/autoconf/autoconf-latest.tar.gz tar -xzvf autoconf-latest.tar.gz cd autoconf-2.69 ./configure --prefix=/usr/local make sudo make install
Autoconf是一个用于包,以适应多种Unix类系统的 shell脚本的工具。由Autoconf生成的配置脚本在运行的时候与Autoconf是无关的, 就是说配置脚本的用户并不需要拥有Autoconf。
使用下面的命令,如果能正常输入版本信息,则安装成功。
autoconf --version
3.安装automake
curl -O http://mirrors.kernel.org/gnu/automake/automake-1.15.tar.xz tar -xzvf automake-1.15.tar.xz cd automake-1.15 ./configure --prefix=/usr/local make sudo make install
automake是一个从Makefile.am文件自动生成Makefile.in的工具。
使用下面的命令,如果能正常输入版本信息,则安装成功。
automake --version
4.安装libtool
curl -O http://mirrors.kernel.org/gnu/libtool/libtool-2.4.6.tar.gz tar -xzvf libtool-2.4.6.tar.gz cd libtool-2.4.6 ./configure --prefix=/usr/local make sudo make install
libtool 是一个通用库支持脚本,将使用动态库的复杂性隐藏在统一、可移植的接口中,也就是说,你可以通过如下所示的标准方法,在不同平台上创建并调用动态库,我们 可以认为libtool是gcc的一个抽象,也就是说,它包装了gcc或者其他的任何编译器,用户无需知道细节,只要告诉libtool说我需要要编译哪 些库即可,并且,它只与libtool文件打交道,例如lo、la为后缀的文件。
使用下面的命令,如果能正常输入版本信息,则安装成功。
libtool --version
5.下载leptonica
curl -O http://www.leptonica.com/source/leptonica-1.73.tar.gz tar -xzvf leptonica-1.73.tar.gz
leptonica是图形处理的基础类库,tesseract-ocr的依赖库。
6.安装gtk+(需要gtk中的pango模块)
brew install gtk+ brew link gtk+
brew 的安装方法请参考这里。
7.安装pkg-config,这是m4的模块。
brew install pkg-config brew link pkg-config
该模块没有安装或者没有加载,会提示PKG_CHECK_MODULES函数不存在的错误。
上面的安装是基于本人机器既有配置。如果安装不成功,请参照错误信息解决,例如提前需要安装gcc。
依赖库和工具安装完成。
开始编译 tesseract
创建编译用的文件夹
#!/bin/sh
# build.sh
GLOBAL_OUTDIR="`pwd`/dependencies"
LOCAL_OUTDIR="./outdir"
LEPTON_LIB="`pwd`/leptonica-1.73"
TESSERACT_LIB="`pwd`/tesseract"
IOS_BASE_SDK="9.3"
IOS_DEPLOY_TGT="7.0"
XCODE_DEVELOPER=/Applications/Xcode.app/Contents/Developer
XCODETOOLCHAIN=$XCODE_DEVELOPER/Toolchains/XcodeDefault.xctoolchain
SDK_IPHONEOS=$(xcrun --sdk iphoneos --show-sdk-path)
SDK_IPHONESIMULATOR=$(xcrun --sdk iphonesimulator --show-sdk-path)
setenv_all()
{
# Add internal libs
export CFLAGS="$CFLAGS -I$GLOBAL_OUTDIR/include -L$GLOBAL_OUTDIR/lib"
export CXX=`xcrun -find c++`
export CC=`xcrun -find cc`
export PATH="$XCODETOOLCHAIN/usr/bin:$PATH"
export LD=`xcrun -find ld`
export AR=`xcrun -find ar`
export AS=`xcrun -find as`
export NM=`xcrun -find nm`
export RANLIB=`xcrun -find ranlib`
export LDFLAGS="-L$SDKROOT/usr/lib/"
export CPPFLAGS=$CFLAGS
export CXXFLAGS=$CFLAGS
}
setenv_arm7()
{
unset SDKROOT CFLAGS CC LD CPP CXX AR AS NM CXXCPP RANLIB LDFLAGS CPPFLAGS CXXFLAGS
export SDKROOT=$SDK_IPHONEOS
export CFLAGS="-arch armv7 -pipe -no-cpp-precomp -isysroot $SDKROOT -miphoneos-version-min=$IOS_DEPLOY_TGT -I$SDKROOT/usr/include/"
setenv_all
}
setenv_arm7s()
{
unset DEVROOT SDKROOT CFLAGS CC LD CPP CXX AR AS NM CXXCPP RANLIB LDFLAGS CPPFLAGS CXXFLAGS
export SDKROOT=$SDK_IPHONEOS
export CFLAGS="-arch armv7s -pipe -no-cpp-precomp -isysroot $SDKROOT -miphoneos-version-min=$IOS_DEPLOY_TGT -I$SDKROOT/usr/include/"
setenv_all
}
setenv_arm64()
{
unset DEVROOT SDKROOT CFLAGS CC LD CPP CXX AR AS NM CXXCPP RANLIB LDFLAGS CPPFLAGS CXXFLAGS
export SDKROOT=$SDK_IPHONEOS
export CFLAGS="-arch arm64 -pipe -no-cpp-precomp -isysroot $SDKROOT -miphoneos-version-min=$IOS_DEPLOY_TGT -I$SDKROOT/usr/include/"
setenv_all
}
setenv_i386()
{
unset DEVROOT SDKROOT CFLAGS CC LD CPP CXX AR AS NM CXXCPP RANLIB LDFLAGS CPPFLAGS CXXFLAGS
export SDKROOT=$SDK_IPHONESIMULATOR
export CFLAGS="-arch i386 -pipe -no-cpp-precomp -isysroot $SDKROOT -miphoneos-version-min=$IOS_DEPLOY_TGT"
setenv_all
}
setenv_x86_64()
{
unset DEVROOT SDKROOT CFLAGS CC LD CPP CXX AR AS NM CXXCPP RANLIB LDFLAGS CPPFLAGS CXXFLAGS
export SDKROOT=$SDK_IPHONESIMULATOR
export CFLAGS="-arch x86_64 -pipe -no-cpp-precomp -isysroot $SDKROOT -miphoneos-version-min=$IOS_DEPLOY_TGT"
setenv_all
}
create_outdir_lipo()
{
for lib_i386 in `find $LOCAL_OUTDIR/i386 -name "lib*.a"`; do
lib_arm7=`echo $lib_i386 | sed "s/i386/arm7/g"`
lib_arm7s=`echo $lib_i386 | sed "s/i386/arm7s/g"`
lib_arm64=`echo $lib_i386 | sed "s/i386/arm64/g"`
lib=`echo $lib_i386 | sed "s/i386//g"`
lib_x86_64=`echo $lib_i386 | sed "s/i386/x86_64/g"`
xcrun -sdk iphoneos lipo -arch armv7 $lib_arm7 -arch armv7s $lib_arm7s -arch arm64 $lib_arm64 -arch x86_64 $lib_x86_64 -arch i386 $lib_i386 -create -output $lib
done
}
merge_libfiles()
{
DIR=$1
LIBNAME=$2
cd $DIR
for i in `find . -name "lib*.a"`; do
$AR -x $i
done
$AR -r $LIBNAME *.o
rm -rf *.o __*
cd -
}
build_leptonica()
{
#######################
# LEPTONLIB
#######################
cd $LEPTON_LIB
rm -rf $LOCAL_OUTDIR
mkdir -p $LOCAL_OUTDIR/arm7 $LOCAL_OUTDIR/arm7s $LOCAL_OUTDIR/arm64 $LOCAL_OUTDIR/i386 $LOCAL_OUTDIR/x86_64
make clean 2> /dev/null
make distclean 2> /dev/null
setenv_arm7
./configure --host=arm-apple-darwin7 --enable-shared=no --disable-programs --without-zlib --without-libpng --without-jpeg --without-giflib --without-libtiff
make -j12
cp -rvf src/.libs/lib*.a $LOCAL_OUTDIR/arm7
make clean 2> /dev/null
make distclean 2> /dev/null
setenv_arm7s
./configure --host=arm-apple-darwin7s --enable-shared=no --disable-programs --without-zlib --without-libpng --without-jpeg --without-giflib --without-libtiff
make -j12
cp -rvf src/.libs/lib*.a $LOCAL_OUTDIR/arm7s
make clean 2> /dev/null
make distclean 2> /dev/null
setenv_arm64
./configure --host=arm-apple-darwin64 --enable-shared=no --disable-programs --without-zlib --without-libpng --without-jpeg --without-giflib --without-libtiff
make -j12
cp -rvf src/.libs/lib*.a $LOCAL_OUTDIR/arm64
make clean 2> /dev/null
make distclean 2> /dev/null
setenv_i386
./configure --enable-shared=no --disable-programs --without-zlib --without-libpng --without-jpeg --without-giflib --without-libtiff
make -j12
cp -rvf src/.libs/lib*.a $LOCAL_OUTDIR/i386
make clean 2> /dev/null
make distclean 2> /dev/null
setenv_x86_64
./configure --host=x86_64-apple-darwin --enable-shared=no --disable-programs --without-zlib --without-libpng --without-jpeg --without-giflib --without-libtiff
make -j12
cp -rvf src/.libs/lib*.a $LOCAL_OUTDIR/x86_64
create_outdir_lipo
mkdir -p $GLOBAL_OUTDIR/include/leptonica && cp -rvf src/*.h $GLOBAL_OUTDIR/include/leptonica
mkdir -p $GLOBAL_OUTDIR/lib && cp -rvf $LOCAL_OUTDIR/lib*.a $GLOBAL_OUTDIR/lib
cd ..
}
build_tesseract()
{
#######################
# TESSERACT-OCR
#######################
cd $TESSERACT_LIB
rm -rf $LOCAL_OUTDIR
mkdir -p $LOCAL_OUTDIR/arm7 $LOCAL_OUTDIR/arm7s $LOCAL_OUTDIR/arm64 $LOCAL_OUTDIR/i386 $LOCAL_OUTDIR/x86_64
make clean 2> /dev/null
make distclean 2> /dev/null
setenv_arm7
bash autogen.sh
./configure --host=arm-apple-darwin7 --enable-shared=no LIBLEPT_HEADERSDIR=$GLOBAL_OUTDIR/include/
make -j12
for i in `find . -name "lib*.a" | grep -v arm`; do cp -rvf $i $LOCAL_OUTDIR/arm7; done
merge_libfiles $LOCAL_OUTDIR/arm7 libtesseract_all.a
make clean 2> /dev/null
make distclean 2> /dev/null
setenv_arm7s
bash autogen.sh
./configure --host=arm-apple-darwin7s --enable-shared=no LIBLEPT_HEADERSDIR=$GLOBAL_OUTDIR/include/
make -j12
for i in `find . -name "lib*.a" | grep -v arm`; do cp -rvf $i $LOCAL_OUTDIR/arm7s; done
merge_libfiles $LOCAL_OUTDIR/arm7s libtesseract_all.a
make clean 2> /dev/null
make distclean 2> /dev/null
setenv_arm64
bash autogen.sh
./configure --host=arm-apple-darwin64 --enable-shared=no LIBLEPT_HEADERSDIR=$GLOBAL_OUTDIR/include/
make -j12
for i in `find . -name "lib*.a" | grep -v arm`; do cp -rvf $i $LOCAL_OUTDIR/arm64; done
merge_libfiles $LOCAL_OUTDIR/arm64 libtesseract_all.a
make clean 2> /dev/null
make distclean 2> /dev/null
setenv_i386
bash autogen.sh
./configure --enable-shared=no LIBLEPT_HEADERSDIR=$GLOBAL_OUTDIR/include/
make -j12
for i in `find . -name "lib*.a" | grep -v arm`; do cp -rvf $i $LOCAL_OUTDIR/i386; done
merge_libfiles $LOCAL_OUTDIR/i386 libtesseract_all.a
make clean 2> /dev/null
make distclean 2> /dev/null
setenv_x86_64
bash autogen.sh
./configure --host=x86_64-apple-darwin --enable-shared=no LIBLEPT_HEADERSDIR=$GLOBAL_OUTDIR/include/
make -j12
for i in `find . -name "lib*.a" | grep -v arm | grep -v i386`; do cp -rvf $i $LOCAL_OUTDIR/x86_64; done
merge_libfiles $LOCAL_OUTDIR/x86_64 libtesseract_all.a
create_outdir_lipo
mkdir -p $GLOBAL_OUTDIR/include/tesseract
tess_inc=( api/apitypes.h api/baseapi.h ccmain/thresholder.h ccmain/resultiterator.h ccmain/pageiterator.h ccmain/ltrresultiterator.h
ccstruct/publictypes.h ccutil/errcode.h ccutil/genericvector.h ccutil/helpers.h ccutil/host.h ccutil/ndminx.h ccutil/ocrclass.h
ccutil/platform.h ccutil/tesscallback.h ccutil/unichar.h ccutil/unicharset.h ccutil/strngs.h ccutil/memry.h ccutil/unicharmap.h ccutil/fileerr.h ccutil/fileerr.h ccutil/serialis.h)
for i in "${tess_inc[@]}"; do
cp -rvf $i $GLOBAL_OUTDIR/include/tesseract
done
mkdir -p $GLOBAL_OUTDIR/lib && cp -rvf $LOCAL_OUTDIR/lib*.a $GLOBAL_OUTDIR/lib
make clean 2> /dev/null
make distclean 2> /dev/null
# rm -rf $LOCAL_OUTDIR
cd ..
}
build_leptonica
build_tesseract
echo "Finished!"
给 build.sh 添加执行权限,并执行
chmod +x build.sh ./build.sh
-------------------------------------
编译成功会提示[Finished!], 并且在生成以下目录结构的文件。
dependencies/include/leptonica/*.h (33个头文件) dependencies/include/tesseract/*.h (23个头文件) dependencies/lib/liblept.a dependencies/lib/libtesseract_all.a dependencies/lib/libtesseract_api.a dependencies/lib/libtesseract_ccstruct.a dependencies/lib/libtesseract_ccutil.a dependencies/lib/libtesseract_classify.a dependencies/lib/libtesseract_cube.a dependencies/lib/libtesseract_cutil.a dependencies/lib/libtesseract_dict.a dependencies/lib/libtesseract_main.a dependencies/lib/libtesseract_neural.a dependencies/lib/libtesseract_opencl.a dependencies/lib/libtesseract_textord.a dependencies/lib/libtesseract_viewer.a dependencies/lib/libtesseract_wordrec.a dependencies/lib/libtesseract.a
实际开发中只要将 include下的头文件,以及 [/lib/liblept.a],[libtesseract_all.a] 添加到工程中
就可以开发了。
编译过程到此结束, 如有问题可以留言。
除特别注明外,本站所有文章均为[果博]原创 » 转载请注明出处来自https://aiguor.com/notes/177.html
果博