tesseract3.0.2在mac 10.10上的编译 xcode6
2015-05-24 19:53
169 查看
一. 编译tesseract的系统环境:
mac系统版本:OS X Yosemite 10.10Xcode版本:Version 6.2 (6C131e)
iOS SDK:8.0
二. 准备工作:
1、下载源代码
1.tesseract (https://code.google.com/p/tesseract-ocr/downloads/list)2.tesseract语言包
3.leptonica(tesseract依赖于它) (http://www.leptonica.com/download.html)
2、新建文件夹 compile_code,讲上面下载的tesseract,leptonica都解压在这里
三. 开始编译:
开发环境配置有很多种,我使用的是MacPort的方式(主要是我第一个接触的就是它,懒得去换了)1.下载MacPort(http://www.macports.org/install.php)
2.修改/opt/local/etc/macports/sources.conf文件
官网修改方案:http://trac.macports.org/wiki/howto/PortTreeTarballsudo vim /opt/local/etc/macports/sources.conf
找到:rsync://rsync.macports.org/release/ports/[default]
修改为:https://distfiles.macports.org/ports.tar.gz [default]
打开终端,输入下面的命令,等待更新结束
sudo port –d sync
3.按顺序安装所需要的工具:M4-> autoconf -> automake -> libtool
以M4安装为例:sudo port install M4
4.进入文件夹compile_code,新建脚本文件build.sh
内容如下:#!/bin/sh GLOBAL_OUTDIR="`pwd`/build" LOCAL_OUTDIR="./outdir" LEPTON_LIB="`pwd`/leptonica-1.72" TESSERACT_LIB="`pwd`/tesseract-ocr" IOS_BASE_SDK="8.0" IOS_DEPLOY_TGT="8.0" # 设置编译器、连接器 export CXX=`xcrun -find c++` export CC=`xcrun -find cc` 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` # 设置编译器路径、模拟器路径 XCODE_DEVELOPER_PATH=/Applications/Xcode.app/Contents/Developer XCODETOOLCHAIN_PATH=$XCODE_DEVELOPER_PATH/Toolchains/XcodeDefault.xctoolchain SDK_IPHONEOS_PATH=$(xcrun --sdk iphoneos --show-sdk-path) SDK_IPHONESIMULATOR_PATH=$(xcrun --sdk iphonesimulator --show-sdk-path) export PATH="$XCODETOOLCHAIN_PATH/usr/bin:$PATH" declare -a archs archs=(arm7 arm7s arm64 i386 x86_64) declare -a arch_name arch_names=(arm-apple-darwin7 arm-apple-darwin7s arm-apple-darwin64 i386-apple-darwin x86_64-apple-darwin) # 设置编译参数 setenv_all() { # Add internal libs export CFLAGS="$CFLAGS -I$GLOBAL_OUTDIR/include -L$GLOBAL_OUTDIR/lib -Qunused-arguments" export LDFLAGS="-L$SDKROOT/usr/lib/" export CPPFLAGS=$CFLAGS export CXXFLAGS=$CFLAGS } setenv_arm7() { unset DEVROOT SDKROOT CFLAGS CPP CXXCPP LDFLAGS CPPFLAGS CXXFLAGS export SDKROOT=$SDK_IPHONEOS_PATH 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 CPP CXXCPP LDFLAGS CPPFLAGS CXXFLAGS export SDKROOT=$SDK_IPHONEOS_PATH 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 CPP CXXCPP LDFLAGS CPPFLAGS CXXFLAGS export SDKROOT=$SDK_IPHONEOS_PATH 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 CPP CXXCPP LDFLAGS CPPFLAGS CXXFLAGS export SDKROOT=$SDK_IPHONESIMULATOR_PATH 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 CPP CXXCPP LDFLAGS CPPFLAGS CXXFLAGS export SDKROOT=$SDK_IPHONESIMULATOR_PATH export CFLAGS="-arch x86_64 -pipe -no-cpp-precomp -isysroot $SDKROOT -miphoneos-version-min=$IOS_DEPLOY_TGT" setenv_all } # 合并库(用于模拟器与真机同时使用) create_outdir_lipo() { for file in `find $LOCAL_OUTDIR/i386 -name "lib*.a"`; do lib_arm7=`echo $file | sed "s/i386/arm7/g"` lib_arm7s=`echo $file | sed "s/i386/arm7s/g"` lib_arm64=`echo $file | sed "s/i386/arm64/g"` lib_x86_64=`echo $file | sed "s/i386/x86_64/g"` lib_i386=`echo $file` lib=`echo $file | sed "s/i386//g"` xcrun -sdk iphoneos lipo -arch armv7s $lib_arm7s -arch armv7 $lib_arm7 -arch arm64 $lib_arm64 -arch i386 $lib_i386 -arch x86_64 $lib_x86_64 -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 - } # 下载源代码 #get_leptonica() #{ # curl -C - -O http://www.leptonica.com/source/leptonica-1.68.tar.gz # tar xzvf leptonica-1.68.tar.gz #} #get_tessreact() #{ # curl -C - -O http://tesseract-ocr.googlecode.com/files/tesseract-3.01.tar.gz # tar xzvf tesseract-3.01.tar.gz #} ####################### # 清理工作空间 ####################### rm -rf $GLOBAL_OUTDIR lib include ######################## ## 下载需要编译的文件 ######################## ## 下载leptonica #get_leptonica ## 下载tessreact #get_tessreact ####################### # 进入LEPTONLIB目录 ####################### cd $LEPTON_LIB rm -rf $LOCAL_OUTDIR for n in "${!archs[@]}" do mkdir -p "$LOCAL_OUTDIR/${archs[$n]}" make clean 2> /dev/null make distclean 2> /dev/null eval "setenv_${archs[$n]}" ./configure --host="${arch_names[$n]}" --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/${archs[$n]}" done create_outdir_lipo mkdir -p $GLOBAL_OUTDIR/include/leptonica && find ./ -name '*.h' -exec cp {} $GLOBAL_OUTDIR/include/leptonica/ \; mkdir -p $GLOBAL_OUTDIR/lib && cp -rvf $LOCAL_OUTDIR/lib*.a $GLOBAL_OUTDIR/lib cd .. ####################### # 进入TESSERACT目录 ####################### cd $TESSERACT_LIB rm -rf $LOCAL_OUTDIR for n in "${!archs[@]}" do mkdir -p "$LOCAL_OUTDIR/${archs[$n]}" make clean 2> /dev/null make distclean 2> /dev/null eval "setenv_${archs[$n]}" bash autogen.sh LIBLEPT_HEADERSDIR=$GLOBAL_OUTDIR/include ./configure --host="${arch_names[$n]}" --enable-shared=no --disable-graphics make -j12 for i in `find . -name "lib*.a" | grep -v $LOCAL_OUTDIR` do cp -rvf $i "$LOCAL_OUTDIR/${archs[$n]}" done merge_libfiles "$LOCAL_OUTDIR/${archs[$n]}" libtesseract_all.a done create_outdir_lipo mkdir -p $GLOBAL_OUTDIR/include/tesseract && find ./ -name '*.h' -exec cp {} $GLOBAL_OUTDIR/include/tesseract/ \; mkdir -p $GLOBAL_OUTDIR/lib && cp -rvf $LOCAL_OUTDIR/lib*.a $GLOBAL_OUTDIR/lib make clean 2> /dev/null make distclean 2> /dev/null cd .. ####################### # Copying ####################### cp -rf $GLOBAL_OUTDIR/include . mkdir -p lib cp -rf $GLOBAL_OUTDIR/lib/libtesseract_all.a $GLOBAL_OUTDIR/lib/liblept.a lib/ echo "Finished!"
6.为build.sh增加可执行权限:
chmod a+x build.sh
7.终端中运行build.sh
运行结束后会在文件夹compile_code中的lib文件夹中生成两个*.a文件,include文件夹中生成头文件,这两个文件夹引入工程中即可使用该框架了。四. iOS上的tesseract实现
/* * tesseract.h(来源网上) */ #import <Foundation/Foundation.h> #import <UIKit/UIKit.h> @interface Tesseract : NSObject { // OCR识别库 NSString* _dataPath; // 需要识别的语言 NSString* _language; // tesseract参数 NSMutableDictionary* _variables; } + (NSString *)version; /** * 设置OCR识别参数 * * @param dataPath OCR识别库 * @param language 所选用的语言 */ - (id)initWithDataPath:(NSString *)dataPath language:(NSString *)language; - (void)setVariableValue:(NSString *)value forKey:(NSString *)key; /** * 设置识别的图片 * * @param image 需要识别的图片 */ - (void)setImage:(UIImage *)image; /** * OCR识别语言设置 * * @param language 需要识别的语言 */ - (BOOL)setLanguage:(NSString *)language; - (BOOL)recognize; - (NSString *)recognizedText; @end
/* * tesseract.mm */ #import "Tesseract.h" #import "baseapi.h" #import "environ.h" #import "pix.h" namespace tesseract { class TessBaseAPI; }; @interface Tesseract () { tesseract::TessBaseAPI* _tesseract; // 转换为二进制的图片数据 uint32_t* _pixels; } @end @implementation Tesseract /** * 获取版本信息 */ + (NSString *)version { return [NSString stringWithFormat:@"%s", tesseract::TessBaseAPI::Version()]; } /** * 设置参数 * * @param dataPath 黑白名单设置 * @param language 所选用的语言 */ - (id)initWithDataPath:(NSString *)dataPath language:(NSString *)language { self = [super init]; if (self) { _dataPath = dataPath; _language = language; _variables = [[NSMutableDictionary alloc] init]; [self copyDataToDocumentsDirectory]; _tesseract = new tesseract::TessBaseAPI(); BOOL success = [self initEngine]; if (!success) { return nil; } } return self; } /** * 初始化tesseract识别 */ - (BOOL)initEngine { int returnCode = _tesseract->Init([_dataPath UTF8String], [_language UTF8String]); return (returnCode == 0) ? YES : NO; } /** * 将识别库拷贝至 Documents 文件夹 */ - (void)copyDataToDocumentsDirectory { // Useful paths NSFileManager *fileManager = [NSFileManager defaultManager]; NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentPath = ([documentPaths count] > 0) ? [documentPaths objectAtIndex:0] : nil; NSString *dataPath = [documentPath stringByAppendingPathComponent:_dataPath]; // Copy data in Doc Directory if (![fileManager fileExistsAtPath:dataPath]) { NSString *bundlePath = [[NSBundle bundleForClass:[self class]] bundlePath]; NSString *tessdataPath = [bundlePath stringByAppendingPathComponent:_dataPath]; if (tessdataPath) { [fileManager createDirectoryAtPath:documentPath withIntermediateDirectories:YES attributes:nil error:NULL]; [fileManager copyItemAtPath:tessdataPath toPath:dataPath error:nil]; } } setenv("TESSDATA_PREFIX", [[documentPath stringByAppendingString:@"/"] UTF8String], 1); } /** * 设置OCR识别参数 * * @param value OCR识别参数属性 * @param key OCR识别参数键值(参考Tesseract源代码:contrib/dump.config) */ - (void)setVariableValue:(NSString *)value forKey:(NSString *)key { /* * Example: * _tesseract->SetVariable("tessedit_char_whitelist", "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"); * _tesseract->SetVariable("language_model_penalty_non_freq_dict_word", "0"); * _tesseract->SetVariable("language_model_penalty_non_dict_word ", "0"); */ [_variables setValue:value forKey:key]; _tesseract->SetVariable([key UTF8String], [value UTF8String]); } /** * 重新设置OCR识别参数 */ - (void)loadVariables { for (NSString* key in _variables) { NSString* value = [_variables objectForKey:key]; _tesseract->SetVariable([key UTF8String], [value UTF8String]); } } /** * 设置识别语言 */ - (BOOL)setLanguage:(NSString *)language { _language = language; // int returnCode = [self initEngine]; // if (returnCode != 0) return NO; /* * "WARNING: On changing languages, all Tesseract parameters * are reset back to their default values." */ [self loadVariables]; return YES; } /** * OCR识别 * * @return 识别是否成功 */ - (BOOL)recognize { int returnCode = _tesseract->Recognize(NULL); return (returnCode == 0) ? YES : NO; } /** * OCR识别 * * @return 识别出来的文本 */ - (NSString *)recognizedText { char* utf8Text = _tesseract->GetUTF8Text(); return [NSString stringWithUTF8String:utf8Text]; } /** * 设置识别的图片 * * @param image 需要识别的图片 */ - (void)setImage:(UIImage *)image { free(_pixels); CGSize size = [image size]; int width = size.width; int height = size.height; if (width <= 0 || height <= 0) { return; } _pixels = (uint32_t *) malloc(width * height * sizeof(uint32_t)); // 清空图片缓存数组 memset(_pixels, 0, width * height * sizeof(uint32_t)); // 申请RGA图片缓存 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); // 申请 _pixels 图片上下文 CGContextRef context = CGBitmapContextCreate(_pixels, width, height, 8, width * sizeof(uint32_t), colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedLast); // 向上下文填充二进制图片数据(该数据会填充到_pixels数组中) CGContextDrawImage(context, CGRectMake(0, 0, width, height), [image CGImage]); // 释放上下文与颜色空间 CGContextRelease(context); CGColorSpaceRelease(colorSpace); // 传递图片给 Tesseract 库 _tesseract->SetImage((const unsigned char *) _pixels, width, height, sizeof(uint32_t), width * sizeof(uint32_t)); } -(void)dealloc{ // 关闭tesseract _tesseract->End(); } @end
Tesseract* tesseract = [[Tesseract alloc] initWithDataPath:@"tessdata" language:@"eng"]; self.tesseract = tesseract; // tesseract参数 // [tesseract setVariableValue:@"textord_words_default_minspace" forKey:@"0.2"]; // [tesseract setVariableValue:@"textord_words_width_ild" forKey:@"0.4"]; // 设置需要识别的图片 UIImage *image = [UIImage imageNamed:@"Capture2.png"]; UIImage *conImage = image; // 图像预处理 conImage = [UIImage convertToGrayscale:conImage]; conImage = [conImage sharpen]; conImage = [UIImage grayImage:conImage]; // 显示图片 self.imageView.image = image; self.conImageView.image = conImage; [self.tesseract setImage:conImage]; [self.tesseract recognize]; NSLog(@"%@", [self.tesseract recognizedText]); [self.tesseract setImage:nil];
五. tesseract小结
网上的一些资料都感觉很古老,很陈旧了,编写这部分代码什么的也弄了2天多的时间。程序现在感觉还是有些问题,但是起码可以识别一些效果比较好的英文了。有时间还会继续研究。个人认为,后续的研究应该就是图像预处理的部分了,有熟悉的大师也可以帮助一下。互勉,共同进步。网上感觉不错的例子:https://github.com/gali8/Tesseract-OCR-iOS或者http://code4app.com/ios/Tesseract-OCR/533d7ada933bf024048b4c8b
一些简单的图像处理函数:http://pan.baidu.com/share/link?shareid=1816900461&uk=218547027(自己网上摘的)
按照网上的说法,tesseract识别的关键点在于字典训练还有图片预处理,因此后续研究方向估计就是图片预处理这部分了。
相关文章推荐
- tesseract-ocr 3.0.2 iPhone编译 xcode6 sdk8
- tesseract-ocr mac编译
- Mac OS X 10.10编译Hadoop 2.6.0笔记
- Mac 10.10 下载、编译android4.4过程及注意事项
- mac OS X 10.10更新gcc 4.9.1后默认无法编译连接的问题
- mac OS X 10.10更新gcc 4.9.1后默认无法编译连接的问题
- Mac OS X 10.10 编译代码出错 fatal error: '__debug' file not found #include <__debug>
- mac OS X 10.10更新gcc 4.9.1后默认无法编译连接的问题
- MAC OS X 10.10编译android5.0源码 步骤 以及 遇到的问题
- mac 10.10 编译 android aosp
- Mac(10.10) 下编译Android4.0源码问题归集
- 安装编译和使用OpenCV(Mac OS X 10.10)
- Mac下编译tesseract报错 DotProductAVX can't be used on Android
- Mac 10.10 编译android 4.4.4 for nexus
- mac10.10 编译mcrypt时,找不到php.h文件的解决办法
- mac 10.10 下编译 ogre 1.10
- mac下反编译apk
- MAC之Qt在Xcode8上编译错误( 二)
- Tesseract编译安装
- ios&mac下编译protobuf C++静态库