2009-08-11 7 views
2

Ich habe einen Scan eines Dokuments (ein Formular tatsächlich) mit einigen handgeschriebenen Informationen gefüllt.Suchen Sie ein Bild in einem Bild C#

Ich habe eine Bitmap des Formulars leer.

Wie kann ich das gedruckte Formular "abbrechen", um nur die Handschrift zu extrahieren.

verwende ich C# ... Dank Jonathan

Antwort

4

Was Sie tun möchten, ist das leere Formular Bild aus dem Bild des Formulars mit der Handschrift in ihm subtrahiert. Dies gibt Ihnen ein vernünftiges Bild der Handschrift allein.

Bitte beachten Sie, dass dies die Bilder nicht registriert. Die Registrierung wird sie so ausrichten, dass sie identische Orientierungen haben, um der Subtraktion die beste Erfolgschance zu geben. Wenn Ihre Bilder schlecht ausgerichtet sind, müssen Sie in die Bildregistrierung schauen. etwas Ähnliches zu tun (dieser Code markiert die Unterschiede in rot)

Hier ist ein Code-Snippet ich eine Weile zurück schrieb:

 Bitmap b1 = new Bitmap(fname1); 
     Bitmap b2 = new Bitmap(fname2); 

     if (b1.Height != b2.Height || b1.Width != b2.Width) { 
      MessageBox.Show("Input files are not the same dimensions!"); 
      Application.Exit(); 
     } 

     totalPixels = b1.Height * b1.Width * 4; 

     Bitmap outImg = new Bitmap(b1.Width, b1.Height, System.Drawing.Imaging.PixelFormat.Format32bppRgb); 

     BitmapData b1Data = b1.LockBits(new Rectangle(0, 0, b1.Width, b1.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppRgb); 
     BitmapData b2Data = b2.LockBits(new Rectangle(0, 0, b1.Width, b1.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppRgb); 
     BitmapData oData = outImg.LockBits(new Rectangle(0, 0, b1.Width, b1.Height), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppRgb); 

     byte[] cur1 = new byte[b1Data.Stride * b1Data.Height]; 
     byte[] cur2 = new byte[b2Data.Stride * b2Data.Height]; 
     byte[] curOut = new byte[b2Data.Stride * b2Data.Height]; 

     Marshal.Copy(b1Data.Scan0, cur1, 0, b1Data.Stride * b1Data.Height); 
     Marshal.Copy(b2Data.Scan0, cur2, 0, b2Data.Stride * b2Data.Height); 

     for (int i = 0; i < b1Data.Stride * b1Data.Height; i += 4) { 
      byte temp1 = cur1[i], temp2 = cur2[i], first = 0, second = 0; 
      curOut[i] = 0; 
      first = (byte) ((temp1 > temp2) ? temp1 - temp2 : temp2 - temp1); 

      temp1 = cur1[i + 1]; 
      temp2 = cur2[i + 1]; 
      curOut[i + 1] = 0; 
      second = (byte) ((temp1 > temp2) ? temp1 - temp2 : temp2 - temp1); 

      temp1 = cur1[i + 2]; 
      temp2 = cur2[i + 2]; 
      curOut[i + 2] = (byte) ((temp1 > temp2) ? temp1 - temp2 : temp2 - temp1); 
      curOut[i + 2] = (byte) ((first + second + curOut[i + 2]) * 255); 

      curPixel = i; 
     } 

     Marshal.Copy(curOut, 0, oData.Scan0, b2Data.Stride * b2Data.Height); 

     b1.UnlockBits(b1Data); 
     b2.UnlockBits(b2Data); 
     outImg.UnlockBits(oData); 

     outImg.Save(outfile); 
+0

danke ... eine Frage ist aber, dass alles muß perfekt ausgerichtet werden ... –

+1

Ja, siehe meinen bearbeiten zur Anmeldung. Wenn Sie Bilder haben, die sehr nah sind, kann die Registrierung so einfach sein wie das Anwenden einer kleinen Drehung oder das Ändern des Histogramms. Wenn sie weiter auseinander liegen, müssen Sie sie in einen einheitlichen Raum projizieren, um sie zu vergleichen. –

+0

Sid. Was ist Bildregistrierung? Kannst du mir etwas dazu sagen? Haben Sie versucht, auch den Text wiederzuerkennen? Danke! –

3

Als Alternative (und möglicherweise viel schnellere Methode) können Sie nicht nur die Speicherung Rectangle psoitions von wo die "Felder" sein werden, dann extrahieren Sie einfach die Pixel für jedes Rechtecke?

Darknight

+0

das mag eine gute Lösung sein, aber die Leute schreiben selten an der richtigen Stelle –

+0

Kann funktionieren, wenn die gescannten Dokumente immer auf die gleiche Weise ausgerichtet sind. Punkte zur Vereinfachung. +1 –

+0

Auch eine gute Methode, kann es einfacher sein, rechteckige Regionen auf die Feldbereiche auszurichten, als das gesamte Formular auszurichten. Einfache Heuristiken könnten Fragmente am Rand des Rechtecks ​​eliminieren und möglicherweise erweitern, wenn der Text als "abgeschnitten" angesehen wird. –