【例子介绍】
通过图像识别技术,对拍摄的车牌照片进行灰化、二值化然后准确读出车牌号。
【相关图片】
【源码结构】
function TBPTrainForm.alloc_1d_dbl(n: integer): D1Array; //申请一维数组
var
new1:D1Array;
begin
setlength(new1,n);
Result:=new1;
end;
function TBPTrainForm.alloc_2d_dbl(m, n: integer): D2Array; //申请二维数组
var
new1:D2Array;
i:integer;
begin
setlength(new1,m);
for i:=low(new1) to High(new1) do
Setlength(new1,n);
Result:=new1;
end;
procedure TBPTrainForm.bpnn_adjust_weights(var delta: D1Array; ndelta: integer;
var ly: D1Array; nly: integer; var w, oldw: D2Array; eta, momentum: double);//调整权值
var
k,j:integer;
new_dw:double;
begin
ly[0]:=1.0;
setlength(delta,ndelta 1);
setlength(ly,nly 1);
setlength(oldw,nly 1,ndelta 1);
setlength(w,nly 1,ndelta 1);
for j:=1 to ndelta do
begin
for k:=0 to nly do
begin
new_dw:=((eta*delta[j]*ly[k]) (momentum*oldw[k,j]));
w[k,j]:=w[k,j] new_dw;
oldw[k,j]:=new_dw;
end;
end;
end;
procedure TBPTrainForm.bpnn_hidden_error(var delta_h: D1Array; nh: integer;
var delta_o: D1Array; no: integer; var who: D2Array; var hidden: D1Array);//隐含层误差
var
j,k:integer;
h,sum:double;//,errsum:double;
begin
// errsum:=0.0;
setlength(delta_h,nh 1);
setlength(delta_o,no 1);
setlength(hidden,nh 1);
setlength(who,nh 1,no 1);
for j:=1 to nh do
begin
h:=hidden[j];
sum:=0.0;
for k:=1 to no do
sum:= sum delta_o[k]*who[j,k];
delta_h[j]:=h*(1.0-h)*sum;
end;
end;
procedure TBPTrainForm.bpnn_initialize;
begin
Randomize;
end;
procedure TBPTrainForm.bpnn_layerforward(var l1, l2: D1Array; var conn: D2Array; n1,
n2: integer);//前向传播
var
sum:double;
j,k:integer;
begin
setlength(l1,n1 1);
setlength(l2,n2 1);
setlength(conn,n1 1,n2 1);
l1[0]:=1.0;
for j:=1 to n2 do
begin
sum:=0.0;
for k:=0 to n1 do
sum:=sum conn[k,j]*l1[k];
l2[j]:=squash(sum);
end;
end;
procedure TBPTrainForm.bpnn_output_error(var delta, target, output: D1Array;
nj: integer); //输出误差
var
j:integer;
o,t:double;
begin
setlength(delta,nj 1);
setlength(target,nj 1);
setlength(output,nj 1);
for j:=1 to nj do //循环计算delta
begin
o:=output[j];
t:=target[j];
delta[j]:=o*(1.0-o)*(t-o);
end;
end;
//随机初始化权值
procedure TBPTrainForm.bpnn_randomize_weights(var w: D2Array; m, n: integer);
var
i,j:integer;
begin
setlength(w,m 1,n 1);
for i:=0 to m do
for j:=0 to n do
w[i,j]:=Dpn1();
end;
procedure TBPTrainForm.bpnn_zero_weights(var w: D2Array; m, n: integer);
var
i,j:integer;
begin
setlength(w,m 1,n 1);
for i:=0 to m do
for j:=0 to n do
w[i,j]:=0.0;
end;
procedure TBPTrainForm.BPTrain(var Data_in, Data_out: D2Array; n_in,
n_hidden: integer; min_ex, momentum, eta: double; num: integer);
var
i,k,n,l,n_out:integer;
ex:double;
input_unites,hidden_unites,output_unites:D1Array;
output_deltas,hidden_deltas,target:D1Array;
Showoutput_unites:D2Array;
input_weights,hidden_weights:D2Array;
input_prev_weights,hidden_prev_weights:D2Array;
digitalcount:integer;
E:WideString;
begin
ex:=0;
l:=0;
n_out:=4;
//为各个数据结构申请内存空间
input_unites:= alloc_1d_dbl(n_in 1);
hidden_unites:=alloc_1d_dbl(n_hidden 1);
output_unites:=alloc_1d_dbl(n_out 1);
output_deltas:=alloc_1d_dbl(n_hidden 1);
hidden_deltas:=alloc_1d_dbl(n_out 1);
target:=alloc_1d_dbl(n_out 1);
input_weights:=alloc_2d_dbl(n_in 1,n_hidden 1);
hidden_weights:=alloc_2d_dbl(n_in 1,n_hidden 1);
input_prev_weights:=alloc_2d_dbl(n_hidden 1,n_out 1);
hidden_prev_weights:=alloc_2d_dbl(n_hidden 1,n_out 1);
// 为产生随机序列播种
bpnn_initialize;
//对各种权值进行初始化
bpnn_randomize_weights(input_weights,n_in,n_hidden);
bpnn_randomize_weights(hidden_weights,n_hidden,n_out);
bpnn_zero_weights(input_prev_weights,n_in,n_hidden);
bpnn_zero_weights(hidden_prev_weights,n_hidden,n_out);
//开始对BP网络训练,设定最大迭代次数为15000次
E:=CharEdit.text;
digitalcount:=length(E);
Showoutput_unites:=alloc_2d_dbl(digitalcount 1,n_out 1,);
bpnn_zero_weights(Showoutput_unites,digitalcount,n_out);
for n:=1 to StrToInt(repeateNumEdit.text) do
begin
data_in:=code(Img,digitalcount,16,20 );
for l:=0 to 15000 do
begin
for k:=0 to num-1 do
begin
//将样本特征向量输送到输入层
for i:=1 to n_in do
input_unites[i]:=data_in[k,i-1];
// 将预定的理想输出输入到BP网络的理想输出单元
for i:=1 to n_out do
target[i]:=data_out[k,i-1];
target0edit.Text :=floattostr(data_out[k,n_out-1]);
target1edit.Text :=floattostr(data_out[k,n_out-2]);
target2edit.Text:=floattostr(data_out[k,n_out-3]);
target3edit.Text :=floattostr(data_out[k,n_out-4]);
// 将数据由输入层传到隐含层
bpnn_layerforward(input_unites,hidden_unites,input_weights,n_in,n_hidden);
// 将隐含层的输出传到输出层
bpnn_layerforward(hidden_unites,output_unites,hidden_weights,n_hidden,n_out);
// 误差计算
bpnn_output_error(output_deltas,target,output_unites,n_out);
bpnn_hidden_error(hidden_deltas,n_hidden,output_deltas,n_out,
hidden_weights,hidden_unites);
//权值调整
bpnn_adjust_weights(output_deltas,n_out,hidden_unites,n_hidden,
hidden_weights,hidden_prev_weights,eta,momentum);
bpnn_adjust_weights(hidden_deltas,n_hidden,input_unites,n_in,
input_weights,input_prev_weights,eta,momentum);
//误差统计
for i:=1 to n_out do
begin
ex:=ex (output_unites[i]-data_out[k,i-1])*(output_unites[i]-data_out[k,i-1]);
Showoutput_unites[k,i]:=output_unites[i]
end;
//每个字的解
end;
ex:=ex/(num*n_out);
// 跳出循环
if ex<min_ex then
break;
end;
memo2.Lines .add('第' inttostr(n) '次四个结点的输出值:');
for i:=0 to num-1 do
memo2.Lines.Add(inttostr(i) '的值:' ' ' format('%5.3f',[showoutput_unites[i,1]]) ' '
format('%5.3f',[showoutput_unites[i,2]]) ' '
format('%5.3f',[showoutput_unites[i,3]]) ' '
format('%5.3f',[showoutput_unites[i,4]]) ' ' #13);
memo2.lines.add('迭代次数为:' inttostr(l) #13);
//迭代次数控制
//相关保存
//输入层到隐含层的权值
end; //训练次数反复
n_out0Edit.Text:=floattostr(output_unites[4]);
n_out1Edit.Text:=floattostr(output_unites[3]);
n_out2Edit.Text:=floattostr(output_unites[2]);
n_out3Edit.Text:=floattostr(output_unites[1]);
w_weight(input_weights,n_in,n_hidden,Pchar('输入层到隐含层.txt'));
//隐含层到输出层的权值
w_weight(hidden_weights,n_hidden,n_out,Pchar('隐含层到输出层.txt'));
//保存各层结点的数目
w_num(n_in,n_hidden,n_out,Pchar('各层结点数.txt'));
if ex<=min_ex then
trainresult.Caption :=format('平均误差为%.4f',[ex]);
if ex>min_ex then
trainresult.Caption :=format('训练失败!迭代了%d次' #13'平均误差为%.4f',[l,ex]);
//释放内存空间
setlength(input_unites,0);
setlength(hidden_unites,0);
setlength(output_unites,0);
setlength(hidden_deltas,0);
setlength(hidden_deltas,0);
setlength(target,0);
setlength(input_weights,0);
setlength(hidden_weights,0);
setlength(input_prev_weights,0);
setlength(hidden_prev_weights,0);
end;
function TBPTrainForm.code(Img: TImage; num, imagewidth,
imageHeight: integer): D2Array;
var
i,j,k:integer;
w,h:integer;
s,Data:D2Array;
max:double;
rect:Trect;
E:WideString;
t:string;
//////////////////////////////////////////////////
// smin,smax:integer;
// minarray,maxarray,ytemp:array of integer;
//////////////////////////////////////////////////
begin
Randomize;
memo1.Clear ;
img.Width:= 190;
img.height:=220;
E:= charedit.Text;
num:=length(E);
setlength(s,imagewidth,imageHeight);
setLength(data,num,imagewidth*imageHeight);
for k:=0 to num-1 do
begin
charimage.Canvas.Font.Color := clBlack;
charimage.Canvas.Font.Size :=36;
if E <> '' then
begin
charimage.Canvas.TextOut(0, 0, E[k 1] ' ') ;
////////////////////////////////////////////////////////////////////////////////
GetRegion(charimage.Picture.Bitmap);
Zoom;
////////////////////////////////////////////////////////////////////////////////
for w:=0 to img.Width-1 do
for H:=0 to img.Height-1 do
img.Canvas.Pixels[w,h]:=clWhite;
{ for w:=0 to charimage.Width-1 do
for H:=0 to charimage.Height-1 do
begin
if charimage.Canvas.Pixels[w,h]=clBlack then
begin
for i:=1 to 4 do
for j:=1 to 4 do
img.Canvas.Pixels[w*4 i Random(3),h*4 j]:=clBlack; //扩展图片
end;
end; }
for w:=0 to NormalImage.Width-1 do
for H:=0 to NormalImage.Height-1 do
begin
if NormalImage.Canvas.Pixels[w,h]=clBlack then
begin
for i:=1 to 4 do
for j:=1 to 4 do
img.Canvas.Pixels[w*4 i Random(3),h*4 j]:=clBlack; //扩展图片
end;
end;
end;
if img <> nil then
begin
img.Width:= imgwidth;
img.height:=imgheight;
w:=img.Width mod imagewidth;
img.Width:=img.Width imagewidth-w;
w:=img.Width div imagewidth;
h:=img.Height mod imageHeight;
img.Height :=img.Height imageHeight -h;
h:= img.Height div imageHeight;
max:=0;
for i:=1 to imagewidth-1 do
for j:=1 to imageHeight-1 do
begin
rect.Left :=w*(i-1);
rect.Top :=h*(j-1);
rect.Right :=rect.Left w-1;
rect.Bottom :=rect.Top h-1;
s[i,j]:=statistic(rect,img);
if s[i,j]>max then
max:=s[i,j];
end;
for j:=0 to imageHeight-1 do
begin
for i:=0 to imageWidth-1 do
begin
if s[i,j]/max >0.2 then
Data[k,j*imagewidth i]:=0.9
else
Data[k,j*imagewidth i]:=0.1;
end;
end;
end;
////////////////////////////////////////////////////////////////////////////////
{ smin:=0;
smax:=0;
setlength(minarray,imageHeight);
setlength(maxarray,imageHeight);
setlength(ytemp,imageHeight);
for j:=0 to imageHeight-1 do
begin
for i:=0 to imageWidth-1 do
begin
if Data[k,j*imagewidth i]<=0.2 then
begin
if i=minarray[j] then inc(minarray[j]);
end;
end;
memo2.Lines.Add(inttostr(minarray[j]));
if minarray[j]=imageWidth then Continue;
for i:=imageWidth-1 downto 0 do
begin
if Data[k,j*imagewidth i]<=0.2 then
begin
if i 1=imageWidth-maxarray[j] then inc(maxarray[j]);
end;
end;
// memo2.Lines.Add(inttostr(maxarray[j]));
end;
for i:=0 to imageHeight-1 do ytemp[i]:=minarray[i];
selectionsort(minarray);
selectionsort(maxarray);
smin:=minarray[0];
i:=-1;
repeat
inc(i);
smax:=maxarray[i];
until(smax<>0);
BPtrainform.Caption:=inttostr(smin) ' ' inttostr(imageWidth-1-smax); }
////////////////////////////////////////////////////////////////////////////////
t:='';
for j:=0 to imageHeight-1 do
begin
// if ytemp[j]=imagewidth then continue;
t:=' ';
for i:=0 to imageWidth-1 do
begin
if Data[k,j*16 i]>=0.8 then
t:= t '1' ' ' ;
if (Data[k,j*16 i]<=0.2) then
t:= t '0' ' ' ;
end;
memo1.Lines.Add(t);
end;
memo1.Lines.Add('');
////////////////////////////////////////////////////////////////////////////////
end;
result:=Data;
end;
// 进行识别,并将识别结果写出
procedure TBPTrainForm.CodeRecognize(var Data_in: D1Array; n_in, n_hidden,
n_out: integer; resultlabel: TLabel);
var
i:integer;
input_unites,hidden_unites,output_unites:D1Array;
input_weights,hidden_weights:D2Array;
output_unites8421:D1Num;
begin
input_unites:=alloc_1d_dbl(n_in 1) ;
hidden_unites:=alloc_1d_dbl(n_hidden 1);
output_unites:=alloc_1d_dbl(n_out 1);
setlength(output_unites8421,4);
input_weights:=alloc_2d_dbl(n_in 1,n_hidden 1);
hidden_weights:=alloc_2d_dbl(n_hidden 1,n_out 1);
if r_weight(input_weights,n_in,n_hidden,Pchar('输入层到隐含层.txt'))
=false then exit;
if r_weight(hidden_weights,n_hidden,n_out,Pchar('隐含层到输出层.txt'))
=false then exit;
begin
for i:=1 to n_in do
input_unites[i]:=data_in[i-1];
//前向激活
bpnn_layerforward(input_unites,hidden_unites,input_weights,n_in,n_hidden);
bpnn_layerforward(hidden_unites,output_unites,hidden_weights,n_hidden,n_out);
for i:=1 to 4 do
begin
if output_unites[i]>0.55 then
output_unites8421[i-1]:=1
else
output_unites8421[i-1]:=0;
end;
n_out0Edit.Text:=floattostr(output_unites[4]);
n_out1Edit.Text:=floattostr(output_unites[3]);
n_out2Edit.Text:=floattostr(output_unites[2]);
n_out3Edit.Text:=floattostr(output_unites[1]);
//根据输出结果进行识别
//显示识别产生的输出码
if (output_unites8421[3]=0) and (output_unites8421[2]=0) and (output_unites8421[1]=0)
and(output_unites8421[0]=0 ) then
resultlabel.Caption :='识别结果为:0';
if (output_unites8421[3]=1) and (output_unites8421[2]=0) and (output_unites8421[1]=0)
and(output_unites8421[0]=0 ) then
resultlabel.Caption :='识别结果为:1';
if (output_unites8421[3]=0) and (output_unites8421[2]=1) and (output_unites8421[1]=0)
and(output_unites8421[0]=0 ) then
resultlabel.Caption :='识别结果为:2';
if (output_unites8421[3]=1) and (output_unites8421[2]=1) and (output_unites8421[1]=0)
and(output_unites8421[0]=0 ) then
resultlabel.Caption :='识别结果为:3';
if (output_unites8421[3]=0) and (output_unites8421[2]=0) and (output_unites8421[1]=1)
and(output_unites8421[0]=0 ) then
resultlabel.Caption :='识别结果为:4';
if (output_unites8421[3]=1) and (output_unites8421[2]=0) and (output_unites8421[1]=1)
and(output_unites8421[0]=0 ) then
resultlabel.Caption :='识别结果为:5';
if (output_unites8421[3]=0) and (output_unites8421[2]=1) and (output_unites8421[1]=1)
and(output_unites8421[0]=0 ) then
resultlabel.Caption :='识别结果为:6';
if (output_unites8421[3]=1) and (output_unites8421[2]=1) and (output_unites8421[1]=1)
and(output_unites8421[0]=0 ) then
resultlabel.Caption :='识别结果为:7';
if (output_unites8421[3]=0) and (output_unites8421[2]=0) and (output_unites8421[1]=0)
and(output_unites8421[0]=1 ) then
resultlabel.Caption :='识别结果为:8';
if (output_unites8421[3]=1) and (output_unites8421[2]=0) and (output_unites8421[1]=0)
and(output_unites8421[0]=1 ) then
resultlabel.Caption :='识别结果为:9';
if (output_unites8421[3]=0) and (output_unites8421[2]=1) and (output_unites8421[1]=0)
and(output_unites8421[0]=1 ) then
resultlabel.Caption :='识别结果为:湘';
if (output_unites8421[3]=1) and (output_unites8421[2]=1) and (output_unites8421[1]=0)
and(output_unites8421[0]=1 ) then
resultlabel.Caption :='识别结果为:赣';
if (output_unites8421[3]=0) and (output_unites8421[2]=0) and (output_unites8421[1]=1)
and(output_unites8421[0]=1 ) then
resultlabel.Caption :='识别结果为:浙';
if (output_unites8421[3]=1) and (output_unites8421[2]=0) and (output_unites8421[1]=1)
and(output_unites8421[0]=1 ) then
resultlabel.Caption :='识别结果为:A';
if (output_unites8421[3]=0) and (output_unites8421[2]=1) and (output_unites8421[1]=1)
and(output_unites8421[0]=1 ) then
resultlabel.Caption :='识别结果为:B';
if (output_unites8421[3]=1) and (output_unites8421[2]=1) and (output_unites8421[1]=1)
and(output_unites8421[0]=1 ) then
resultlabel.Caption :='识别结果为:C';
setlength(input_unites,0);
setlength(hidden_unites,0);
setlength(output_unites,0);
setlength(input_weights,0,0);
setlength(hidden_weights,0,0);
end;
end;
function TBPTrainForm.Dpn1: double;
begin
Randomize;
result:=((Random*2.0)-1.0);
end;
function TBPTrainForm.r_num(n: D1Num; name: Pchar): boolean;
var
buffer:D1Num;
s:TStringList;
i:integer;
Pathstring:string;
begin
s:=TStringList.Create ;
setlength(buffer,3);
Pathstring:=ExtractFilePath(Application.ExeName) '\NetWeightParameter\' ;
s.LoadFromFile(Pathstring name);
for i:=0 to 2 do
begin
buffer[i]:=strtoint(s[i]);
n[i]:=buffer[i];
end;
setlength(buffer,0);
result:=true;
end;
function TBPTrainForm.Rcode(AImg: TImage; imagewidth,
imageHeight: integer): D1Array;
var
i,j,k,idx:integer;
w,h:integer;
s:D2Array;
Data:D1Array;
max:double;
rect:Trect;
E:WideString;
t:string;
//////////////////////////////////////////////
smin,smax:integer;
minarray,maxarray,ytemp:array of integer;
temp,temp2:array of array of integer;
begin
Randomize;
memo1.Clear ;
k:=0;
img.Width:= 190;
img.height:=220;
setlength(s,imagewidth,imageHeight);
setLength(data,imagewidth*imageHeight);
charimage.Canvas.Font.Color := clBlack;
charimage.Canvas.Font.Size :=36;
if E <> '' then
begin
if RecognizeCharInPicture=false then
charimage.Canvas.TextOut(0, 0, E[1] ' ') ;
for w:=0 to img.Width-1 do
for H:=0 to img.Height-1 do
img.Canvas.Pixels[w,h]:=clWhite;
for w:=0 to charimage.Width-1 do
for H:=0 to charimage.Height-1 do
begin
if charimage.Canvas.Pixels[w,h]=clBlack then
begin
for i:=1 to 4 do
for j:=1 to 4 do
img.Canvas.Pixels[w*4 i,h*4 j]:=clBlack;
end;
end;
end;
if img <> nil then
begin
img.Width:= imgwidth;
img.height:=imgheight;
w:=img.Width mod imagewidth;
img.Width:=img.Width imagewidth-w;
w:=img.Width div imagewidth;
h:=img.Height mod imageHeight;
img.Height :=img.Height imageHeight -h;
h:= img.Height div imageHeight;
max:=0;
for i:=1 to imagewidth-1 do
for j:=1 to imageHeight-1 do
begin
rect.Left :=w*(i-1);
rect.Top :=h*(j-1);
rect.Right :=rect.Left w-1;
rect.Bottom :=rect.Top h-1;
s[i,j]:=statistic(rect,img);
if s[i,j]>max then
max:=s[i,j];
end;
for j:=0 to imageHeight-1 do
begin
for i:=0 to imageWidth-1 do
begin
if s[i,j]/max >0.2 then
Data[j*imagewidth i]:=0.9
else
Data[j*imagewidth i]:=0.1;
end;
end;
end;
////////////////////////////////////////////////////////////////////////////////
{ smin:=0;
smax:=0;
setlength(minarray,imageHeight);
setlength(maxarray,imageHeight);
setlength(ytemp,imageHeight);
for j:=0 to imageHeight-1 do
begin
for i:=0 to imageWidth-1 do
begin
if Data[j*imagewidth i]<=0.2 then
begin
if i=minarray[j] then inc(minarray[j]);
end;
end;
if minarray[j]=imageWidth then Continue;
for i:=imageWidth-1 downto 0 do
begin
if Data[j*imagewidth i]<=0.2 then
begin
if i 1=imageWidth-maxarray[j] then inc(maxarray[j]);
end;
end;
end;
for i:=0 to imageHeight-1 do ytemp[i]:=minarray[i];
selectionsort(minarray);
selectionsort(maxarray);
smin:=minarray[0];
i:=-1;
repeat
inc(i);
smax:=maxarray[i];
until(smax<>0);
BPtrainform.Caption:=inttostr(smin) ' ' inttostr(imageWidth-1-smax); }
////////////////////////////////////////////////////////////////////////////////
for j:=0 to imageHeight-1 do
begin
// if ytemp[j]=imagewidth then continue;
t:=' ';
for i:=0 to imageWidth-1 do
begin
if Data[j*16 i]>=0.8 then
begin
t:= t '1' ' ';
end;
if (Data[j*16 i]<=0.2) then
begin
t:= t '0' ' ';
end;
end;
memo1.Lines.Add(t);
end;
result:=Data;
end;
function TBPTrainForm.squash(x: double): double;
begin
Result:=(1.0/(1.0 exp(-x)));
end;
function TBPTrainForm.Statistic(const rect: Trect; img: TImage): integer;
var
x,y:integer;
begin
Result:=0;
for x:=rect.Left to rect.Right do
for y:=rect.Top to rect.Bottom do
if img.Canvas.Pixels[x,y]<>16777215 then
inc(result);
end;
procedure TBPTrainForm.w_num(n1, n2, n3: integer; name: Pchar); //保存各层结点的数目
var
s:TStringList;
buffer: D1Num;
i:integer;
begin
s:=TStringList.Create ;
setlength(buffer,3);
buffer[0]:=n1;
buffer[1]:=n2;
buffer[2]:=n3;
for i:=0 to 2 do
s.Add(inttostr(buffer[i])) ;
s.SaveToFile(name);
s.Free;
end;
function TBPTrainForm.r_weight(var w: D2Array; n1, n2: integer;
name: Pchar): boolean; //读取权值
var
i,j:integer;
buffer:D1Array;
s:TStringList;
Pathstring:string;
begin
setlength(buffer,(n1 1)*(n2 1));
setlength(w,(n1 1),(n2 1));
s:=TStringList.Create ;
Pathstring:=ExtractFilePath(Application.ExeName) '\NetWeightParameter\' ;
s.LoadFromFile(Pathstring name);
for i:=0 to s.Count-1 do
buffer[i]:=strtofloat(s[i]);
for i:=0 to n1 do
for j:=0 to n2 do
w[i,j]:=buffer[i*(n2 1) j];
s.Free;
setlength(buffer,0);
setlength(buffer,(n1 1)*(n2 1)); result:=true;
end;
procedure TBPTrainForm.w_weight(var w: D2Array; n1, n2: integer; name: Pchar);
var
i,j:integer;
s:TstringList;
buffer:D1Array;
Pathstring:string;
begin
s:=TStringList.Create ; //??
setlength(buffer,(n1 1)*(n2 1));
for i:=0 to n1 do
for j:=0 to n2 do
begin
buffer[i*(n2 1) j]:=w[i,j];
s.Add(floattostr(buffer[i*(n2 1) j]));
end;
Pathstring:=ExtractFilePath(Application.ExeName) '\NetWeightParameter\' ;
s.SaveToFile(Pathstring name);
end;
procedure TBPTrainForm.FormCreate(Sender: TObject);
begin
imgwidth:=180;
imgheight:=210;
OpenDialog1.Filter:='*.bmp|*.bmp';
RecognizeCharInPicture:=false;
end;
procedure TBPTrainForm.ShowResult();
begin
n_out0Edit.Text:=show1;
n_out1Edit.Text:=show2;
n_out2Edit.Text:=show3;
n_out3Edit.Text:=show4;
end;
procedure TBPTrainForm.RecognizeInPictureClick(Sender: TObject);
begin
RecognizeCharInPicture:=true;
if OpenDialog1.Execute then
begin
CharImage.Picture.Bitmap.LoadFromFile(OpenDialog1.FileName);
end;
RecognizeChar(Sender);
end;
procedure TBPTrainForm.trainButtonClick(Sender: TObject);
var
momentum,min_ex,eta:double;
n_hidden,digitalcount:integer;
data_in,data_out:D2Array;
i,j:integer;
E:WideString;
const
A:array[0..15] of array[0..3] of double=((0.1,0.1,0.1,0.1),(0.1,0.1,0.1,0.9),
(0.1,0.1,0.9,0.1),(0.1,0.1,0.9,0.9),(0.1,0.9,0.1,0.1),(0.1,0.9,0.1,0.9),
(0.1,0.9,0.9,0.1),(0.1,0.9,0.9,0.9),(0.9,0.1,0.1,0.1),(0.9,0.1,0.1,0.9),
(0.9,0.1,0.9,0.1),(0.9,0.1,0.9,0.9),(0.9,0.9,0.1,0.1),(0.9,0.9,0.1,0.9),
(0.9,0.9,0.9,0.1),(0.9,0.9,0.9,0.9));
n_in:integer=320;
begin
E:=CharEdit.text;
digitalcount:=length(E);
momentum:=strtofloat(m_a.Text );
min_ex:=strtofloat(m_ex.Text );
eta:=strtofloat(m_eta.Text );
n_hidden:=strtoint(m_hn.Text );
setlength(data_in,16,20);
setlength(data_out,digitalcount,4);
data_in:=code(Img,digitalcount,16,20 );
for i:=0 to digitalcount-1 do //输出节点值赋值
for j:=0 to 3 do
data_out[i,j]:=A[i,j];
//训练BP网络
BPTrain(Data_in, Data_out, n_in, n_hidden,min_ex, momentum, eta, digitalcount);
end;
procedure TBPTrainForm.RecognizeChar(Sender: TObject);
var
n:D1Num;
n_in,n_hidden,n_out:integer;
i,j,w,h,x0,y0:integer;
data:D1Array;
//data_in:D1Array;
E:WideString;
begin
img.Width:= 190;
img.height:=220;
E:=RecognizeEdit.Text;
charimage.Canvas.Font.Color := clBlack;
charimage.Canvas.Font.Size :=36;
if E<> '' then
begin
for w:=0 to img.Width-1 do
for H:=0 to img.Height-1 do
img.Canvas.Pixels[w,h]:=clWhite;
if RecognizeCharInPicture=false then
charimage.Canvas.TextOut(0, 0, E[1] ' ') ;
//////////////////////////////////////////////////////////////////
GetRegion(charimage.Picture.Bitmap);
zoom;
x0:=Random(2); y0:=Random(2);
// for w:=0 to NormalImage.Width-1 do
// for H:=0 to NormalImage.Height-1 do
// img.Canvas.Pixels[w,h]:=clWhite;
for w:=0 to NormalImage.Width-1 do
for H:=0 to NormalImage.Height-1 do
begin
if NormalImage.Canvas.Pixels[w,h]=clBlack then
begin
for i:=1 to 4 do
for j:=1 to 4 do
if RecognizeCharInPicture=false then
img.Canvas.Pixels[x0 w*4 i,y0 h*4 j]:=clBlack
else img.Canvas.Pixels[x0 w*4 i,y0 h*4 j]:=clBlack;
end;
end;
end;
setlength(data,16*20);
setlength(n,3);
if r_num(n,Pchar('各层结点数.txt'))=false then exit
else
n_in:=n[0]; //获取输入层结点数目
n_hidden:=n[1]; //获取隐含层数目
n_out:=n[2];//获取输出层数目
data:= rcode(Img,16,20);
//根据特征进行样本识别
CodeRecognize(Data,n_in, n_hidden,n_out,resultlabel);
end;
procedure TBPTrainForm.patternClick(Sender: TObject);
var
momentum,min_ex,eta:double;
n_hidden,digitalcount:integer;
data_in:d1array;
data_out:D2Array;
i,j:integer;
E:WideString;
k:integer;
const
A:array[0..15] of array[0..3] of double=((0.1,0.1,0.1,0.1),(0.1,0.1,0.1,0.9),
(0.1,0.1,0.9,0.1),(0.1,0.1,0.9,0.9),(0.1,0.9,0.1,0.1),(0.1,0.9,0.1,0.9),
(0.1,0.9,0.9,0.1),(0.1,0.9,0.9,0.9),(0.9,0.1,0.1,0.1),(0.9,0.1,0.1,0.9),
(0.9,0.1,0.9,0.1),(0.9,0.1,0.9,0.9),(0.9,0.9,0.1,0.1),(0.9,0.9,0.1,0.9),
(0.9,0.9,0.9,0.1),(0.9,0.9,0.9,0.9));
n_in:integer=320;
begin
k:=strtoint(recognizeedit.Text);
momentum:=strtofloat(m_a.Text );
min_ex:=strtofloat(m_ex.Text );
eta:=strtofloat(m_eta.Text );
n_hidden:=strtoint(m_hn.Text );
setlength(data_in,charimage.Width*charimage.height);
setlength(data_out,digitalcount,4);
data_in:=rcode(Img,charimage.width,charimage.height );
//for i:=0 to digitalcount-1 do //输出节点值赋值
for j:=0 to 3 do
data_out[k,j]:=A[k,j];
//训练BP网络
// BPreTrain(Data_in, Data_out, n_in, n_hidden,min_ex, momentum, eta);
end;
procedure TBPTrainForm.StandardImageClick(Sender: TObject);
var
i,j,k,m:integer;
w,h:integer;
s:D2Array;
Data:D1Array;
max:double;
// rect:Trect;
E:WideString;
t:string;
bmp:tbitmap;
xmin,xmax,ymin,ymax:integer;
ps: pbytearray;
begin
bmp:=tbitmap.Create;
bmp.Assign(charimage.Picture.Bitmap);
bmp.Width:=charimage.width;
bmp.Height:=charimage.height;
// xmin:=0;
// xmax:=0;
// ymin:=0;
// ymax:=0;
// for j:=0 to bmp.height-1 do begin
// ps:=bmp.ScanLine[j];
// for i:=0 to bmp.width-1 do
// if ps[3*i]=0 then begin
// if ymin=0 then begin
// ymin:=j;
// xmin:=i;
// end;
// if xmin>=i then
// xmin:=i;
// end;
// end;
// for j:=bmp.height-1 downto 0 do begin
// ps:=bmp.ScanLine[j];
// for i:=bmp.width-1 downto 0 do
// if ps[3*i]=0 then begin
// if ymax=0 then begin
// ymax:=j;
// xmax:=i;
// end;
// if xmax<=i then
// xmax:=i;
// end;
// end;
// stdimg.Width:=xmax-xmin;
// stdimg.Height:=ymax-ymin;
// charimage.Picture.Bitmap.empty;
// stdimg.Canvas.CopyRect(rect(0,0,xmax-xmin,ymax-ymin),
// bmp.canvas,rect(xmin,ymin,xmax,ymax));
// edit1.Text:=inttostr(xmin) inttostr(xmax) inttostr(ymin) inttostr(ymax);
// label7.Caption:=inttostr(img.Height);
// listbox1.Items.Clear;
// listbox1.Items.Add(inttostr(xmin));
// listbox1.Items.Add(inttostr(xmax));
// listbox1.Items.Add(inttostr(ymin));
// listbox1.Items.Add(inttostr(ymax));
bmp.Free;
img.Width:= 80;
img.height:=160;
for i:=0 to img.Width-1 do
for j:=0 to img.Height-1 do
img.Canvas.Pixels[i,j]:=clWhite;
w:=img.Width mod charimage.width;
charimage.Width:=charimage.Width w;
w:=img.Width div charimage.width;
h:=img.Height mod charimage.height;
charimage.Height :=charimage.Height h;
h:= img.Height div charimage.height;
for i:=0 to charimage.Width do
for j:=0 to charimage.Height do
begin
if charimage.Canvas.Pixels[i,j]=clBlack then
begin
for k:=1 to w do
for m:=1 to h do
img.Canvas.Pixels[i*w k,j*h m]:=clBlack;
// Canvas.CopyMode := cmSrcCopy;
// img.Canvas.CopyRect(rect(0,0,190,220),charimage.canvas,rect(0,0,charimage.Width,charimage.Height));
end;
end;
end;
procedure TBPTrainForm.PropertyGetButtonClick(Sender: TObject);
var
i,j,k:integer;
w,h:integer;
s:array[1..8]of array[1..16] of integer;
Data:array[1..8]of array[1..16] of real;
max:double;
rect:Trect;
E:WideString;
t:string;
begin
memo1.Clear ;
k:=0;
img.Width:= 80;
img.height:=160;
//setlength(s,8,16);
// setLength(data,8*16);
max:=0;
for i:=1 to 8 do
for j:=1 to 16 do
begin
rect.Left :=10*(i-1);
rect.Top :=10*(j-1);
rect.Right :=rect.Left 10-1;
rect.Bottom :=rect.Top 10-1;
s[i,j]:=statistic(rect,img);
if s[i,j]>max then
max:=s[i,j];
end;
for j:=1 to 16 do
begin
for i:=1 to 8 do
begin
if s[i,j]/max >0.2 then
Data[i,j]:=0.9
else
Data[i,j]:=0.1;
end;
end;
t:='';
for j:=1 to 16 do
begin
t:=' ';
for i:=1 to 8 do
begin
if Data[i,j]>=0.8 then
t:= t '1' ' ' ;
if (Data[i,j]<=0.2) then
t:= t '0' ' ' ;
end;
memo1.Lines.Add(t);
end;
// result:=Data;
end;
procedure TBpTrainForm.SelectionSort(var a: array of integer);
var
i, j, t: integer;
begin
for i := low(a) to high(a) - 1 do
for j := high(a) downto i 1 do
if a[i] > a[j] then
begin
//交换值(a[i], a[j], i, j);
t := a[i];
a[i] := a[j];
a[j] := t;
end;
end;
procedure TBpTrainForm.GetRegion(Bmp: TBitmap);
var
i,j,min,max:integer;
minarray,maxarray,ytemp:array of integer;
l,r,t,b:integer;
begin
setlength(minarray,Bmp.Height);
setlength(maxarray,Bmp.Height);
setlength(ytemp,Bmp.Height);
for j:=0 to Bmp.Height-1 do
begin
for i:=0 to Bmp.Width-1 do
begin
if Bmp.Canvas.Pixels[i,j]=clwhite then
begin
if i=minarray[j] then inc(minarray[j]);
end;
end;
if minarray[j]=Bmp.Width then Continue;
for i:=Bmp.Width-1 downto 0 do
begin
if Bmp.Canvas.Pixels[i,j]=clwhite then
begin
if i 1=Bmp.Width-maxarray[j] then inc(maxarray[j]);
end;
end;
end;
for i:=0 to Bmp.Height-1 do ytemp[i]:=minarray[i];
selectionsort(minarray);
selectionsort(maxarray);
min:=minarray[0];
i:=-1;
repeat
inc(i);
max:=maxarray[i];
until(max<>0);
l:=min-1;
r:=Bmp.Width-max;
for i:=0 to Bmp.Height-2 do
begin
if ((ytemp[i]=Bmp.Width) and (ytemp[i 1]<>Bmp.Width)) then t:=i;
if ((ytemp[i]<>Bmp.Width) and (ytemp[i 1]=Bmp.Width)) then b:=i 1;
end;
CreateBmp(l,r 2,t,b 2);
// CreateBmp(l,r 2,t,b 2);
end;
procedure TBpTrainForm.CreateBmp(Left,Right,Top,Bottom: integer);
var
p1,p2:pbytearray;
x,y,r,g,b,n,gray:integer;
bmp:Tbitmap;
s,t:string;
begin
bmp:=Tbitmap.Create;
bmp.PixelFormat:=charimage.Picture.Bitmap.PixelFormat;
bmp.Width:=Right-Left-1;
bmp.Height:=Bottom-Top-1;
for y:=top 1 to bottom-1 do
begin
for x:=left 1 to right-1 do
begin
if charimage.Canvas.Pixels[x,y]=clwhite then bmp.Canvas.Pixels[(x-Left-1),(y-Top-1)]:=clwhite;
if charimage.Canvas.Pixels[x,y]=clblack then bmp.Canvas.Pixels[(x-Left-1),(y-Top-1)]:=clblack;
end;
end;
image1.Picture.Bitmap.Assign(Bmp);
end;
procedure TBPTrainForm.Zoom;
var
Mybmp: TBitmap;
begin
self.DoubleBuffered := True;
Mybmp := TBitmap.Create;
Mybmp.Width := 49;
Mybmp.Height := 57;
NormalImage.Width := Mybmp.Width;
NormalImage.Height := MyBmp.Height;
SetStretchBltMode(Mybmp.Canvas.Handle, HalfTone);
Stretchblt(Mybmp.Canvas.Handle, 0, 0, Mybmp.Width,
Mybmp.Height, image1.Canvas.Handle, 0, 0, image1.Picture.Bitmap.Width,
image1.Picture.Bitmap.Height,
SRCCOPY);
Mybmp.PixelFormat := pf24bit;
//MyBmp.Assign(newbmp);
NormalImage.Picture.Bitmap.Assign(MyBmp);
// showform.ShowModal;
MyBmp.Free;
end;
procedure TBPTrainForm.RecognizeInCharClick(Sender: TObject);
begin
RecognizeCharInPicture:=false;
RecognizeChar(Sender);
end;
procedure TBPTrainForm.PatternButtonClick(Sender: TObject);
var
momentum,min_ex,eta:double;
n_hidden,digitalcount:integer;
data_in:d1array;
data_out:D2Array;
i,j:integer;
E:WideString;
k:integer;
const
A:array[0..15] of array[0..3] of double=((0.1,0.1,0.1,0.1),(0.1,0.1,0.1,0.9),
(0.1,0.1,0.9,0.1),(0.1,0.1,0.9,0.9),(0.1,0.9,0.1,0.1),(0.1,0.9,0.1,0.9),
(0.1,0.9,0.9,0.1),(0.1,0.9,0.9,0.9),(0.9,0.1,0.1,0.1),(0.9,0.1,0.1,0.9),
(0.9,0.1,0.9,0.1),(0.9,0.1,0.9,0.9),(0.9,0.9,0.1,0.1),(0.9,0.9,0.1,0.9),
(0.9,0.9,0.9,0.1),(0.9,0.9,0.9,0.9));
n_in:integer=320;
begin
k:=strtoint(recognizeedit.Text);
momentum:=strtofloat(m_a.Text );
min_ex:=strtofloat(m_ex.Text );
eta:=strtofloat(m_eta.Text );
n_hidden:=strtoint(m_hn.Text );
setlength(data_in,charimage.Width*charimage.height);
setlength(data_out,digitalcount,4);
data_in:=rcode(Img,charimage.width,charimage.height );
//for i:=0 to digitalcount-1 do //输出节点值赋值
for j:=0 to 3 do
data_out[k,j]:=A[k,j];
//训练BP网络
// BPreTrain(Data_in, Data_out, n_in, n_hidden,min_ex, momentum, eta);
end;
评论