找传奇、传世资源到传世资源站!

Delphi实现车牌识别

8.5玩家评分(1人评分)
下载后可评
介绍 评论 失效链接反馈

【例子介绍】

通过图像识别技术,对拍摄的车牌照片进行灰化、二值化然后准确读出车牌号。

【相关图片】

from clipboard

【源码结构】

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;

评论

发表评论必须先登陆, 您可以 登陆 或者 注册新账号 !


在线咨询: 问题反馈
客服QQ:174666394

有问题请留言,看到后及时答复