image2data

Der Tech-Blog

...weitermachen, wo OCR aufhört

Plugin "Mustererkennung" (i2dxPattRec)

Feb 282015

Über das image2data-Plugin "Mustererkennung" (i2dxPattRec) können graphische Objekte miteinander verglichen werden. Ein Beispiel hierfür ist das Finden von Kundenlogos auf einem Dokument. Hierzu werden die Klassifikatoren der möglichen Objekte (in dem Beispiel für die Kundenlogos) einmalig berechnet und später in der Verarbeitung auf den eingehenden Belegen gesucht. Je geringer die Distanz zwischen bekanntem Objekt und dem gefundenen, desto ähnlicher sind sie sich. Die in diesem Plugin implementierte Mustererkennung ist spiegelungs-, rotations- und größeninvariant, d.h. das Vergleichsergebnis wird durch die vorgenannten Faktoren nicht beeinflusst.

Das folgende Skript berechnet die Klassifikatoren für den Buchstaben "D" auf einem Beispielbeleg. Anschließend wird über alle auf dem Beleg gefundenen Zeichen iteriert und dabei die Klassifikatoren des jeweiligen Zeichens berechnet. Um später ein aussagekräftiges Ergebnis erhalten zu können, muß, nachdem die Berechnungen für alle Zeichen abgeschlossen sind, die Varianz aller Klassifikatoren berechnet werden ("i2dxPattRecCalcVarianceOfMoments").

Nun wird mit dem Befehl "i2dxPattRecCompareWithAllMoments" der Vergleich ausgeführt und dabei das Array "aMomentCompareResults" gefüllt, in dem sich u.a. die Distanz aller Objekte zu dem gesuchten findet. Unterschreitet diese Distanz den Wert aus "MAXALLOWEDDISTANCE", dann wird das Objekt auf dem Beleg mit einem grünen Rechteck markiert.

// ******************************************************************
// * sample_i2dxpattrec.i2dspt                                      *
// *                                                                *
// * Sample script for the i2dxPattRec (pattern recognition) plugin *
// * REQUIRES THE INSTALLED PLUGIN TO COMPILE AND RUN!              *
// *                                                                *
// * Press F9 to execute the code or F7/F8 to debug it              *
// *                                                                *
// * Contact www.norpa.eu if the plugin is required but missing     *
// ******************************************************************
 
{$I i2dxPattRec}
 
const
  NUMBEROFMOMENTS = 24;
  MAXALLOWEDDISTANCE = 0.075;
 
var
  // Declare some variables
  i: Integer;
 
  oPage: TBitmap;
 
  rProcessSettings: Ti2dProcessSettings;
 
  aOCRObjects: Ti2dOCRObjects;
  aSearchedObjectMoments: Ti2dxPattRecMoments;
  aAllMoments: Ti2dxPattRecAllMoments;
  aVarianceOfAllMoments: Ti2dxPattRecMoments;
  aMomentCompareResults: Ti2dxPattRecMomentCompareResults;
 
begin
  // Get the configured process settings. We must know the configured "in"-folder because that's
  // where the sample docs are located in!
  i2dGetProcessSettings(rProcessSettings);
 
  // Create the bitmap object
  oPage := TBitmap.Create;
 
  try
    // Load first page of the image into the bitmap object
    i2dLoadBitmap(rProcessSettings.InPath + 'sample_invoice_1.tif', 1, oPage);
 
    // Get some image objects, starting with a size from 10x10 pixels
    i2dGetBitmapObjects(oPage, 10, 10, 4, 11, 5, 5, 5, 5, 3, aOCRObjects);
 
    // The moments of the objects to search for
    SetLength(aSearchedObjectMoments, NUMBEROFMOMENTS);
    // The moments of all found objects
    SetLength(aAllMoments, Length(aOCRObjects));
    // The variance of the moments of all objects
    SetLength(aVarianceOfAllMoments, NUMBEROFMOMENTS);
    // The resulting ascending sorted moment compare distances and indices
    SetLength(aMomentCompareResults, Length(aOCRObjects));
 
    // Calculate the zernike moments of character "D"; on the sample image using the above settings, it is index 4.
    // In the following lines we will try to find similar objects to this character
    i2dxPattRecCalcZernikeMoments(aOCRObjects[4].Points, aSearchedObjectMoments);
 
    // Calculate the zernike moments of all found objects
    for i := 0 to Length(aOCRObjects) - 1 do begin
      SetLength(aAllMoments[i], NUMBEROFMOMENTS);
      i2dxPattRecCalcZernikeMoments(aOCRObjects[i].Points, aAllMoments[i]);
    end;
 
    // Calculate the variance of the moments of all objects...
    i2dxPattRecCalcVarianceOfMoments(aAllMoments, aVarianceOfAllMoments);
    // ...and compare the calculated moments of the object we want to find with the moments of all objects considering the variance
    i2dxPattRecCompareWithAllMoments(aSearchedObjectMoments, aAllMoments, aVarianceOfAllMoments, aMomentCompareResults);
 
    i2dForceTCBitmap(oPage);
 
    oPage.Canvas.Brush.Color := clGreen;
    oPage.Canvas.Brush.Style := bsBDiagonal;
    oPage.Canvas.Pen.Width := 3;
    oPage.Canvas.Pen.Color := clGreen;
 
    // Iterating over the sorted compare results and draw a rectangle around the best matching objects
    for i := 0 to Length(aMomentCompareResults) - 1 do begin
      if aMomentCompareResults[i].Distance <= MAXALLOWEDDISTANCE then begin
        with aOCRObjects[aMomentCompareResults[i].Index] do
          oPage.Canvas.Rectangle(Left, Top, Left + Width, Top + Height);
        i2dDebugOut(Format('The object with the index %d has a distance of %.4f to the searched object', [aMomentCompareResults[i].Index, aMomentCompareResults[i].Distance]));
      end;
    end;
 
    // And show it
    i2dShowInBitmapViewerB(oPage);
  finally
    // Destroy the bitmap object and release memory
    oPage.Free;
  end;
end.

Atom

powered by Nibbleblog