2012-12-22 104 views
7

我试图在C#与Aforge.Net感知,使OCR。我用九个30 * 30的二进制图片学习了我的网络。但是在结果中,它将一切都视为'C'。 这是代码:OCR与Aforge.net的感知神经网络错答案

private void button1_Click(object sender, EventArgs e) 
    { 
     AForge.Neuro.ActivationNetwork network = new AForge.Neuro.ActivationNetwork(new AForge.Neuro.BipolarSigmoidFunction(2), 900, 3); 
     network.Randomize(); 
     AForge.Neuro.Learning.PerceptronLearning learning = new AForge.Neuro.Learning.PerceptronLearning(network); 
     learning.LearningRate =1 ; 
     double[][] input = new double[9][]; 
     for (int i = 0; i < 9; i++) 
     { 
      input[i] = new double[900]; 
     } 
    //Reading A images 
     for (int i = 1; i <= 3; i++) 
     { 
      Bitmap a = AForge.Imaging.Image.FromFile(path + "\\a" + i + ".bmp"); 
      for (int j = 0; j < 30; j++) 
       for (int k = 0; k < 30; k++) 
       { 
        if (a.GetPixel(j, k).ToKnownColor() == KnownColor.White) 
        { 
         input[i-1][j * 10 + k] = -1; 
        } 
        else 
         input[i-1][j * 10 + k] = 1; 
       } 
      // showImage(a); 

     } 
    //Reading B images 
     for (int i = 1; i <= 3; i++) 
     { 
      Bitmap a = AForge.Imaging.Image.FromFile(path + "\\b" + i + ".bmp"); 
      for (int j = 0; j < 30; j++) 
       for (int k = 0; k < 30; k++) 
       { 
        if (a.GetPixel(j , k).ToKnownColor() == KnownColor.White) 
        { 
         input[i + 2][j * 10 + k] = -1; 
        } 
        else 
         input[i + 2][j * 10 + k] = 1; 
       } 
      // showImage(a); 

     } 
    //Reading C images 
     for (int i = 1; i <= 3; i++) 
     { 
      Bitmap a = AForge.Imaging.Image.FromFile(path + "\\c" + i + ".bmp"); 
      for (int j = 0; j < 30; j++) 
       for (int k = 0; k < 30; k++) 
       { 
        if (a.GetPixel(j , k).ToKnownColor() == KnownColor.White) 
        { 
         input[i + 5][j * 10 + k] = -1; 
        } 
        else 
         input[i + 5][j * 10 + k] = 1; 
       } 
      // showImage(a); 

     } 

     bool needToStop = false; 
     int iteration = 0; 
     while (!needToStop) 
     { 
      double error = learning.RunEpoch(input, new double[9][] { new double[3] { 1, -1, -1 },new double[3] { 1, -1, -1 },new double[3] { 1, -1, -1 },//A 
       new double[3] { -1, 1, -1 },new double[3] { -1, 1, -1 },new double[3] { -1, 1, -1 },//B 
       new double[3] { -1, -1, 1 },new double[3] { -1, -1, 1 },new double[3] { -1, -1, 1 } }//C 
        /*new double[9][]{ input[0],input[0],input[0],input[1],input[1],input[1],input[2],input[2],input[2]}*/ 
       ); 
      //learning.LearningRate -= learning.LearningRate/1000; 
      if (error == 0) 
       break; 
      else if (iteration < 1000) 
       iteration++; 
      else 
       needToStop = true; 
      System.Diagnostics.Debug.WriteLine("{0} {1}", error, iteration); 
     } 
     Bitmap b = AForge.Imaging.Image.FromFile(path + "\\b1.bmp"); 
    //Reading A Sample to test Netwok 
     double[] sample = new double[900]; 
     for (int j = 0; j < 30; j++) 
      for (int k = 0; k < 30; k++) 
      { 
       if (b.GetPixel(j , k).ToKnownColor() == KnownColor.White) 
       { 
        sample[j * 30 + k] = -1; 
       } 
       else 
        sample[j * 30 + k] = 1; 
      } 
     foreach (double d in network.Compute(sample)) 
      System.Diagnostics.Debug.WriteLine(d);//Output is Always C = {-1,-1,1} 
    } 

我真的很想知道它为什么会出错。

+0

嗨,你有没有找到一个解决这个问题? –

回答

3

加载您最初的30×30图像转换成在input结构的双[900]数组您使用以下的计算:

for (int j = 0; j < 30; j++) 
    for (int k = 0; k < 30; k++) 
    { 
     if (a.GetPixel(j, k).ToKnownColor() == KnownColor.White) 
      input[i-1][j * 10 + k] = -1; 
     else 
      input[i-1][j * 10 + k] = 1; 
    } 

你的偏移量计算是错在这里。您需要更改j * 10 + kj * 30 + k或者你会得到无效的结果。稍后在加载测试图像时使用正确的偏移量计算,这就是为什么它不能正确匹配损坏的样本。

你应该写为位图加载到double[900]阵列,并调用它对于每个图像,而不是相同的代码多次写入的方法。这有助于减少像这样的问题,其中由两段代码给出不同的结果,应该返回相同的结果。

1

我想你的代码。它也帮助了我,并为此感谢了很多。我可以通过对图像中的位数进行一些更改来让代码正常工作。这是我使用的方法。

` 
     private double[] GetImageData(Bitmap bmp) 
     { 
     double[] imageData = null; 

     //Make the image grayscale 
     Grayscale filter = new Grayscale(0.2125, 0.7154, 0.0721); 
     bmp = filter.Apply(bmp); 

     //Binarize the image 
     AForge.Imaging.Filters.Threshold thFilter = new AForge.Imaging.Filters.Threshold(128); 
     thFilter.ApplyInPlace(bmp); 

     int height = bmp.Height; 
     int width = bmp.Width; 
     imageData = new double[height * width]; 
     int imagePointer = 0; 
     System.Diagnostics.Debug.WriteLine("Height : " + height); 
     System.Diagnostics.Debug.WriteLine("Width : " + width); 

     for (int i = 0; i < height; i++) 
     { 
      for (int j = 0; j < width; j++) 
      { 
       System.Diagnostics.Debug.Write(string.Format("({0} , {1})  Color : {2}\n", i, j, bmp.GetPixel(i, j))); 

       //Identify the black points of the image 
       if (bmp.GetPixel(i, j) == Color.FromArgb(255, 0, 0, 0)) 
       { 
        imageData[imagePointer] = 1; 
       } 
       else 
       { 
        imageData[imagePointer] = 0; 
       } 
       imagePointer++; 
      } 
      System.Diagnostics.Debug.WriteLine(""); 
     } 
     System.Diagnostics.Debug.WriteLine("Bits : " + imagePointer); 
     return imageData; 
    }` 

希望这会有所帮助。谢谢。

0

尝试这种

double error = learning.RunEpoch(input, new double[9][] { new double[3] **{ 1, -1, -1 }**,new double[3] **{ -1, 1, -1 }**,new double[3] **{ -1, -1, 1 }**,//A 
       new double[3] **{ 1, -1, -1 }**,new double[3] **{ -1, 1, -1 }**,new double[3] **{ -1, -1, 1 }**,//B 
       new double[3] **{ 1, -1, -1 }**,new double[3] **{ -1, 1, -1 }**,new double[3] **{ -1, -1, 1 }** }//C 

       ); 

或这样

double[][] output = new double[patterns][]; 
      for (int j = 0; j < patterns; j++) 
      { 
       output[j] = new double[patterns]; 
       for (int i = 0; i < patterns; i++) 
       { 
        if (i != j) 
        { 
         output[j][i] = -1; 
        } 
        else 
        { 
         output[j][i] = 1; 
        } 
       } 
      } 


double error = learning.RunEpoch(input,output) 

double[] netout = neuralNet.Compute(pattern); 

int maxIndex = 0; 
      double max = netout[0]; 

      for (int i = 1; i < netout.Length; i++) 
      { 
       if (netout[i] > max) 
       { 
        max = netout[i]; 
        maxIndex = i; 
       } 
      } 

如果maxIndex = 0答案是A

如果maxIndex = 1答案为B

如果maxIndex = 2的答案是C

也是我认为你必须从图像中创建矩阵,并把它作为图案,例如20/20或15/15或小,你的30/30大。

我用来获取图像格式不同的方式。 我划分图像20/20和如果其中一个像素矩形是黑色(或其他颜色,你想)保存1矩阵,否则0.

我做了替换所有像素后,我只有两种颜色,白色和黑色,我可以用轮廓操纵。

private void Cmd_ReplaceColors(ref WriteableBitmap Par_WriteableBitmap,int Par_Limit=180) 
     { 

      for (int y = 0; y < Par_WriteableBitmap.PixelHeight; y++) 
      { 
       for (int x = 0; x < Par_WriteableBitmap.PixelWidth; x++) 
       { 

        Color color = Par_WriteableBitmap.GetPixel(x, y); 

        if (color == Colors.White) 
        { 

        } 
        else 
        { 
         if (color.R < Par_Limit) 
         { 
          Par_WriteableBitmap.SetPixel(x, y, Colors.Black); 
         } 
         else 
         { 
          Par_WriteableBitmap.SetPixel(x, y, Colors.White); 
         } 

        } 

       } 
      } 

      Par_WriteableBitmap.Invalidate(); 
     } 

1000次迭代在我看来是小,更好地100 000 :)