iOS汉字识别改进算法

简介

前边一篇文章介绍了班讯通中新加的一个根据拼音写汉字功能的第一版本算法实现,今天说一说改进之后的算法。

班讯通3.2版本提交之后,我们对汉字识别算法进行了改进,并且将该模块抽离出来完善成了一个新的应用--写霸,现已经通过appstore审核上线, 欢迎大家下载体验。


进入正题

在第一版本中,我们将整个字拆为若干笔画存入数据库,每条笔画记录都对应若干条点记录,模板和用户记录均如此,在对比模板和用户数据的时候,根据笔画id对比相应的记录,最后根据匹配结果计算分数。新的版本里,我们在数据库中为所有笔画建立模型,然后每个字对应若干笔画模型。用户写字提交之后,分析用户输入的每一个笔画,在模板表中匹配出到若干笔画,再看与模板是否一致,从而得出分数。以下是详细过程

1.提炼笔画模型

在网上查到有三十一个笔画,于是将三十一个笔画一一录入,然后观察其特点。最后决定再将每一个笔画细分成几个线段,比如横折钩,拆成三段。具体做法是:写某一个笔画的时候,计算相邻两个点所成直线与水平直线的角度, 当这个角度与前两个点成直线的角度相差大于某个值(比如15度)的时候,就认为该笔画又多了一段。最后把该笔画所有线段id和线段平均角度存入数据库,这样一个笔画就对应若干个线段了。

// 解析笔画模型

- (void)featurePoints {
    
    NSArray *array = self.gridArray;
    
    if ([array count] < 4) {
        self.gridArray = self.pointArray;
        array = self.pointArray;
    }
    CGPoint point;
    CGPoint point0;
    CGPoint point1;
    CGPoint point2;
    int tag = 0;
    
    double angle0 = 0.0;
    double angle1 = 0.0;
    double angle3 = 0.0;
    for (int i=0; i<[array count]; i++) {
        if (i > 0) {
            point1 = [array[i-1] CGPointValue];
            point2 = [array[i] CGPointValue];
            
            angle1 = atan2(point2.y-point1.y, point2.x-point1.x)*180/M_PI;
            if (angle1 < -180) {
                angle1 += 360;
            }
            if (i > 1) {
                point0 = [array[i-2] CGPointValue];
                angle0 = atan2(point1.y-point0.y, point1.x-point0.x)*180/M_PI;
                if ((fabs(angle1-angle0)>180 && 360-fabs(angle1-angle0)>36) || fabs(angle1 - angle0) > 36) {
                    tag += 1;
                } else if(i > 2) {
                    point = [array[i-3] CGPointValue];
                    angle3 = atan2(point0.y-point.y, point0.x-point.x)*180/M_PI;
                    if (fabs(angle3-angle1)>36 || (fabs(angle3-angle1)>180 && 360-fabs(angle3-angle1)>36)) {
                        tag += 1;
                    }
                }
            }
        }
        [self.angleArray addObject:[NSNumber numberWithDouble:angle1]];
        [self.angleTagArray addObject:[NSNumber numberWithInt:tag]];
    }
}

2.录入模板

手工录入汉字模板,每录入一个字,按笔画进行比对,查找出相匹配的笔画,将笔画id存入该汉字记录,最后每个汉字就对应多个笔画了。


// 录入汉字模板

- (void)insertStandardStroke2:(CharacterModel *)model {
    
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];// 记录重复的笔画的个数
    NSUserDefaults *userdefaults = [NSUserDefaults standardUserDefaults];
    NSNumber *widthNumber = [userdefaults objectForKey:wtDefaultsCanvasViewWidth];
    NSNumber *heightNumber = [userdefaults objectForKey:wtDefaultsCanvasViewHeight];
    float canvasViewWidth = widthNumber.floatValue;
    float canvasViewHeight = heightNumber.floatValue;
    
    /****************插入字**************/
    [self.hanziDb executeUpdate:@"insert into s_character(chinese, pinyin) values(?,?)", model.chinese, model.pinyin];
    
    /****************获取字的id**************/
    FMResultSet* set0 = [self.hanziDb executeQuery:@"select max(id) as maxCharId from s_character"];
    int charid = -1;
    if([set0 next]) {
        charid = [set0 intForColumn:@"maxCharId"];
    } else {
        return;
    }
    
    NSArray *strokeModelArray = model.strokeModelArray;
    for (int strokeIndex=0; strokeIndex<strokeModelArray.count; strokeIndex++) {
        StrokeModel *strokeModel = strokeModelArray[strokeIndex];
        [self clearUserTable];
        
        /****************插入笔画**************/
        CGPoint minPoint = [model.minPointValue CGPointValue];
        CGPoint maxPoint = [model.maxPointValue CGPointValue];
        [self.hanziDb executeUpdate:@"insert into u_stroke(minX, minY, maxX, maxY) values(?,?,?,?)", minPoint.x, minPoint.y, maxPoint.x,maxPoint.y];
        
        /****************获取笔画的id**************/
        NSString *queryStrokeid = [NSString stringWithFormat:@"select max(id) maxid from u_stroke"];
        FMResultSet* setStrokeid = [self.hanziDb executeQuery:queryStrokeid];
        int strokeid = -1;
        if([setStrokeid next]) {
            strokeid = [setStrokeid intForColumn:@"maxid"];
        } else {
            return;
        }
        
        /****************插入点和角度**************/
        NSArray *pointsArray1 = strokeModel.gridArray;
        NSArray *angleArray1 = strokeModel.angleArray;
        NSArray *angleTagArray1 = strokeModel.angleTagArray;
        
        for (int i=0; i<pointsArray1.count; i++) {
            NSValue *pointValue = pointsArray1[i];
            NSNumber *angleTagNumber = angleTagArray1[i];
            CGFloat angle = [angleArray1[i] floatValue];
            CGPoint point = [pointValue CGPointValue];
            
            NSString *ss = [NSString stringWithFormat:@"insert into u_angle(strokeid, pointX, pointY, angle, angleTag) values(%d,%.2f,%.2f,%.2f,%d)", strokeid,point.x,point.y,angle, angleTagNumber.intValue];
            [self.hanziDb executeUpdate:ss];
        }
        
        // 提炼 把每个笔画分解成线段
        [self.hanziDb executeUpdate:@"insert into u_line (strokeid, pointcount, angle, angletag) select strokeid, count(*), sum(angle)/count(*),angletag from u_angle group by strokeid, angleTag"];
<span style="white-space:pre">	</span>// ......
}

3.判断用户输入

判断用户输入的时候只需要对比对应汉字模板的笔画id就可以了,具体代码就不再奉上(⊙﹏⊙b实在不敢公开)


结局

等待了一周多,写霸上线,结果刚上线,就被朋友们玩儿坏了……

有这样的:



竟然还有这样的





不多说了,回去接着改算法

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
苹果iOS是由苹果公司开发的手持设备操作系统。苹果公司最早于2007年1月9日的Macworld大会上公布这个系统,最初是设计给iPhone使用的,后来陆续套用到iPod touch、iPad以及Apple TV等苹果产品上。iOS与苹果的Mac OS X操作系统一样,它也是以Darwin为基础的,因此同样属于类Unix的商业操作系统。原本这个系统名为iPhone OS,直到2010年6月7日WWDC大会上宣布改名为iOS。截止至2011年11月,根据Canalys的数据显示,iOS已经占据了全球智能手机系统市场份额的30%,在美国的市场占有率为43%。 源码列表: 按钮类 按钮 Drop Down Control 按钮-Circular Music Player Control 》》Flat Pill Button 按钮类--Fancy Menu 按钮之Custom Gradient Button 按钮之Flat Button 按钮之NIDropDown 按钮之Popup Menu 按钮之UIMenuItem with Image 标签类 标签之Emoji Label 标签之Justifier Label 标签之Top Aligning Label 标签之单一label多颜色多字体 弹出视图 弹出视图 View Bounce Animation 弹出视图(Popup View)UIPopoverListView 弹出视图(Popup View)之URBAlertView 弹出视图(Popup View)之自定义菜单UIMenuBar 弹出视图-Patterned Alert View 弹出视图-Table Alert 弹出视图类--Blur ModalView 弹出视图类--Depth View 弹出视图类--FWTPopover 弹出视图类--icon sheet 弹出视图类--Informatic Toolbar 弹出视图类--WCAlertView 弹出视图之Depth Modal 弹出视图之SelectViewController 导航条 导航条(Navigation Bar)Navigation Menu 导航条(Navigation Bar)之Menu on NavigationBar 导航条类--iOS更换皮肤 导航条之Breadcrumb View 导航条之NavBarNotificationView 导航条之NavigationController Transition 导航条之Title Swipe View 导航条之Title View on NavigationBar 地图类--自定义地图标注 地图(Map)之SJOPaperboy 地图类--Custom Annotation 地图类--DirectionsKit 地图类--Location Indicator 地图类--简单的地图路径 地图类--自定义地图标注 动画类 动画--Spring LoadedView 动画-UIKitForGame 动画类--Guide Arrow 动画之Animation Sequence 动画之Genie Effect 动画之Steam View 分段选择类 分段选择(Segment)之URBSegmentedControl 分段选择类--SVSegmentedControl 扩展 分段选择之AKSegmentedControl 分段选择之Color Bar Segments 滚动视图 滚动的标签 滚动视图(ScrollView)Scroll Grid Controller 滚动视图--Infinite GridView 滚动视图类--CoverFlow 滚动视图类-Lazy ScrollView 滚动视图类--Parallax ScrollView 滚动视图类--Parallax View 滚动视图类-简单的广告栏 滚动视图类--拖动UIScrollView放大图片 滚动视图之Extended UIScrollView 滚动视图之MCPagerView 滚动视图之Page Scrubber Bar 滚动视图之Parallel View 滚动视图之SBFlowView 滚动视图之Wheel Component 汉字转换为拼音 滑竿类 滑杆(Slider)Circular Slider View 滑杆(Slider)之Range Selector 滑杆(Slider)之Volume Bar 滑杆类-Vertical Slider View 滑杆之Slider popover 滑杆之Trim Control 绘图类--My Palette 绘图类--超级简单的画正方形的方法 绘图之Drawing View 基于FMDB的数据库操作 简单阅读器 键盘类 键盘(Keyboard)之自定义表情键盘 键盘-FaceBoard 键盘-Keyboard Bar TextField 键盘类》》Number PadView 键盘类》》ZenKeyboard 键盘类--自定义的拨号键盘 键盘之Custom iOS Keyboard 进图条类 进度条(Progress)Circular Progress View 进度条(Progress)之Progress Toolbar 进度条-Colorful ProgressView 进度条类--Range Slider With Progress 进度条之circular timer 进度条之MCProgressView 开关类 开关(Switch)之RESwitch 开关-Simple Switch Demo 开关之Toggle View 开关之TTSwitch 列表类 联系人搜索算法 列表 纵向Table里嵌套横向Table 列表(Table)Cell Flip Segue 列表(Table)之DynamicHeights 列表(Table)之Expansion Table 列表(Table)之Horizontal table 列表(Table)之Pull Up To Refresh 列表(Table)之TableView with SearchBar 列表(Table)之UITable嵌套UITable 列表(Table)之UploadProgressView 列表-Rainbow Styled Pull To Refresh 列表-UITableView背景随动 列表类》》自定义Table View折叠效果 列表类-FormInputAccessoryView 列表类-Grid TableView 列表类-Grouped TableView With Shadows 列表类--iOS 6.0 Pull to Refresh 列表类--Section Selection View 列表类--Styled TableViewCell 列表类--TableView的各种操作 列表类--UIListView 列表类--下拉刷新加载SQLite数据 列表-让TableView的子view保持固定 列表之ExpansionTableView 列表之iOS Tree Component 列表之Refresh Control 列表之首列固定的列表 日历类 日历(Calendar)之Calendar Picker 日历(Calendar)之TimesSquare 日历之CalendarView 日历控件 日历之封装的My97DatePicker日历 社交类 社交分享-SinaWeibo Share 社交分享类》》ios6 Share Demo 社交分享类--Social Share TableViewCell 社交分享之KRShare 社交分享之MessageActivities 社交分享之ShareSDK 视图布局类 视图布局(View Layout)Border View 视图布局(View Layout)之Linear Layout View 视图布局(View Layout)之Quilt Layout 视图布局(View Layout)之模仿ness伸缩效果 视图布局-Animated Grid 视图布局-Note ViewController 视图布局-Side bar demo 视图布局-Sliding Grid View 视图布局类》》Circle Layout 视图布局类-HGPhoto Wall 视图布局类--Scaling For iPad mini 视图布局类--Swipe ViewController 视图布局之Cycled Viewer 视图布局之Dragging Buttons 视图布局之Mosaic UI 视图布局之Rounded View 视图手势切换 视图切换(View Transition)GuideViewController 视图切换类-3D浏览器 视图切换类--zaker应用进入画面效果 视图切换之视图切换大小渐变效果 手势交互--物体根据重力感应运动 手势交互之Drag View 手势交互之Touch Visualizer 图表类 图表--百分比圆环 图表类--Percentage Chart 图表类--极简个税计算器 图表之Rotation Pie Chart 图表之实时更新的曲线图 图像类 图像(Image)Transition ImageView 图像(Image)之Colorized Progress View 图像-AsyncImageView 图像-Blurred Image 图像-iOS Image Editor 图像-NLImageCropper 图像-Scratch View 图像类 -Photo Zoom 图像类》》360 Degree Panorama 图像类--Before After 图像类--Crop Image 图像类--Image Category 图像类--Image Select and Crop 图像类--OLImageView 图像类View With Bordered Image 图像类--图片下载和保存 图像之AmazeKit 图像之Croppable View 图像之ImagePickerController of InstaPDF 图像之ImageView With Preview 图像之Media Focus Manager 图像之Multiple Image Picker 网络类 网络类--Downloader Management 网络类--photo批量上传ftp 网络类--Reachability 网络之Multi Downloader 文字视图类 文字视图(Text)之AutoComplete TextField 文字视图(Text)之Bar Track ball Item 文字视图(Text)之Messages TableViewController 文字视图(Text)之TextView Placeholder 文字视图-HashTag Mention Controller 文字视图-Tweet Label 文字视图类--Digit Input 文字视图类--emoji-converter 文字视图类--Placeholder TextView 文字视图类--Swipe Shift Caret 文字视图之Autocomplete UITextField 文字视图之Clickable Label 文字视图之Hyperlink Label 文字视图之Note View 文字视图之Rich Content Label 相机类 相机-iOSMp4Camera 相机类>>Camera多张拍摄Demo 相机类--flash light 相机之实用手电筒 选项卡类 选项卡之AKTabBarController 选项卡之Arc Tab 选项卡之LSTabs 选择器类 选择器类--PickerView with Search Bar 选择器类--Value Selector 选择器类--Wheel Menu 选择器类--老虎机 选择器之定制多选的PickerView 音频声效类 音频声效 VoiceTTS Demo 音频声效(Audio)之语音识别 音频声效-iOS Mp3 Recorder 音频声效--VoiceTTS Demo 音频声效类--AAC Audio Converter 音频声效类--BobMusic播放器 音频声效类--Groover 音频声效之Hysteria Player 音频声效之Sound Board 游戏引擎类 游戏引擎(cocos2d)Castle Hassle 游戏引擎类》》模仿合金弹头Demo 游戏引擎类--tank大战 游戏引擎类--Tiny Seal 游戏引擎类--基于cocos2d的连连看游戏 游戏引擎类--简单炸弹人小游戏源码 游戏引擎类--切水果游戏 游戏引擎类幸运大转盘的抽奖游戏 游戏引擎-推箱子游戏 游戏引擎之雷电游戏的激光子弹 指示器类 指示器(HUD)之Android Style Toast 指示器-Activity Bar 指示器--Notify HUD 指示器之MBAlertView 指示器之YLActivityIndicatorView 其他类 财付通打印票据和拖动银行卡效果 寸光阴课程表 功能齐全的计算器 每日金句 扫雷游戏 数字输入 天气预报 之DDClock 之滚动视图旋转菜单 状态栏-StatusBar Notifier View 状态栏之MPNotificationView Ad Controller AdMob demo Animation之Gmail Like Loading AWVersionAgent Bee Framework Circle Menu Cocoa Touch Barcodes Contact Picker FileMD5Hash Fontastic Icons fontawesome Harpy iHasApp In-App Feedback In-App Purchase Inner Shadow Layer Keyboard之DLIDEKeyboard Leak Hunter Message Template NSLogger NSUndoManager Demo Open InApp Activity Passcode Passcode Lock Rating Control SBook ScaffoldKit for Core Data Shine Effect SKYdata Sliding Puzzle Board Spotlight System File Browser Ternary Search Tree UIBezierPath Symbol UITextField 焦点提示 Webview之UIWebView 离线浏览

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值