2012-12-22 113 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 :)