delphi手写字符识别

合集下载

delphi 字符串类型浅析[新版]

delphi 字符串类型浅析[新版]

delphi 字符串类型浅析[新版] Delphi 字符串类型浅析收藏参考资料《Delphi 5开发人员指南》“第2章Object Pascal语言” 《PASCAL精要》“第7章字符串操作”“Delphi中String类型和Char类型的比较”“Object Pascal中String类型的内幕探讨”基本知识字符串类型•AnsiString这是Pascal缺省的字符串类型,它由AnsiChar字符组成,其长度没有限制,同时与null结束的字符串相兼容。

•ShortString保留该类型是为了向后兼容Delphi1.0,它的长度限制在255个字符内。

•WideString功能上类似于AnsiString,但它是由WideChar字符(UniCode字符集)组成的。

引入这种类型,主要是为了支持OLE编程。

•PChar指向null结束的Char字符串的指针,类似于C的char*或lpstr类型。

•PAnsiChar指向null结束的AnsiChar字符串的指针。

•PWideChar指向null结束的WideChar字符串的指针。

字符类型•AnsiChar,以 8 位表示 (共有 256 个不同的符号)。

•WideChar,以 16 位表示 (共有 64,000 个不同的符号)。

String类型注意:以下是指Delphi2007以前的编译器(包括Delphi2007)。

1、缺省情况下,如果用如下的代码来定义字符串,编译器认为是AnsiString字符串:varS:string;//编译器认为S的类型是AnsiString2、编译开关$H“$H编译开关”的值用来决定当变量声明为string时,它是被当作AnsiString类型还是被当作ShortString类型。

当“$H”值为负时,string变量是ShortString类型;当“$H”值为正时(缺省情况),string变量是AnsiString 类型。

手写字符识别原理

手写字符识别原理

手写字符识别原理
手写字符识别是指将手写的文字、数字、符号等信息通过计算机自动识别出来的过程。

它是近年来人工智能领域中的一个重要应用,被广泛应用于手写数字识别、手写汉字识别、银行支票识别、邮件地址识别、手写签名识别等领域。

手写字符识别的原理主要是将手写的字符图像通过数字化和特
征提取转化为数值型的表示形式,然后通过机器学习的方法来训练模型,以实现对手写字符的识别。

手写字符识别的流程主要包括以下几步:
1. 图像预处理:将手写字符的图像进行数字化处理,转化为二值图像或灰度图像,并进行多种滤波和预处理操作,以提高图像的质量和准确性。

2. 特征提取:对处理后的手写字符图像进行特征提取,选取一些能够表征字符本质特性的特征,如笔画数目、笔画方向、角度、曲度等,通过这些特征来描述字符的形状和结构。

3. 特征选择:对提取的特征进行筛选和选择,选取对字符识别最为重要和有效的特征。

4. 模型训练:通过机器学习的方法,训练一个分类器模型,以将不同的手写字符进行分类和识别。

5. 模型测试:使用测试集对训练好的模型进行测试和验证,以评估模型的准确率和性能。

在实际应用中,手写字符识别面临的挑战主要包括手写字符的多
样性、复杂性和变异性,以及文化和语言的差异等因素。

因此,如何提高模型的鲁棒性和泛化能力,对于实现高效的手写字符识别具有重要意义。

基于Delphi的驾校考试指纹识别系统设计

基于Delphi的驾校考试指纹识别系统设计

考 试答题系 统答题 ,同时在进行桩 考前考生必 须预 先进行指 纹身份鉴 定才 能进入 考场,否则 考试成绩无效 。 ( 3 ) 使用 帮助 :为使用 者提供 系统 使用帮 助 ,对登记 、指 纹 比对 的具体流程作 了详细介
T e m p l a t e l ( A F P D a t a ) :
面 向对象  ̄D e l p h i 语言 ,系统 的阐述 了驾校考试 指纹识别 系统的开发设计全过程。
【 关键词 】指纹识别 ;身份认 证;De l p h i 语言 .
指 纹 身份 认 证 是利 用人 体 指纹 人 皆 不 同 和永恒 不变的生物 特征进行 身份识别 ,将 克服 传 统方法 带来 的不 足。不 同人 的指纹不 同,同 个人 不同手指 的指纹也不 相同 。且人 的指纹 终生不变 ,另外 ,由于生物特 征是人体 的一部

ቤተ መጻሕፍቲ ባይዱ










鳗 廑 一 J
基  ̄- D e l p h i 的驾校考试指 纹识别 系统设计
武警 工程 大学 刘超群
【 摘要】由 于指纹的唯一性和不变性, 指纹身份认证成为众多身份识别领域里使用最广 泛、应用最便捷的身份识别手段之一。 本文在U . A R E . u 指纹采集仪的基础上, 利用
w i t h A O ue r y d o b e g i n
Cl o s e:
S QL . C l e a r:
S O L . A d d( ’ i n s e r t i n t o z k F i n g e r P r i n t
( I D , T e m p l a t e , N a m e ) v a l u e s ( ’ + i n t t o s t r ( A F i n g e 绍 ,并及时解决使用者提 出的问题。 i D ) , … + t e m p l a t e a s s t r i n g + … , … + E D F i n g ( 4 ) 系统 维护 :此 模块 为管理 员对 系统进 r 行维 护提供入 口,也可通过 网络对系 统终端 出 e r N a m e . T e x t + … ) ’ ) : 现 的 问题 进行 查 询 ,及 时解 决 系统 出现 的故 E x e c S Q L : e n d: 障。 2 . 工作 流程 E n d; 指纹仪初始化进入工作状态后,调用B e g i n 省 了很多成本 。到2 0 0 4 年 ,随着 移动存储 设备 说明: 由于S D K 中指纹模板是 以V a r i a n t 变 等数 码类产 品的大量使 用,指纹技 术与数码类 E n r o l 1 处于 登记指纹状态 ,调用B e g i n C a p t u r e 量 的方式保存和传递 ,其存储 的是一维二进制 产 品结合应用 的局面才 铺开 ,现 在 ,指纹 识别 处于指纹 验证状态 。控件 的工作方式 是基 于事 字节数组 ,不能像字符串一样直接 用S Q L 语句 写 技术 已经广泛 用于 民用 产业 ,在很 多信息 安全 件驱动,触发事件的顺序参考下面 。 入和读 出,所 以此处先利用E n c o d e T e m p l a t e 将 领域 ,甚至金 融领域都 出现 了指纹 技术应用方 指纹 登记 一般 需要按 同一手 指卜4 次 ,然 指纹模板 转化成长字 符串型 ,以便 于将 指纹信 案。 后 由识 别 系统 综合 处 理 得 到一 个指 纹 登记 模 息写入到数据库 中。 如今 ,驾校 考试报名与 管理 系统也开始广 板,按压登记指纹次数 由控件属性E n r o l 1 C o u n t 3 . 2指纹验证部分源代码 n E n r o l 1 和 P r 0 c e d t l r e T F 0 r m1 . G e t F P D a t a( A Q u 泛应 用指纹识 别技术 ,通 过对考生报 名时登记 设置 ,达 到 设 定次 数 后 会 触 发 O e r Y: T A D O Q u e r y: A F i n g e r I D: I n t e g e r: v a r 和采 集考生 的指纹信 息和照片信 息,在进行桩 O n E n r o l l T o F i l e 事件 。 F P D a t a : O l e V a r i a n t ) : 考前 进行指纹 身份鉴定 以保证其指 纹身份 的真 指纹验证时,按压 手指后会触发O n C a p t u r e A V a r 实性 ,杜绝 冒名考 试、舞弊现 象的发生。 和O n Ca pt u r e T o Fi 1 e事件 ,此 时 可 以 调 用 T m pl a a t e a s s t r i ng: w i d e s t r i n g; 1 . 系统 总体 设计 V e r F i n g e r 或者 I d e n t i f i c a i i o n l n F P C a c h e D B 进行 S c o r e , P ro c e s s N u m ,I D , i 1 , i 2 , i 3 , i 4: I n t e g 本文 系统采用面 向对象的编程工具B o r l a n d 比对 。 D e l p h i 2 0 1 0 语言和B i o k e y S D K 3 . 8 开发包进 需要 注 意每 次按 压手 指都 会 触发 O n F e a - e r: u r e l n f o 事件 ,如果按压手指 的指纹模板质 量 B e g i n 行开 发,D e l p h i 语言 以其基 于窗 口和 面向对象 t

Delphi中常用字符串处理函数

Delphi中常用字符串处理函数

Delphi中常⽤字符串处理函数1.copy(str,pos,num) 从str字符串的pos处开始,截取num个字符的串返回.假设str为'abcdef',copy(str,3,2)='cd',copy(str,4,10)='def'2.concat(str1,str2{,strn}) 把各⾃变量连接起来,返回连接后的字符串(长度不能超过255)3.length(str) 返回str的字符个数,即其长度.4.pos(obj,target) 在target字符串中找出第⼀个出现obj的第⼀个字符位置,如果找不到,返回0.5.AnsiStrLastChar('你好')结果是“好”。

如果有半个汉字出现,返回这半个汉字。

⼆者字符串长度分别为2和1。

pareStr - 区分⼤⼩写pareText - 不区分⼤⼩写8.StringReplace(const S, OldPattern, NewPattern: string;Flags: TReplaceFlags): string;字符串替换函数,需要引⽤SysUtils单元rfReplaceAll:全部替换rfIgnoreCase:忽略⼤⼩写使⽤⽅法Lg: str:='01231142211:655767';//需要把:替换成----s:=StringReplace(str,':','----',[rfReplaceAll]);For Example:varaStr: String;beginaStr := 'This is a book, not a pen!';ShowMessage(StringReplace (aStr, 'a', 'two', [])); //This is two book, not a pen!只替换了第⼀个符合的字ShowMessage(StringReplace (aStr, 'a', 'two', [rfReplaceAll]));//This is two book, not two pen!替换了所有符合的字aStr := 'This is a book, not A pen!';ShowMessage(StringReplace (aStr, 'a', 'two', [rfReplaceAll])); //This is two book, not A pen!只替换了符合的字(⼩写a)ShowMessage(StringReplace (aStr, 'a', 'two', [rfReplaceAll, rfIgnoreCase])); //This is two book, not two pen!不管⼤⼩写替换了所有符合的字end;9.delete是删除⼀个字符串中的某部分字符⽤法是delete(str,//被删除的字符串index,//从第⼏个字符开始删除count //删除⼏个);Delete(S, 2, 2); 就是从S中的第⼆个开始删除,删除2个字符即2、3.所以结果是145.////////////////////////////////////////////////////////LEFTSTR, MIDSTR, RIGHTSTR的介绍这⼏个函数都包含在StrUtils中,所以需要uses StrUtils;假设字符串是 Dstr := ’Delphi is the BEST’, 那么LeftStr(Dstr, 5) := ’Delph’MidStr(Dstr, 6, 7) := ’i is th’RightStr(Dstr, 6) := ’e BEST’8.{判断字符是否是数字}function IsDigit(ch: char): boolean;beginResult := ch in ['0'..'9'];end;9、{判断字符是否是⼤写字符}function IsUpper(ch: char): boolean;beginResult := ch in ['A'..'Z'];end;10、{判断字符是否是⼩写字符}function IsLower(ch: char): boolean;beginResult := ch in ['a'..'z'];end;11、{转换为⼤写字符}function ToUpper(ch: char): char;beginResult := chr(ord(ch) and $DF);end;12、{转换为⼩写字符}function ToLower(ch: char): char;beginResult := chr(ord(ch) or $20);end;{ Capitalizes first letter of every word in s }function Proper(const s: string): string;vari: Integer;CapitalizeNextLetter: Boolean;beginResult := LowerCase(s);CapitalizeNextLetter := True;for i := 1to Length(Result) dobeginif CapitalizeNextLetter and IsLower(Result[i]) thenResult[i] := ToUpper(Result[i]);CapitalizeNextLetter := Result[i] = '';end;end;////////////////////////////////////////////////////////////13.{返回两个⼦字符串之间字符的个数}Function p2pcount( s, ss1, ss2 : string ): integer;var i, j, slen : integer;begini := pos( ss1, s );j := pos( ss2, s );slen := Length(ss2);if j >= i then Result := j - i + slen else Result := 0;end;14.{更快速的字符查询,快40%}function ScanStr(ToScan: PChar; Sign: Char):PChar;beginResult:= nil;if ToScan <> nil thenwhile (ToScan^ <> #0) do beginif ToScan^ = Sign then beginResult:= ToScan;break;end;inc(ToScan);end;end;/////////////////////////////15.替换字符串中⼦串的函数,他可以从字符串中找出指定⼦串,并替换为另⼀⼦串。

手写字符识别原理

手写字符识别原理

手写字符识别原理
手写字符识别是指通过图像处理技术,将手写的字符转化为计算机可以识别的数字或文字形式的技术。

手写字符识别的原理主要包括图像处理、特征提取和分类器设计等几个方面。

在图像处理方面,首先需要对手写的字符图像进行预处理,包括二值化、去噪、尺寸归一化等操作。

然后将处理后的图像分成若干个小块,并提取出每个小块的特征,比如颜色、纹理、形状等。

接着,通过数据的归一化和降维,将特征向量转化为计算机可以处理的数字形式。

在特征提取方面,有很多种基于统计学、机器学习或深度学习的算法,比如主成分分析(PCA)、线性判别分析(LDA)、支持向量机(SVM)、卷积神经网络(CNN)等。

这些算法可以根据不同的任务和数据特点选择和调整。

最后,根据特征向量和标签信息,设计合适的分类器,比如k-最近邻、决策树、朴素贝叶斯、神经网络等。

分类器可以通过训练和测试来不断优化,并可以根据应用场景选择不同的性能指标和优化策略,比如准确率、召回率、F1值等。

总的来说,手写字符识别的原理涉及到图像处理、特征提取和分类器设计几个方面,需要综合运用多种技术和算法,并通过不断的优化来实现更高的性能和精度。

- 1 -。

电子手写签名接口的研究与实现

电子手写签名接口的研究与实现

在 Delphi 的 Code Explorer 窗口中,用户可以方便地浏览 AutoCAD 的 ActiveX 对象及 这些对象的属性和方法,并可以了解调用这些属性和方法时可用的参数及形式。

在开发程序时还可以引用该单元文件,从而 可 以使用 库中 声明 的变 量类型 和常 量定 义。

在编写程序时可以利用 Delphi 的自 动完成功能减少错误,编译程序时函数、 方法和属性可以得到自动检查。

(1)对 AutoCAD 的 Activex Au tomation 初 始化。

在 Delphi 环境下进行 AutoCAD 的 Ac- tivex Au tomation 设计需要进行 3 方面的初始 化:uses 语句引用 Comobj 单元,它是 Delphi 应用程序中处理 Activex Au tomation 的关键 代码;获取AutoCAD 的 Application 和 document 对象,用来管理 Au toC AD 应用程序和操纵 当前活动图形文件。

下列代码可进行必要的初始化工作:uses ComObj;// 引用 ComObj 单元var Acad,AcadDwg:OleV ariant; // 定义 Application 和 docu ment 对象变量 Acad:=GetActiveOleObject ('AutoCAD. Application');// 获取 Application 对象AcadDwg:=Acad.ActiveDocument; //获取AutoCAD 当前活动文档Document 对象(2)获取和设置 AutoCAD 系统变量。

当需要获取并修改 AutoCAD 的系统变量时,可使用 Document 对象的以下 2 个方法:RetV al:=ObjDocument. GetV ariable (Sy s- Name:String ); // 返回系统变量 sysname 的当前值 ObjDo cument. Set V ariable (SysName: string,SysV alue );// 设置系统变量 SysName 的当前值为 新值 SysV alue使用这两个方法时需注意GetVariable 函数返回值和 SetV ariable 函数中参数 sys- V alue 的类型随着系统变量的不同而变化, 例如多点线线宽返回实数、当前颜色返回 整数等。

delphi新特性

delphi新特性
type TMyClass = class procedure MyProc;
function MyFunc: Integer; end; end …… procedure TMyClass.MyProc; var X: Integer; begin X := MyFunc; end; end function TMyClass.MyFunc: Integer; begin …… end; end …… type TMyClassHelper = class helper for TMyClass procedure HelloWorld; function MyFunc: Integer; end; end …… procedure TMyClassHelper.HelloWorld; begin writeln(Self.ClassName); // Self 是 TMyClass 类, 不是 TMyClassHelper writeln end; end function TMyClassHelper.MyFunc: Integer; begin …… end end; …… var X: TMyClass; begin X := TMyClass.Create; X.MyProc; // 调用 TMyClass.MyProc X.HelloWorld; // 调用 TMyClassHelper.HelloWorld
Delphi2010 新发现-类的构造和析构函数功能 新发现 类的构造和析构函数功能
Delphi2010 发布了. 虽然凭着对 Delphi 的热爱第一时间就安装了,但是现在可能是年纪大了,对新事物缺乏兴趣了. 一直都没有仔细研究. 今天有点时间试了一下新功能. 本来 C#和 是支持类的构造函数/析构函数的(注意不是实例的构造和析构).也就 是在模块初始化/卸载的时候会调用. 这样有很多好处,比如说类的静态变量的初始化什么的都可以在这里做. Delphi For Win32 对这方面的需求还不是很大. 第一个原因.历史上旧版 Delphi 不支持静态变量.只能用 Unit 的全局变量+类函数来模拟.所以 类的构造析构基本没需求.从 Delphhi2005 还是 2006 开始才支持 Class var 的.记得不太清楚了 第二个原因.Delphi 的 Unit 有初始化节和反初始化节(initialization/finalization).很多初始化工 作都可以在这里面做.比如说类的静态变量.所以对类的构造函数需求不是很大. 随手试了一下 Delphi2010.惊喜的发现不知道什么时候 Delphi2010 已经开始支持类的构造和 析构函数了.易博龙和 CodeGear 居然在介绍 Delphi2010 的新变化的同时都没有介绍这个特 征. 贴一段代码: type TTest = class private class var StaticABC : Integer; //类变量(类似 C++的静态变量.但不完全等同) var FABC : Integer; //普通成员变量 public class constructor Create();//类的构造函数 class destructor Destroy; //类的析构函数 constructor Create(); //实例的构造函数 destructor Destroy; override; //实例的析构函数 end; { TTest } class constructor TTest.Create; begin StaticABC := 1234; end; class destructor TTest.Destroy; begin end;

DELPHI最精简的小写金额转大写的函数

DELPHI最精简的小写金额转大写的函数

最精简的小写金额转大写的函数function NumToChar(const n: Real): string; //可以到万亿,并且可以随便扩大范围const cNum: WideString = '零壹贰叁肆伍陆柒捌玖--万仟佰拾亿仟佰拾万仟佰拾元角分';cCha:array[0..1, 0..12]of string =(( '零元','零拾','零佰','零仟','零万','零亿','亿万','零零零','零零','零万','零亿','亿万','零元'), ( '元','零','零','零','万','亿','亿','零','零','万','亿','亿','元'));var i : Integer;sNum,sTemp : WideString;beginresult :='';sNum := format('%15d',[round(n * 100)]);for i := 0 to 14 dobeginstemp := copy(snum,i+1,1);if stemp=' ' then continueelse result := result + cNum[strtoint(stemp)+1] + cNum[i+13];end;for i:= 0 to 12 doResult := StringReplace(Result, cCha[0,i], cCha[1,i], [rfReplaceAll]);if pos('零分',result)=0then Result := StringReplace(Result, '零角', '零', [rfReplaceAll])else Result := StringReplace(Result, '零角','整', [rfReplaceAll]);Result := StringReplace(Result, '零分','', [rfReplaceAll]);end;function Changdx2(mmje: Double): String;const s1: String = '零壹贰叁肆伍陆柒捌玖';s2: String = '分角元拾佰仟万拾佰仟亿拾佰仟万';function StrTran(const S, S1, S2: String): String;beginResult := StringReplace(S, S1, S2, [rfReplaceAll]);end;var s, dx: String;i, Len: Integer;beginif mmje < 0 thenbegin dx := '负';mmje := -mmje;end;s := Format('%.0f', [mmje*100]);Len := Length(s);for i := 1 to Len dodx := dx + Copy(s1, (Ord(s[i]) - Ord('0'))*2 + 1, 2) + Copy(s2, (Len - i)*2 + 1, 2);dx := StrTran(StrTran(StrTran(StrTran(StrTran(dx, '零仟', '零'), '零佰', '零'), '零拾', '零'), '零角', '零'), '零分', '整');dx := StrTran(StrTran(StrTran(StrTran(StrTran(dx, '零零', '零'), '零零', '零'), '零亿', '亿'), '零万', '万'), '零元', '元');if dx = '整' then Result := '零元整'else Result := StrTran(StrTran(dx, '亿万', '亿零'), '零整', '整');end;。

delphi实现数字签名

delphi实现数字签名

delphi实现数字签名ryptToAPI——除非特殊安全需要,只公布使用自己的接口,不支持微软接口。

由于使用CryptT oAPI,使用起来较繁琐,微软提供了CAPICOM组件,方便开发。

不论是硬证书或软证书,只要支持CryptToAPI接口,那么CAPICOM均可使用。

为此本次内容以CAPICOM,作为数字签名功能的基础。

有关数字签名的概念、原理,这里就不做介绍了,请自行google或百度。

利用证书对文件进行签名,从证书来源看,可分为两种:1、软证书:就是将*.pfx文件导入到系统中,这意味着,只要登录到PC中的用户,均可以使用该证书;2、硬证书:通常将证书存放到uKey中(smart card),这样的好处是,只有拥有usb key的人才有权限使用该证书。

USB Key通常支持CryptToAPI——除非特殊安全需要,只公布使用自己的接口,不支持微软接口。

由于使用CryptToAPI,使用起来较繁琐,微软提供了CAPICOM组件,方便开发。

不论是硬证书或软证书,只要支持CryptToAPI接口,那么CAPICOM均可使用。

为此本次内容以CAPICOM,作为数字签名功能的基础。

动手之前,首先要熟悉数字签名的过程。

通过分析,主要是两部分:数字签名(身份标识及防篡改)和数字信封;其实按业务流程,签名之前还有签章的过程(也就是通常的盖章);过程大致如下:发送方1、验证证书是否准备好?(若是硬证书,usbkey是否已插入;判断证书是否有效);2、对文件进行签名;3、对文件进行数字信封(公钥加密);4、可选:填入CSP(加密服务提供商,通常是在USB Key当中)信息接收方:1、获取文件,读取CSP信息;2、依据CSP信息,获取相关证书并验证;3、利用证书进行数字解封;4、签名验证,确认身份及文件的完整性(是否被篡改);依据以上分析,程序可这样设计,由于USB Key可能支持CAPICOM,也可能不支持,所以,后续可能会有相应由多种方法去执行签名。

Delphi对汉字字符串的截取问题

Delphi对汉字字符串的截取问题

Delphi对汉字字符串的截取问题
Delphi 对汉字字符串的截取问题
博客分类:
•Delphi
在Delphi中,用Length来取字符长度时,会将汉字当成两个字节来计算,Copy把汉字当成两个来处理,可能截取半个汉字,那我们如何知道是否取的是汉字呢?是否把一个汉字取完整了呢?
其实,可以用ByteType对取出来的字符进行判断是一个单字符还是汉字的一部分!
mbLeadByte: 汉字的第一个字节
mbTrailByte: 汉字的第二个字节
mbSingleByte: 单个的字符,不是中文字符。

如果Copy出来的是汉字的第一个字节,就再多(或少)Copy一个,凑成完整的汉字。

如下例:
function GetText(strtxt:string;iLen:integer):string;
begin
//先判断要截取的字符串最后一个字节的类型
//如果为汉字的第一个字节则减(加)一位
if ByteType(strtxt,iLen) = mbLeadByte then
iLen := iLen - 1;
result := copy(strtxt,1,iLen) + "...";
end;。

使用delphi获得字符内码

使用delphi获得字符内码

使用delphi获得字符内码使用delphi获得字符内码2011-06-15 17:41那么我就给你介绍一下我总结出来的GB字符识别方法(是的,就是你想要的那种把半角字符、全角符号和汉字区别开来的方法)吧。

在此之前希望你有心里准备,篇幅可能会稍微长一些,因为涉及到的内容比较多。

不论你之前看过什么样的资料,并对此有多大程度的了解,如果你希望能非常专业地解决这个问题(嗯哼,就像Win32 API或VCL做的那样专业),那就要有一定的耐心从最基础的地方看起。

对了,在继续看下去之前,我想你至少应该明白ANSI和双字节字符集的概念,如果不明白,可以先看看这篇文章原文虽没有明确解释ANSI的概念,但在介绍双字节字符集时已多次涉及,这里我总结一下:所谓ANSI就是在Unicode和ISO10646出现以前,各个非英语国家和地区的计算机科技工作者为了将本地语言文字编码进计算机,而对基本ASCII编码所做的各种扩展编码方案的统称,它们多用两个以上的字节编码一个字符(称为多字节字符集MBCS),其中比较典型的就是在东亚广泛被使用的双字节字符集(DBCS)。

这个东西可没你想象的那么简单呢-第一步认识Delphi的ByteType函数(我用的是Delphi7,6用得少,里面应该有这个函数吧)这个函数的作用是检测ANSI字符串中某个字节是属于一个单字节字符(即ASCII字符)还是双字节字符的第一个字节,又或是双字节字符的第二个字节。

声明单元SysUtils VCL例程分类MBCS处理Delphi语法:function ByteType(const S:string;Index:Integer):TMbcsByteType;C++语法:extern PACKAGE TMbcsByteType __fastcall ByteType(const AnsiString S,int Index);说明用ByteType函数可以检测字符串指定字节的类型:单字节字符、多字节字符的引导字节或多字节字符的尾字节中的一个。

delphi 字符串类型浅析[新版]

delphi 字符串类型浅析[新版]

delphi 字符串类型浅析[新版] Delphi 字符串类型浅析收藏参考资料《Delphi 5开发人员指南》“第2章Object Pascal语言” 《PASCAL精要》“第7章字符串操作”“Delphi中String类型和Char类型的比较”“Object Pascal中String类型的内幕探讨”基本知识字符串类型•AnsiString这是Pascal缺省的字符串类型,它由AnsiChar字符组成,其长度没有限制,同时与null结束的字符串相兼容。

•ShortString保留该类型是为了向后兼容Delphi1.0,它的长度限制在255个字符内。

•WideString功能上类似于AnsiString,但它是由WideChar字符(UniCode字符集)组成的。

引入这种类型,主要是为了支持OLE编程。

•PChar指向null结束的Char字符串的指针,类似于C的char*或lpstr类型。

•PAnsiChar指向null结束的AnsiChar字符串的指针。

•PWideChar指向null结束的WideChar字符串的指针。

字符类型•AnsiChar,以 8 位表示 (共有 256 个不同的符号)。

•WideChar,以 16 位表示 (共有 64,000 个不同的符号)。

String类型注意:以下是指Delphi2007以前的编译器(包括Delphi2007)。

1、缺省情况下,如果用如下的代码来定义字符串,编译器认为是AnsiString字符串:varS:string;//编译器认为S的类型是AnsiString2、编译开关$H“$H编译开关”的值用来决定当变量声明为string时,它是被当作AnsiString类型还是被当作ShortString类型。

当“$H”值为负时,string变量是ShortString类型;当“$H”值为正时(缺省情况),string变量是AnsiString 类型。

delphi 字符串的相关判断

delphi 字符串的相关判断

转载他人博客文章,仅供学习之用某一字符是否在字符串中本实例是用AnsiMidstr()函数获取指定字符串中的单个字符,也可以获取指定长度的子字符串。

运行结果如图5.10所示。

图5.10 判断某一字符是否在字符串中主要代码如下:procedure TForm1.Button1Click(Sender: TObject);vari,p:Integer;beginif (Edit1.Text='')or(Edit2.Text='') thenbeginShowMessage('请把信息添全。

');endelsebeginif Length(Edit2.Text)=1 thenbeginp:=Length(Edit1.Text);for i:=1 to p dobeginif Trim(Edit2.Text)=AnsiMidstr(Edit1.Text,i,1) thenbeginLabel4.Caption:='在字符串中';break;endelsebeginLabel4.Caption:='不在字符串中';end;end;endelseShowMessage('字符只能是单个字符。

');end;end;字符串是由数字、大写字母或小写字母组成本实例是用StrToInt()函数来判断字符串是否由数字组成,当字符串不能由StrToInt()函数进行转换时,在异常处理中用Uppercase()和Lowercase()函数来判断字符串是由大写字符串还是小写字符串组成。

运行结果如图5.11所示。

图5.11 判断字符串是由数字、大写字母或小写字母组成主要代码如下:procedure TForm1.Button1Click(Sender: TObject);varIsstr : String;beginIsstr := Edit1.Text;tryStrToInt(Isstr);ShowMessage('由数字组成!');exceptif Isstr=Uppercase(Isstr) thenShowMessage('由大写字母组成!')elseif Isstr=Lowercase(Isstr) thenShowMessage('由小写字母组成!')elseShowMessage('无法识别,可能是混杂型。

Delphi开发技巧:字符串的相关判断[5]

Delphi开发技巧:字符串的相关判断[5]

Delphi开发技巧:字符串的相关判断[5]——此文章摘自《Delphi开发经验技巧宝典》定价¥特价¥购买>>//track linktech cn/?m_id=dangdang&a_id=A &l= &l_type = width= height= border= nosave>字符中是否有双字节中文所用的字符全是双字节字符英文所用的字节全是单字节字符也就是mbSingleByte 本实例是用ByteType()函数返回字符串指定位置上的字符如果不是mbSingleByte 则表示为双字节字符运行结果如图所示//develop csai cn/delphi/images/ jpg >图判断字符中是否有双字节主要代码如下 procedure TForm Button Click(Sender: TObject); var s s : String; i : Integer; begin s := Edit Text; i := ; while i<Length(s) do begin if (ByteType(S i) <> mbSingleByte) then begin s := s + Copy(s i )+ ; i := i+ ; end else i:= i+ ; end; Label Caption := Trim(s ); end;判数输入的字符串是否为整数本实例是用库函数sign()来判断数字是否为整数当传入的值小于则返回&# ; 若传入的值大于则返回否则返回在用sign()函数时要在单元中加入Math单元运行结果如图所示//develop csai cn/delphi/images/ jpg >图判数输入的字符串是否为整数主要代码如下 procedure TForm Button Click(Sender: TObject); var s : String; i : Integer; begin s:=Edit Text; try i:=StrtoInt(s); if sign(i)= then //添加单元Math 或if i> then Label Caption := 是正整数 else begin if i= then Label Caption := 是整数else Label Caption := 非正整数; end; except Label Caption := 输入无效; end; end; lishixinzhi/Article/program/Delphi/201311/8466。

使用DELPHI对图片中的文字进行识别的过程(最简单实现)

使用DELPHI对图片中的文字进行识别的过程(最简单实现)

使用DELPHI对图片中的文字进行识别的过程(最简单实现)unit bmp2number;{将传递进来的图像进行对比,识别出图片中的数字。

本程序使用的是模式识别的方式,需要照片标准,数字无反光。

电表只有4位数字+1位小数,小数因为在拍照中不能保证停止,所以本程序也不作小数位的识别因此。

如果当前的数字已经识别到了4位,程序就返回,我们预设一个记录,用来记录这被识别的出4位数字的具体位置,再通过对TOP及LEFT位置的进行排序组合后返回对于本模板的重要方法说明:Function GetNumber:string功能:返回识别出的数字字符串按照对TBmp2Number对象的下列属性:SoruceBitmap:需要被识别的图像Temp_Index:模板编号Temp_path:模板文件目录discern_rate:识别率}interfaceuses windows,math,classes,controls,graphics,jpeg,sysutils,di alogs,extctrls,forms,stdctrls,ComCtrls;TypepRGBTripleArray = ^TRGBTripleArray;TRGBTripleArray = array [0 .. 65535] of TRGBTriple;Ptemplate=^Ttemplate; //被识别的数字当用记录保存起来Ttemplate=recordnumber:integer;top:Integer;Left:Integer;end;TBmp2Number=class(Tobject)privateFSourceBitMap:Tbitmap;FTempl_index:integer;Ftempl_Path:String;Fdiscern_rate:Double;FNumber:string;FNumberList:TList;tmeplate:Ptemplate;fStop:Boolean;FShowDemo:Boolean;protectedprocedure SetTempl_index(value:Integer); procedure SetTempl_path(Value:String); procedure InitTemplate;Function GetNumber:String;publicmemo1:TRichedit;image1,image2:Timage;pb_Count,pb_deta:TProgressbar; constructor Create;publishedproperty SourceBitMap:Tbitmap read FSourceBitMap write FSourceBitmap;property Templ_index:integer read Ftempl_index write SetTe mpl_index;Property Templ_Path:String read Ftempl_Path write SetTemp l_path;property discern_rate:Double read Fdiscern_rate write Fdisc ern_rate ;property Number:String read GetNumber;property Stop:Boolean read Fstop write FStop;property ShowDemo:Boolean read FShowDemo write FSho wDemo;end;//SourceBitmap:电表图片,template_index:调用的模板号 template_path;模板存放的目录Function Pic2Bmp(PicFileName:String):TBitmap;implementation//将图片转换成BMP格式,以便比较,主要是因为数码相机采集的图片基本上是JPEG 格式的。

Delphi中建立指定大小字体和读取该字体点阵信息的函数

Delphi中建立指定大小字体和读取该字体点阵信息的函数

Delphi中建立指定大小字体和读取该字体点阵信息的函数由于要控制硬件,需要把矢量的汉字转化为点阵信息写入eprom或在液晶屏上显示,因此用Delphi写了如下的函数,可以把指定的一个汉字(两个字符)转化为点阵信息保存到文件,每个点对应一个位,有文字信息该位为1,否则为0。

目前该函数可以生成指定的大小汉字并读取成点阵字模信息保存到文件。

如ConvertToMatrix(Pchar('北'),6,18,'Font.dat')将生成12*18点阵文件 Font.dat,其中保存汉字‘北’的字模。

文件格式是从上到下,先行后列,如下图,第一行保存00 00,第二行是90 00 (均是16进制,余下个行类推)//转化一个汉字为点阵信息Text为一个汉字,ChrWidth是字符宽,汉字是两个字符大小,所有如果要生成宽是12的汉字则ChrWidth为6,ChrWidth目前最多是8,因为大多数的硬件使用的点阵信息是16以下ChrHeight是汉字的高,SaveFileName是保存该汉字点阵信息的文件名。

function ConvertToMatrix(Text:PChar;ChrWidth,ChrHeight:Byte; SaveFileName:Pchar):Bool;typePBITMAPINFO=^TBitmapInfo;varTempBmp:TBitmap;lpvSBits,lpvDBits:Pchar;dOffset,sOffset:integer;DC:HDC;TheFont: HFont;BMIInfo:PBITMAPINFO;DS: TDIBSection;BMIbuf:array[0..2047]of byte;i,j:integer;//循环控制wData:WORD;//保存字体每行的点阵信息,最多16位,不足16位忽略多余的高位MemoryStream:TMemoryStream;begin//大于一个字退出if Length(Text)>2 thenbeginShowMessage('请转化一个汉字!');Result:=False;Exit;end;//参数合理否if (ChrWidth=0) or (ChrHeight=0) or (SaveFileName = '') thenbeginShowMessage('参数错误!');Result:=False;Exit;end;//建立流MemoryStream:=TMemoryStream.Create;//建立临时文件TempBmp:=TBitmap.Create;//设定为256色TempBmp.PixelFormat:= pf8bit;//设定图宽度TempBmp.Width:=ChrWidth * Length(Text);//设定图高度TempBmp.Height:= ChrHeight;//得到BMP文件HDCDC:=TempBmp.Canvas.Handle;//建立逻辑字体TheFont := CreateFont(ChrHeight,ChrWidth, 0, 0, 400, 0, 0, 0, GB2312_CHARSET, Out_Default_Precis, Clip_Default_Precis, Default_Quality, Default_Pitch OR FF_SCRIPT, 'script');//指定字体给DCSelectObject(DC,TheFont);//写入指定字符串TextOut(DC,0,0,Pchar(Text),Length(Text));//释放逻辑字体DeleteObject(TheFont);//取得Bmp信息到lpvSBitsBMIInfo:=PBITMAPINFO(@BMIbuf);//分配内存lpvSBits:=AllocMem(TempBmp.Width*TempBmp.Height);lpvDBits:=AllocMem(TempBmp.Width*TempBmp.Height);//建立程序屏幕兼容的DCDC := CreateCompatibleDC(0);//返回指定的BMP信息到DS中保存GetObject(TempBmp.Handle, SizeOf(DS), @DS);//读取头信息BMIInfo.bmiHeader:=ds.dsBmih;//读入DIBGetDIBits(DC, TempBmp.Handle, 0, ds.dsBmih.biHeight,lpvSBits, BMIInfo^ , DIB_RGB_COLORS);//倒置图像for i:=0 to TempBmp.Height-1 dobeginsOffset:=i*TempBmp.Width;dOffset:=(TempBmp.Height-i-1)*TempBmp.Width;CopyMemory(lpvDBits+dOffset,lpvSBits+sOffset,TempBmp.Width); end;//保存文件for i:=0 to TempBmp.Height-1 dobeginwData:=0;for j:=0 to TempBmp.Width-1 dobegin//ShowMessage(inttostr(ord((lpvDBits+i*TempBmp.Width+j)^)));if ord((lpvDBits+i*TempBmp.Width+j)^)=0 thenbeginwData:=(wData shl 1)OR 1;endelsebeginwData:=(wData shl 1)OR 0;end;end;MemoryStream.Write(wData,SizeOf(wData));end;MemoryStream.SaveToFile(SaveFileName);MemoryStream.Free;//TempBmp.SaveToFile('temp.bmp')可删除,存'temp.bmp'文件的目的只是为对比察看TempBmp.SaveToFile('temp.bmp');TempBmp.Free;result:=True;end;附:本文全部为原创内容,如果您使用中对程序做了改动请发给作者一分**************************;引用是请注明作者Thermometer和Email,谢谢。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

varForm1: TForm1;myNet: CNeuronet;maxneur: integer;implementation{$R *.DFM}procedure TForm1.ocrbuttons_freigeben();beginButAnalyse.Enabled:=true;ButSavLet.Enabled:=true;ButAddLet.Enabled:=true;LetNr.Enabled:=true;end;procedure TForm1.ocrbuttons_sperren();beginButAnalyse.Enabled:=false;ButSavLet.Enabled:=false;ButAddLet.Enabled:=false;LetNr.Enabled:=false;end;procedure TForm1.plainbuttons_freigeben();beginImagePat.Enabled:=true;PatNr.Enabled:=true;ButAddPat.Enabled:=true;ButSavPat.Enabled:=true;end;procedure TForm1.plainbuttons_sperren();beginImagePat.Enabled:=false;PatNr.Enabled:=false;ButAddPat.Enabled:=false;ButSavPat.Enabled:=false;end;procedure TForm1.B1ErstellenClick(Sender: TObject);var i,rowanz:integer;beginGrNetSpec.Enabled:=true; GrNetSpec.Visible:=true;GrLern.Enabled:=false;plainbuttons_sperren; ocrbuttons_sperren;GrOCRLearn.Visible:=false; GrOCRLearn.Visible:=false;GrSimpleLearn.Visible:=false; GrSimpleLearn.Visible:=false;GrError.Visible:=false;ButSavNet.Enabled:=false; ButReset.Enabled:=false;ImagePat.clientWidth:=250;GrOCRTest.Visible:=false; Image.Visible:=false;rowanz:=Rows.Value+1;AnzGrid.RowCount:=rowanz;AnzGrid.Cells[1,1]:=floattostr(225); AnzGrid.Cells[0,1]:='Input';AnzGrid.Cells[1,rowanz-1]:=floattostr(26); AnzGrid.Cells[0,rowanz-1]:='Output';for i:=2 to rowanz-2 do beginAnzGrid.Cells[0,i]:=inttostr(i);AnzGrid.Cells[1,i]:=floattostr(1);end;end;procedure TForm1.drawnet();beginImage.Canvas.Pen.color:=clWhite;Image.Canvas.Rectangle(Image.ClientRect);myNet.calc_forward();myNet.zeichne(Image.Canvas); {netz zeichnen}end;procedure TForm1.B2beginClick(Sender: TObject);var i,rowanz,layanz:integer;nanz: array of integer;art: char;beginrowanz:=Rows.Value+1;layanz:=rowanz-1;if (RadioGroup1.ItemIndex=0) then beginart:='P';endelse beginart:='O';AnzGrid.Cells[1,1]:=floattostr(225);AnzGrid.Cells[1,AnzGrid.RowCount-1]:=floattostr(26);end;{anz neuronen pro schicht aus dem grid auslesen }maxneur:=0; { f黵dimension der gewichtsmatrix das maximum merken }SetLength(nanz,layanz);for i:=0 to layanz-1 do beginnanz[i]:=strtoint(AnzGrid.Cells[1,i+1]); {anzahl der neuronen je schicht}if nanz[i]>maxneur then maxneur:=nanz[i];end;inc(maxneur); {wegen dem bias}myNet.Free; {evtl. vorhandenes Netz l鰏chen }myNet:=CNeuronet.Create(layanz,nanz,art); {netz erstellen}myNet.w.Free;myNet.w:=Cwmatrix.Create(nz,maxneur); {gewichtsmatrix erz}ButSavNet.Enabled:=true;ButReset.Enabled:=true;if (art='P') then begin { wenn plain }GrOCRLearn.Visible:=false; GrOCRLearn.Visible:=false;GrSimpleLearn.Visible:=true; GrSimpleLearn.Enabled:=true;clearI(ImagePat);Image.Visible:=true;drawnet();endelse if (art='O') then begin { wenn ocr }GrOCRLearn.Visible:=true; GrOCRLearn.Enabled:=true;GrSimpleLearn.Visible:=false; GrSimpleLearn.Enabled:=false;GrError.Visible:=true;GrOCRTest.Visible:=true; GrOCRTest.Enabled:=true;ClearI(ImOCRTestDraw);ClearI(Imgezoomt);ClearI(ImZNeur);end;GrNetSpec.Visible:=false; GrError.Visible:=true;end;procedure TForm1.ImageMouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);var nr: integer;n: ^CNeuron;beginnr:=0;if ((Y>0) and (Y<20)) then beginnr:= ( (X-10+(myNet.L[0].abst div 2)) div myNet.L[0].abst);end;if ((nr>0 )and (nr<myNet.L[0].Nanz)) then beginn:=@myNet.L[0].N[nr];n.activity:=1.0-n.activity;myNet.calc_forward();myNet.zeichne(Image.Canvas);end; //myNet.zeichne(Image.Canvas);end;procedure TForm1.Akt();beginErrorLabel.Caption:=floattostrf(myNet.qerror,ffFixed,7,7)+ ' finished!';myNet.calc_forward(); myNet.zeichne(Image.Canvas);end;procedure TForm1.vorbereiten();beginmyNet.stop:=false;trymyNet.eta:=strtofloat(etaedit.Text);exceptmyNet.eta:=0.2; etaedit.Text:=floattostr(0.2);end;trymyNet.mom:=strtofloat(momedit.Text);exceptmyNet.mom:=0; momedit.Text:=floattostr(0);end;ErrorLabel.Caption:='calculating...'; ErrorLabel.Update;end;function TForm1.getnoise():double;var noise:double;begintrynoise:=strtofloat(EditNoise.Text);exceptnoise:=0.02;end;if (noise<0) then noise:=0 else if (noise>1.0) then noise:=1.0;EditNoise.text:=floattostr(noise);getnoise:=noise;end;procedure TForm1.Button6Click(Sender: TObject);beginvorbereiten;myNet.lerne_schritte(Application,getsolle(),1,getnoise(),ErrorLabel,ErrorImage);Akt();end;function TForm1.getsolle:double;var solle:double;begintrysolle:=strtofloat(sollerror.Text);exceptsolle:=0.01;end;getsolle:=solle;end;procedure TForm1.Button1Click(Sender: TObject);beginvorbereiten;myNet.lerne_schritte(Application,getsolle(),10,getnoise(),ErrorLabel,ErrorImage);Akt();end;procedure TForm1.Button2Click(Sender: TObject);beginvorbereiten;myNet.lerne_schritte(Application,getsolle(),100,getnoise(),ErrorLabel,ErrorImage);Akt();end;procedure TForm1.Button3Click(Sender: TObject);beginmyNet.lerne_schritte(Application,getsolle(),1000,getnoise(),ErrorLabel,ErrorImage);Akt();end;procedure TForm1.Button4Click(Sender: TObject);beginvorbereiten;myNet.lerne_schritte(Application,getsolle(),10000,getnoise(),ErrorLabel,ErrorImage);Akt();end;procedure TForm1.Button7Click(Sender: TObject);beginvorbereiten;myNet.lerne_schritte(Application,getsolle(),100000,getnoise(),ErrorLabel,ErrorImage);Akt();end;procedure TForm1.ImOCRLernDrawMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);beginzeichne:=true;ax:=x;ay:=y;with ImOCRLernDraw.Canvas.Pen do begincolor:=clRed;width:=6;end;end;procedure TForm1.ImOCRLernDrawMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);beginzeichne:=false;end;procedure TForm1.ImOCRLernDrawMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);beginif zeichne then beginImOCRLernDraw.Canvas.MoveTo(ax,ay);ImOCRLernDraw.Canvas.LineTo(x,y);ax:=x;ay:=y;end;end;procedure TForm1.FormCreate(Sender: TObject);beginzeichne:=false;erkenne:=false;ax:=0; ay:=0;ButClearClick(Sender);ButReset.Caption:='R';end;procedure TForm1.ButClearClick(Sender: TObject);beginClearI(ImOCRLernNeur);ClearI(ImOCRLernDraw);ClearI(ImOCRLernZoom);end;procedure TForm1.ButAnalyseClick(Sender: TObject);var sx,sy,dx,dy,x,y,nr:integer;minx,maxx,miny,maxy,maxh,maxb,maxhb: double;altx,alty,mittel: double;feld: array of double;beginminx:=1000; maxx:=0; miny:=1000; maxy:=0;SetLength(feld,225);{ Grenzen im Paint-Image feststellen }for sx:=0 to 63 do beginfor sy:=0 to 63 do beginif (ImOCRLernDraw.Canvas.Pixels[sx,sy]=clRed) then beginif sx < minx then minx:=sx; if sx > maxx then maxx:=sx;if sy < miny then miny:=sy; if sy > maxy then maxy:=sy;end;end;end;{aspect-ratio beibehalten }maxh:=maxy-miny; maxb:=maxx-minx;if (maxh>maxb) then begin { breite < h鰄e -> maxx u minx anpassen }maxhb:=maxh;minx:=round( ((maxx-minx)/2+minx)-(1/2*(maxhb)));maxx:=round( ((maxx-minx)/2+minx)+(1/2*(maxhb)));endelse begin { h鰄e < breite -> maxy u miny anpassen }maxhb:=maxb;miny:=round( ((maxy-miny)/2+miny)-(1/2*(maxhb)));maxy:=round( ((maxy-miny)/2+miny)+(1/2*(maxhb)));end;{ projezieren }if ((maxy>miny) and (maxx>minx)) then beginfor dx:=0 to 63 do beginfor dy:=0 to 63 do beginaltx:=dx/64*(maxx-minx)+minx;alty:=dy/64*(maxy-miny)+miny;sx:=round(altx);sy:=round(alty);if ((sx<0) or (sx>63) or (sy<0) or (sy>63)) thenImOCRLernZoom.Canvas.Pixels[dx,dy]:=clWhiteelseImOCRLernZoom.Canvas.Pixels[dx,dy]:=ImOCRLernDraw.Canvas.Pixels[sx,sy];end;end;end;// neuronenbelegung durch mittelwertbildung erzeugenfor dx:=0 to 14 do beginfor dy:=0 to 14 do beginmittel:=0;for x:=0 to 5 do beginfor y:=0 to 5 do beginif ImOCRLernZoom.Canvas.Pixels[2+dx*4+x,2+dy*4+y]=clRed then beginmittel:=mittel+1;end;end;end;mittel:=mittel/36;feld[dy*15+dx]:=mittel;end;end;nr:=Letnr.Value;{neuronenbelegung anzeigen und in Mustersatz 黚ertragen}for dx:=0 to 14 do beginfor dy:=0 to 14 do beginmyNet.myPatterns.M[nr].input[dy*15+dx]:=feld[dy*15+dx];ImOCRLernNeur.Canvas.brush.color:=round(myNet.myPatterns.M[nr].input[dy*15+dx]*255);ImOCRLernNeur.Canvas.fillrect(Rect(dx*5,dy*5,dx*5+4,dy*5+4));end;end;{hier noch die Muster in "myletters" zum abspeichern 黚ertragen }if ((nr>=0) and (nr<myNet.myLetters.Banz)) then beginfor dx:=0 to 63 do beginfor dy:=0 to 63 do beginif (ImOCRLernZoom.Canvas.Pixels[dx,dy]=clred) thenmyNet.myLetters.B[nr].input[dy*64+dx]:=1.0elsemyNet.myLetters.B[nr].input[dy*64+dx]:=0.0;end;end;myNet.myLetters.B[nr].buchst:=upcase(sollchar.text[1]);end;{output-neuronen auf 0 ausser eines}for dx:=0 to myNet.L[nz-1].Nanz-2 do beginif ( dx= (ord(myNet.myLetters.B[nr].buchst)-ord('A'))) then myNet.myPatterns.M[nr].output[dx]:=1else myNet.myPatterns.M[nr].output[dx]:=0;end;feld:=nil;end;procedure TForm1.ButSavPatClick(Sender: TObject);var filename: string;datei: file of double;temp: double;i,a,b: integer;beginif SaveDialogPat.Execute then beginfilename:=SaveDialogPat.FileName;tryAssignFile(datei,filename);Rewrite(datei);temp:=myNet.myPatterns.Manz; Write(datei,temp);temp:=myNet.myPatterns.ilen; Write(datei,temp);temp:=myNet.myPatterns.olen; Write(datei,temp);for i:=0 to myNet.myPatterns.Manz-1 do beginfor a:=0 to myNet.myPatterns.ilen-1 do begintemp:=myNet.myPatterns.M[i].input[a];Write(datei,temp);end;for b:=0 to myNet.myPatterns.olen-1 do begintemp:=myNet.myPatterns.M[i].output[b];Write(datei,temp);end;end;finallyCloseFile(datei);end;end;end;procedure TForm1.ClearI(wo: TImage);var cx,cy:integer;beginfor cx:=0 to wo.clientwidth-1 do beginfor cy:=0 to wo.clientheight-1 do beginwo.Canvas.Pixels[cx,cy]:=0;end;end;end;procedure TForm1.drawPatterns(welches:integer);var x,breite,hoehe: integer;beginLabAnzPat.Caption:='0-'+inttostr(myNet.myPatterns.Manz-1);breite:=round(ImagePat.clientWidth/(myNet.myPatterns.ilen+myNet.myPatterns.olen));ImagePat.clientWidth:=breite*(myNet.myPatterns.ilen+myNet.myPatterns.olen);hoehe:=ImagePat.clientHeight;for x:=0 to myNet.myPatterns.ilen-1 do beginif (myNet.myPatterns.M[welches].input[x]<0.5) then ImagePat.Canvas.brush.color:=clwhiteelse ImagePat.Canvas.brush.color:=clblack;ImagePat.Canvas.FillRect(Rect(x*breite,0,(x+1)*breite-1,hoehe));ImagePat.Canvas.Pen.color:=clblue;ImagePat.Canvas.MoveTo(x*breite,0);ImagePat.Canvas.LineTo(x*breite,ImagePat.clientHeight);end;for x:=0 to myNet.myPatterns.olen-1 do beginif (myNet.myPatterns.M[welches].output[x]<0.5) then ImagePat.Canvas.brush.color:=clwhiteelse ImagePat.Canvas.brush.color:=clblack;ImagePat.Canvas.FillRect(Rect((myNet.myPatterns.ilen+x)*breite,0,(myNet.myPatterns.ilen+x+1)*breite-1,hoehe ));ImagePat.Canvas.Pen.color:=clblue;ImagePat.Canvas.MoveTo((myNet.myPatterns.ilen+x)*breite,0);ImagePat.Canvas.LineTo((myNet.myPatterns.ilen+x)*breite,ImagePat.clientHeight);end;ImagePat.Canvas.Pen.color:=clred;ImagePat.Canvas.MoveTo(myNet.myPatterns.ilen*breite,0);ImagePat.Canvas.LineTo(myNet.myPatterns.ilen*breite,ImagePat.clientHeight);end;procedure TForm1.drawletter(welches: integer);var x,y: integer;beginLabAnzLet.Caption:='0-'+inttostr(myNet.myLetters.Banz-1);for x:=0 to 63 do beginfor y:=0 to 63 do beginImOCRLernZoom.Canvas.Pixels[x,y]:=round(myNet.myLetters.B[welches].input[y*64+x]*255);end;end;end;procedure TForm1.ButOpenClick(Sender: TObject);var filename: string;datei: file of double;temp: double;i,a,b,Mx,Ix,Ox: integer;iar,oar: array of double;tm: CMusterPaar;beginif OpenDialogPat.Execute then beginfilename:=OpenDialogPat.FileName;AssignFile(datei,filename);tryReset(datei);Read(datei,temp); Mx:=round(temp);Read(datei,temp); Ix:=round(temp);Read(datei,temp); Ox:=round(temp);if ((Ix=(myNet.L[0].Nanz-1)) and ((Ox=(myNet.L[nz-1].Nanz-1)))) then begin myNet.myPatterns.Free;myNet.myPatterns:=CMusterSatz.Create(Mx,Ix,Ox);SetLength(iar,Ix); SetLength(oar,Ox);for i:=0 to Mx-1 do beginfor a:=0 to Ix-1 do beginRead(datei,temp); iar[a]:=temp;end;for b:=0 to Ox-1 do beginRead(datei,temp); oar[b]:=temp;end;tm:=CMusterPaar.Create(Ix,Ox,iar,oar);myNet.myPatterns.M[i]:=@tm;tm.free;end;endelse begin {muster passt nicht zum Netz}MessageBox(0,'Illegal Patternset! Creating a new one...', 'caption',1);myNet.myPatterns.Free;myNet.myPatterns:=CMustersatz.Create(1,myNet.L[0].Nanz-1,myNet.L[nz-1].Nanz-1);end;GrLern.Enabled:=true;plainbuttons_freigeben();finallyCloseFile(datei);iar:=nil; oar:=nil;end;PatNr.Text:=inttostr(0);drawPatterns(0);end;end;procedure TForm1.ButSavNetClick(Sender: TObject);vardatei: file of double;temp: double;a,vonl,y1,y2: integer;beginif SaveDialogNet.Execute then begintryAssignFile(datei,SaveDialogNet.Filename);Rewrite(datei);if (myNet.art='P') then temp:=0 else temp:=1; Write(datei,temp);temp:=nz; Write(datei,temp);for a:=0 to nz-1 do begintemp:=myNet.L[a].Nanz; Write(datei,temp);end;for vonl:=0 to nz-2 do beginfor y1:=0 to myNet.L[vonl].Nanz-1 do beginfor y2:=1 to myNet.L[vonl+1].Nanz-1 do begintemp:=myNet.w.w[vonl,y1,y2]; Write(datei,temp);end;end;end;finallyCloseFile(datei);end;end;end;procedure TForm1.Button10Click(Sender: TObject);vardatei: file of double;temp: double;maxanz,a,vonl,y1,y2,Lx: integer;LA: array of integer;art: char;beginif OpenDialogNet.Execute then beginGrNetSpec.Enabled:=false;GrNetSpec.Visible:=false;GrOCRLearn.Visible:=false; GrError.Visible:=true; GrOCRTest.Visible:=false;GrSimpleLearn.Visible:=false; Image.Visible:=false;ocrbuttons_sperren; plainbuttons_sperren;AssignFile(datei,OpenDialogNet.FileName);maxanz:=0;tryReset(datei);Read(datei,temp); if (temp=0) then art:='P' else art:='O';Read(datei,temp); Lx:=round(temp);SetLength(LA,Lx);for a:=0 to Lx-1 do beginRead(datei,temp); LA[a]:=round(temp-1); // -1 , weil bias wird bei layer.create automatisch addiertif LA[a]>maxanz then maxanz:=LA[a];end;myNet.Free;myNet:=CNeuroNet.Create(Lx,LA,art);myNet.w:=Cwmatrix.Create(Lx,maxanz+1); // +1 wegen biasfor vonl:=0 to Lx-2 do beginfor y1:=0 to LA[vonl] do beginfor y2:=1 to LA[vonl+1] do beginRead(datei,temp); myNet.w.w[vonl,y1,y2]:=temp;end;end;end;drawnet();GrLern.Enabled:=false;ButSavNet.Enabled:=true;ButReset.Enabled:=true;if ( myNet.art='P') then beginGrSimpleLearn.Visible:=true;GrSimpleLearn.Enabled:=true;Image.Visible:=true;endelse if (myNet.art='O') then beginGrOCRLearn.Visible:=true;GrOCRLearn.Enabled:=true;GrOCRTest.Visible:=true;GrError.Visible:=true;ClearI(ImOCRTestDraw);ClearI(Imgezoomt);clearI(ImZNeur);end;finallyCloseFile(datei);ImagePat.clientWidth:=400;LA:=nil;end;end;end;procedure TForm1.ButAddPatClick(Sender: TObject);beginmyNet.myPatterns.addPat();drawpatterns(PatNr.Value);end;procedure TForm1.ButPatternsSetNewClick(Sender: TObject);beginmyNet.myPatterns.Free;myNet.myLetters.Free;plainbuttons_freigeben();myNet.myPatterns:=CMustersatz.Create(1,myNet.L[0].Nanz-1,myNet.L[nz-1].Nanz-1);GrLern.Enabled:=true;PatNr.Value:=0;drawpatterns(0);end;procedure TForm1.ImagePatMouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);var dx: integer;isoutput:boolean;pm: PMusterPaar;beginisoutput:=false;dx:=trunc(X /(ImagePat.clientWidth/(myNet.myPatterns.ilen+myNet.myPatterns.olen)));if dx>=myNet.myPatterns.ilen then beginisoutput:=true;dec(dx,myNet.myPatterns.ilen);end;pm:=myNet.myPatterns.M[PatNr.Value];if isoutput then beginif (pm.output[dx]<0.5) then beginpm.output[dx]:=1.0endelse beginpm.output[dx]:=0.0;endendelse beginif (pm.input[dx]<0.5) then beginpm.input[dx]:=1.0endelse beginpm.input[dx]:=0.0;end;end;drawpatterns(PatNr.Value);end;procedure TForm1.PatNrChange(Sender: TObject);begintryif (myNet.myPatterns.Manz>0) then beginif (PatNr.Value<0) then PatNr.Value:=0else if (PatNr.Value>=myNet.myPatterns.Manz) then PatNr.Value:=myNet.myPatterns.Manz-1;drawPatterns(PatNr.Value);end;exceptPatNr.Value:=0;end;end;procedure TForm1.Button14Click(Sender: TObject);beginmyNet.myPatterns.Free;myNet.myLetters.Free;myNet.myLetters:=CLetterSet.Create(1);myNet.myPatterns:=CMusterSatz.Create(1,256,26);LabAnzLet.Caption:='0-'+inttostr(myNet.myLetters.Banz-1);GrLern.Enabled:=true;LetNr.Value:=0;drawletter(0);ocrbuttons_freigeben();end;procedure TForm1.ButAddLetClick(Sender: TObject);beginmyNet.myLetters.addLet();myNet.myPatterns.addPat();drawletter(LetNr.Value);end;procedure TForm1.LetNrChange(Sender: TObject);varnr: integer;beginClearI(ImOCRLernDraw); ClearI(ImOCRLernNeur);trynr:=LetNr.Value;exceptnr:=0;end;if (myNet.myLetters.Banz>0) then beginif (nr<0) then beginnr:=0; LetNr.Value:=0endelse if (nr>=myNet.myLetters.Banz) then beginnr:=myNet.myLetters.Banz-1;LetNr.Value:=nr;end;drawletter(nr);sollchar.Text:=upcase(myNet.myLetters.B[nr].buchst);end;end;procedure TForm1.ButOpeLetClick(Sender: TObject);var datei: file of double;temp,mittel: double;Mx,Ix,i,a,dx,dy,x,y: integer;iar,feld: array of double;tL: CLetter;sc: char;beginif OpenDialogOCR.Execute then begintryAssignFile(datei,OpenDialogOCR.FileName);Reset(datei);Read(datei,temp); Mx:=round(temp);Ix:=4096;myNet.myLetters.Free;myNet.myPatterns.Free;myNet.myLetters:=CLetterSet.Create(Mx);myNet.myPatterns:=CMusterSatz.Create(Mx,225,26);SetLength(feld,225);SetLength(iar,4096);for i:=0 to Mx-1 do beginRead(datei,temp); sc:=chr(round(temp));for a:=0 to Ix-1 do beginRead(datei,temp); iar[a]:=temp;end;tL:=CLetter.Create(iar);myNet.myLetters.B[i]:=@tL;myNet.myLetters.B[i].buchst:=sc;tL.free;// in das muster f黵die neuronen eintragenfor dx:=0 to 14 do beginfor dy:=0 to 14 do beginmittel:=0;for x:=0 to 5 do beginfor y:=0 to 5 do beginmittel:=mittel+myNet.myLetters.B[i].input[(2+dx*4+x)+(2+dy*4+y)*64];end;end;mittel:=mittel/36;feld[dy*15+dx]:=mittel;end;end;for x:=0 to 224 do beginmyNet.myPatterns.M[i].input[x]:=feld[x];end;for dx:=0 to myNet.L[nz-1].Nanz-2 do beginif (dx= (ord(myNet.myLetters.B[i].buchst)-ord('A'))) then myNet.myPatterns.M[i].output[dx]:=1else myNet.myPatterns.M[i].output[dx]:=0;end;end;GrLern.Enabled:=true;GrOCRTest.Visible:=true; GrError.Visible:=true;ClearI(ImOCRTestDraw);ClearI(Imgezoomt);iar:=nil;feld:=nil;finallyClosefile(datei);end;ocrbuttons_freigeben();LetNr.Text:=inttostr(0);drawletter(0);end;end;procedure TForm1.ButSavLetClick(Sender: TObject);var datei: file of double;i,a: integer;temp:double;beginif SaveDialogOCR.Execute then begintryAssignFile(datei,SaveDialogOCR.FileName);Rewrite(datei);temp:=myNet.myLetters.Banz;Write(datei,temp);for i:=0 to myNet.myLetters.Banz-1 do begintemp:=ord(myNet.myLetters.B[i].buchst); Write(datei,temp);for a:=0 to 4095 do begintemp:=myNet.myLetters.B[i].input[a];Write(datei,temp);end;end;finallyCloseFile(datei);end;end;end;procedure TForm1.ImOCRTestDrawMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);beginerkenne:=true;ax:=x;ay:=y;with ImOCRTestDraw.Canvas.Pen do begincolor:=clRed;width:=6;end;end;procedure TForm1.ImOCRTestDrawMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);beginif erkenne then beginImOCRTestDraw.Canvas.MoveTo(ax,ay);ImOCRTestDraw.Canvas.LineTo(x,y);ax:=x;ay:=y;end;end;procedure TForm1.ImOCRTestDrawMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);beginerkenne:=false;end;procedure TForm1.Button16Click(Sender: TObject);var zumneur: array of double;sx,sy,maxx,maxy,maxhb,minx,miny,maxh,maxb,dx,dy,x,y:integer;mittel,altx,alty:double;beginmaxx:=0; minx:=1000;maxy:=0; miny:=1000;SetLength(zumneur,225);//=============================================================== { Grenzen im Paint-Image feststellen }for sx:=0 to 63 do beginfor sy:=0 to 63 do beginif (ImOCRTestDraw.Canvas.Pixels[sx,sy]=clRed) then beginif sx < minx then minx:=sx; if sx > maxx then maxx:=sx;if sy < miny then miny:=sy; if sy > maxy then maxy:=sy;end;end;end;{aspect-ratio beibehalten }maxh:=maxy-miny; maxb:=maxx-minx;if (maxh>maxb) then begin { breite < h鰄e -> maxx u minx anpassen }maxhb:=maxh;minx:=round( ((maxx-minx)/2+minx)-(1/2*(maxhb)));maxx:=round( ((maxx-minx)/2+minx)+(1/2*(maxhb)));endelse begin { h鰄e < breite -> maxy u miny anpassen }maxhb:=maxb;miny:=round( ((maxy-miny)/2+miny)-(1/2*(maxhb)));maxy:=round( ((maxy-miny)/2+miny)+(1/2*(maxhb)));end;{ zoomen }if ((maxy>miny) and (maxx>minx)) then beginfor dx:=0 to 63 do beginfor dy:=0 to 63 do beginaltx:=dx/64*(maxx-minx)+minx;alty:=dy/64*(maxy-miny)+miny;sx:=round(altx);sy:=round(alty);if ((sx<0) or (sx>63) or (sy<0) or (sy>63)) thenImGezoomt.Canvas.Pixels[dx,dy]:=clWhiteelseImgezoomt.Canvas.Pixels[dx,dy]:=ImOCRTestDraw.Canvas.Pixels[sx,sy];end;end;end;{ auf ein Muster 6*6-Patches die sich 黚erlappen interpolieren }{ daher auf ein Feld von 10*10 (256 Neuronen) }for dx:=0 to 14 do beginfor dy:=0 to 14 do beginmittel:=0;for x:=0 to 5 do beginfor y:=0 to 5 do beginif Imgezoomt.Canvas.Pixels[2+dx*4+x,2+dy*4+y]=clRed then beginmittel:=mittel+1;end;end;end;mittel:=mittel/36;zumneur[dy*15+dx]:=mittel;end;end;{ zeichnen und ans netz anlegen}for dx:=0 to 14 do beginfor dy:=0 to 14 do beginImZNeur.Canvas.brush.color:=round(zumneur[dy*15+dx]*255);ImZNeur.Canvas.fillrect(Rect(dx*5,dy*5,dx*5+4,dy*5+4));myNet.L[0].N[dy*15+dx].activity:=zumneur[dy*15+dx];end;end;myNet.calc_forward();show_ocr_result();zumneur:=nil;end;procedure TForm1.ButTestClearClick(Sender: TObject);beginclearI(ImOCRTestDraw);clearI(Imgezoomt);clearI(ImZNeur);end;procedure TForm1.Button17Click(Sender: TObject);beginClose;end;procedure TForm1.Button8Click(Sender: TObject);var solle,noise: double;beginvorbereiten;trysolle:=strtofloat(sollerror.Text);exceptsolle:=0.01;end;noise:=getnoise();myNet.lerne_bis(Application,solle,ErrorLabel,noise,ErrorImage);Akt();end;procedure TForm1.RadioGroup1Click(Sender: TObject);beginif (RadioGroup1.ItemIndex=1) then beginAnzGrid.Cells[1,1]:=floattostr(225);AnzGrid.Cells[1,AnzGrid.RowCount-1]:=floattostr(26);end;end;procedure TForm1.AusQuelleClick(Sender: TObject);varmittel:double;zumneur: array of array of integer;dx,dy,x,y: integer;beginclearI(ImOCRTestDraw);for dx:=0 to 14 do beginfor dy:=0 to 14 do beginmittel:=0;for x:=0 to 5 do beginfor y:=0 to 5 do beginif ImOCRLernZoom.Canvas.Pixels[2+dx*4+x,2+dy*4+y]=clRed then beginmittel:=mittel+1;end;end;end;mittel:=mittel/36;myNet.L[0].N[dy*15+dx].activity:=mittel;end;end;myNet.calc_forward();show_ocr_result();zumneur:=nil;end;procedure TForm1.show_ocr_result() ;varletztlay,x,gewinnt: integer;akt,mgew: double;beginclearI(ImErg);mgew:=0; gewinnt:=0;ImErg.Canvas.Brush.color:=clwhite;letztlay:=nz-1;ImErg.Canvas.Font.Height:=4;for x:=1 to ((myNet.L[nz-1].Nanz)-1) do beginakt:=myNet.L[letztlay].N[x].activity;if (akt>mgew) then begin mgew:=akt; gewinnt:=x; end;ImErg.Canvas.fillrect(Rect(x*14,70-round(60*akt),2+x*14,70));ImErg.Canvas.TextOut(x*14-2,80,chr(ord('A')-1+x));end;x:=gewinnt;ImErg.Canvas.Brush.color:=clgreen;ImErg.Canvas.TextOut(x*14-2,80,chr(ord('A')-1+x));end;procedure TForm1.ButResetClick(Sender: TObject);beginmyNet.w.initialisieren();myNet.zeichne(Image.canvas);myNet.clearerror();end;procedure TForm1.Button5Click(Sender: TObject);beginmyNet.stop:=true;end;end.。

相关文档
最新文档