Dans le cas de la reconnaissance au niveau des champs, de courts fragments de texte sont reconnus afin de capturer les données de certains champs. La qualité de la reconnaissance est cruciale dans ce scénario.Ce scénario peut également être utilisé dans le cadre de scénarios plus complexes, dans lesquels des données pertinentes doivent être extraites de documents (par exemple, pour capturer des données de documents papier dans des systèmes d’information et des bases de données, ou pour classer et indexer automatiquement des documents dans des systèmes de gestion documentaire).Dans ce scénario, le système reconnaît soit plusieurs lignes de texte dans certains champs seulement, soit l’intégralité du texte sur une image de petite taille. Le système calcule un indice de confiance pour chaque caractère reconnu. Les indices de confiance peuvent ensuite être utilisés lors de la vérification des résultats de reconnaissance. En outre, le système peut stocker plusieurs variantes de reconnaissance pour les mots et les caractères du texte, qui peuvent ensuite être utilisées dans des algorithmes de vote afin d’améliorer la qualité de la reconnaissance.Le traitement de petits fragments de texte dans ce scénario diffère à certains égards des étapes correspondantes dans d’autres scénarios :
Prétraitement des images numérisées ou des photos
Les images à reconnaître peuvent inclure des marquages et du bruit de fond, qui peuvent tous deux nuire à la reconnaissance. C’est pourquoi tout marquage indésirable et tout bruit de fond sont supprimés à cette étape.
Reconnaissance de petits fragments de texte
Lors de la reconnaissance de petits fragments de texte, le type de données à reconnaître est connu à l’avance. Par conséquent, la qualité de la reconnaissance peut être améliorée grâce à l’utilisation de dictionnaires externes, d’expressions régulières, de langues de reconnaissance et d’alphabets personnalisés, ainsi qu’en imposant des restrictions sur le nombre de caractères dans une chaîne. Les champs de texte peuvent contenir du texte imprimé, manuscrit en lettres détachées et manuscrit cursif.
Travail avec les données reconnues
Ce scénario exige une précision de reconnaissance maximale afin de réduire au minimum le travail de vérification des données. Le système peut calculer un indice de confiance pour chaque mot ou caractère reconnu et fournir plusieurs variantes de reconnaissance, parmi lesquelles plusieurs Engines peuvent ensuite choisir le meilleur candidat en appliquant des algorithmes de vote.
Les exemples de code fournis dans cette section sont spécifiques à Windows.
Vous trouverez ci-dessous une description détaillée de la méthode recommandée pour utiliser ABBYY FineReader Engine 12 dans ce scénario. Cette méthode repose sur les paramètres de traitement jugés les plus adaptés à ce scénario.
Étape 1. Chargement d’ABBYY FineReader Engine
Pour commencer à utiliser ABBYY FineReader Engine, vous devez créer l’objet Engine. L’objet Engine est l’objet de plus haut niveau dans la hiérarchie des objets ABBYY FineReader Engine ; il fournit divers paramètres globaux, certaines méthodes de traitement, ainsi que des méthodes permettant de créer les autres objets.Pour créer l’objet Engine, vous pouvez utiliser la fonction InitializeEngine. Consultez également les autres façons de charger l’objet Engine (Win).
public class EngineLoader : IDisposable{ public EngineLoader() { // Initialisez ces variables avec le chemin complet vers FREngine.dll, votre Customer Project ID, // et, le cas échéant, le chemin vers votre fichier de jeton de licence en ligne et le mot de passe de la licence en ligne string enginePath = ""; string customerProjectId = ""; string licensePath = ""; string licensePassword = ""; // Chargement de la bibliothèque FREngine.dll dllHandle = LoadLibraryEx(enginePath, IntPtr.Zero, LOAD_WITH_ALTERED_SEARCH_PATH); try { if (dllHandle == IntPtr.Zero) { throw new Exception("Impossible de charger " + enginePath); } IntPtr initializeEnginePtr = GetProcAddress(dllHandle, "InitializeEngine"); if (initializeEnginePtr == IntPtr.Zero) { throw new Exception("Impossible de trouver la fonction InitializeEngine"); } IntPtr deinitializeEnginePtr = GetProcAddress(dllHandle, "DeinitializeEngine"); if (deinitializeEnginePtr == IntPtr.Zero) { throw new Exception("Impossible de trouver la fonction DeinitializeEngine"); } IntPtr dllCanUnloadNowPtr = GetProcAddress(dllHandle, "DllCanUnloadNow"); if (dllCanUnloadNowPtr == IntPtr.Zero) { throw new Exception("Impossible de trouver la fonction DllCanUnloadNow"); } // Conversion des pointeurs en délégués initializeEngine = (InitializeEngine)Marshal.GetDelegateForFunctionPointer( initializeEnginePtr, typeof(InitializeEngine)); deinitializeEngine = (DeinitializeEngine)Marshal.GetDelegateForFunctionPointer( deinitializeEnginePtr, typeof(DeinitializeEngine)); dllCanUnloadNow = (DllCanUnloadNow)Marshal.GetDelegateForFunctionPointer( dllCanUnloadNowPtr, typeof(DllCanUnloadNow)); // Appel de la fonction InitializeEngine // en transmettant le chemin vers le fichier de licence en ligne et le mot de passe de la licence en ligne int hresult = initializeEngine(customerProjectId, licensePath, licensePassword, "", "", false, ref engine); Marshal.ThrowExceptionForHR(hresult); } catch (Exception) { // Libération de la bibliothèque FREngine.dll engine = null; // Suppression de tous les objets avant l'appel à FreeLibrary GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); FreeLibrary(dllHandle); dllHandle = IntPtr.Zero; initializeEngine = null; deinitializeEngine = null; dllCanUnloadNow = null; throw; } } // Fonctions de Kernel32.dll [DllImport("kernel32.dll")] private static extern IntPtr LoadLibraryEx(string dllToLoad, IntPtr reserved, uint flags); private const uint LOAD_WITH_ALTERED_SEARCH_PATH = 0x00000008; [DllImport("kernel32.dll")] private static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName); [DllImport("kernel32.dll")] private static extern bool FreeLibrary(IntPtr hModule); // Fonctions de FREngine.dll [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode)] private delegate int InitializeEngine(string customerProjectId, string licensePath, string licensePassword, string tempFolder, string dataFolder, bool isSharedCPUCoresMode, ref FREngine.IEngine engine); [UnmanagedFunctionPointer(CallingConvention.StdCall)] private delegate int DeinitializeEngine(); [UnmanagedFunctionPointer(CallingConvention.StdCall)] private delegate int DllCanUnloadNow(); // Variables privées private FREngine.IEngine engine = null; // Handle vers FREngine.dll private IntPtr dllHandle = IntPtr.Zero; private InitializeEngine initializeEngine = null; private DeinitializeEngine deinitializeEngine = null; private DllCanUnloadNow dllCanUnloadNow = null;}
// Initialisez ces variables avec le chemin vers FREngine.dll, votre Customer Project ID FineReader Engine,// et, le cas échéant, le chemin vers le jeton de licence en ligne et le mot de passe de la licence en lignewchar_t* FreDllPath;wchar_t* CustomerProjectId;wchar_t* LicensePath; // si vous n'utilisez pas de licence en ligne, affectez des chaînes vides à ces variableswchar_t* LicensePassword;// HANDLE vers FREngine.dllstatic HMODULE libraryHandle = 0;// Objet Engine FineReader globalFREngine::IEnginePtr Engine;void LoadFREngine(){ if( Engine != 0 ) { // Déjà chargé return; } // Première étape : charger FREngine.dll if( libraryHandle == 0 ) { libraryHandle = LoadLibraryEx( FreDllPath, 0, LOAD_WITH_ALTERED_SEARCH_PATH ); if( libraryHandle == 0 ) { throw L"Erreur lors du chargement d'ABBYY FineReader Engine"; } } // Deuxième étape : récupérer l'objet Engine typedef HRESULT ( STDAPICALLTYPE* InitializeEngineFunc )( BSTR, BSTR, BSTR, BSTR, BSTR, VARIANT_BOOL, FREngine::IEngine** ); InitializeEngineFunc pInitializeEngine = ( InitializeEngineFunc )GetProcAddress( libraryHandle, "InitializeEngine" ); if( pInitializeEngine == 0 || pInitializeEngine( CustomerProjectId, LicensePath, LicensePassword, L"", L"", VARIANT_FALSE, &Engine ) != S_OK ) { UnloadFREngine(); throw L"Erreur lors du chargement d'ABBYY FineReader Engine"; }}
Étape 2. Chargement des paramètres du scénario
Les paramètres les plus adaptés peuvent être sélectionnés à l’aide de la méthode LoadPredefinedProfile de l’objet Engine. Cette méthode prend le nom du profil en paramètre d’entrée. Vous pouvez sélectionner les paramètres les plus adaptés en utilisant le profil prédéfini FieldLevelRecognition. Pour en savoir plus sur les profils, consultez Working with Profiles.
// Charger un profil prédéfiniEngine->LoadPredefinedProfile( L"FieldLevelRecognition" );
Si vous souhaitez modifier les paramètres utilisés pour le traitement, utilisez les objets Parameter correspondants. Pour plus d’informations, consultez la section Optimisation supplémentaire ci-dessous.
Étape 3. Chargement et prétraitement des images
ABBYY FineReader Engine fournit un objet FRDocument pour traiter les documents multipages. Pour charger les images d’un document et les prétraiter, vous devez créer l’objet FRDocument et y ajouter des images. Vous pouvez procéder de l’une des façons suivantes :
Créez un objet FRDocument à l’aide de la méthode CreateFRDocumentFromImage de l’objet Engine. Cette méthode crée un objet FRDocument et charge les images à partir du fichier spécifié.
// Ouvrir un fichier image et créer l'objet FRDocumentFREngine::IFRDocumentPtr frDocument = Engine->CreateFRDocumentFromImage( L"C:\\MyImage.tif", 0 );
Étape 4. Configuration des champs à reconnaître
Vous devez maintenant créer des blocs contenant vos champs et, pour chacun d’eux, spécifier le type de bloc ainsi que les caractéristiques connues des données qu’il contient.Effectuez l’analyse de la mise en page du document à l’aide de la méthode Analyze, ou ajoutez manuellement des blocs contenant les champs que vous devez reconnaître. Consultez Working with Layout and Blocks pour savoir comment procéder.Pour chaque champ, vous pouvez désormais définir ses propres paramètres de reconnaissance. Par exemple, si un champ contient du texte, utilisez la propriété ITextBlock::RecognizerParams :
définissez le type de texte à l’aide de la propriété TextTypes de l’objet RecognizerParams. Par exemple, si le champ contient des chiffres écrits au format d’un code postal, utilisez le type de texte TT_Index.
définissez la langue à l’aide de la méthode SetPredefinedTextLanguage. L’utilisation de langues prédéfinies spéciales (Windows uniquement) peut être utile si vous connaissez le type d’informations contenues dans le champ. Par exemple, si le champ contient une adresse aux États-Unis, sélectionnez la langue prédéfinie English_US_Address. Cela garantit une reconnaissance plus fiable du texte.
définissez les propriétés SaveCharacterRecognitionVariants et SaveWordRecognitionVariants de l’objet RecognizerParams si vous devez utiliser les variantes de reconnaissance pour vérifier plus en détail le résultat, comme décrit ci-dessous à l’étape 6. Notez que ce paramètre n’est pas disponible pour les textes manuscrits ou écrits à la main en lettres détachées.
// Analyser la mise en page du documentfrDocument.Analyze( null, null, null );// Supposons que nous sachions que le premier bloc// de la mise en page contient une adresse aux États-UnisFREngine.ITextBlock addressBlock = frDocument.Pages[0].Layout.Blocks[0].GetAsTextBlock();FREngine.IRecognizerParams paramsAddressBlock = addressBlock.RecognizerParams;paramsAddressBlock.SetPredefinedTextLanguage( "English_US_Address" );// Activer la collecte des variantes de reconnaissanceparamsAddressBlock.SaveCharacterRecognitionVariants = true;paramsAddressBlock.SaveWordRecognitionVariants = true;// Configurer de la même manière les propriétés des autres blocs de la mise en page...
// Analyser la mise en page du documentfrDocument->Analyze( 0, 0, 0 );// Supposons que nous sachions que le premier bloc// de la mise en page contient une adresse aux États-UnisFREngine::ILayoutBlocksPtr layoutBlocks = frDocument->Pages->Item( 0 )->Layout->Blocks;FREngine::IRecognizerParamsPtr paramsAddressBlock = layoutBlocks->Item( 0 )->GetAsTextBlock()->RecognizerParams;paramsAddressBlock->SetPredefinedTextLanguage( L"English_US_Address" );// Activer la collecte des variantes de reconnaissanceparamsAddressBlock->SaveCharacterRecognitionVariants = VARIANT_TRUE;paramsAddressBlock->SaveWordRecognitionVariants = VARIANT_TRUE;// Configurer de la même manière les propriétés des autres blocs de la mise en page...
Étape 5. Reconnaissance
Comme la mise en page du document a déjà été analysée et modifiée par vos soins, n’appelez pas de nouveau les méthodes d’analyse. Utilisez la méthode Recognize, qui effectue la reconnaissance et la synthèse des pages pour l’ensemble des pages du document. Dans ce scénario, vous devez extraire les données des champs et non exporter le document reconnu ; vous n’aurez donc pas besoin de la synthèse du document.
// Reconnaître le document// Il n'est pas nécessaire de spécifier des paramètres, car ils sont définis par le profil de traitementfrDocument.Recognize( null, null );
// Reconnaître le document// Il n'est pas nécessaire de spécifier des paramètres, car ils sont définis par le profil de traitementfrDocument->Recognize( 0, 0 );
Étape 6. Utilisation des données reconnues
Utilisez l’objet Text pour accéder au fragment de texte reconnu (vous pouvez obtenir cet objet pour un bloc de texte via la propriété ITextBlock::Text). Utilisez la propriété Paragraphs pour obtenir la collection de paragraphes du fragment, ainsi que la méthode IParagraphs::Item pour accéder aux paragraphes individuels. La propriété IParagraph::Text donne accès au texte reconnu d’un paragraphe.Vous pouvez utiliser IParagraph::Words pour obtenir la collection de mots d’un paragraphe. Utilisez la méthode IWords::Item pour accéder aux mots individuels de la collection. La propriété IWord::Text renvoie la ligne qui contient le mot reconnu. Utilisez la méthode GetRecognitionVariants de l’objet Word ou la méthode GetWordRecognitionVariants de l’objet Paragraph pour obtenir les variantes de reconnaissance d’un mot.Les attributs de chaque caractère sont accessibles via la méthode GetCharParams de l’objet Paragraph. Cette méthode donne accès à l’objet CharParams, qui contient les paramètres du caractère reconnu. Les variantes de reconnaissance d’un caractère sont accessibles via la propriété ICharParams::CharacterRecognitionVariants.Pour des informations détaillées sur l’utilisation du texte, consultez Utilisation du texte. Pour en savoir plus sur l’utilisation de l’Engine dans les algorithmes de vote, consultez Utilisation de l’API Voting.Une fois que vous avez terminé de travailler avec l’objet FRDocument, libérez toutes les ressources utilisées par cet objet. Utilisez la méthode IFRDocument::Close.
Étape 7. Déchargement d’ABBYY FineReader Engine
Une fois que vous avez fini d’utiliser ABBYY FineReader Engine, vous devez décharger l’objet Engine. Pour cela, utilisez la fonction exportée DeinitializeEngine.
Vous pouvez utiliser le fichier FREngineDistribution.csv pour créer automatiquement une liste des fichiers nécessaires au fonctionnement de votre application. Pour le traitement dans ce scénario, sélectionnez dans la colonne 5 (RequiredByModule) les valeurs suivantes :CoreCore.ResourcesOpeningOpening, ProcessingProcessingProcessing.OCRProcessing.OCR, Processing.ICRProcessing.OCR.NaturalLanguagesProcessing.OCR.NaturalLanguages, Processing.ICR.NaturalLanguagesSi vous modifiez le scénario standard, adaptez les modules requis en conséquence. Vous devez également spécifier les langues de l’interface, les langues de reconnaissance et toutes les fonctionnalités supplémentaires utilisées par votre application (par exemple, Opening.PDF si vous devez ouvrir des fichiers PDF, ou Processing.OCR.CJK si vous devez reconnaître des textes en langues CJK). Consultez Working with the FREngineDistribution.csv File pour plus de détails.
Voici les sections du fichier d’aide où vous trouverez des informations complémentaires sur la configuration des paramètres des différentes étapes de traitement :
Reconnaissance
Utilisation des langues Utilisation des langues de reconnaissance intégrées et personnalisées.
Langues prédéfinies spéciales dans ABBYY FineReader Engine - Windows Liste des langues de reconnaissance qui contiennent des unités linguistiques spéciales : adresses, date et heure, noms de personnes, etc. Ces langues peuvent être utilisées pour la reconnaissance des champs.
Utilisation des données reconnues
Utilisation du texte Utilisation du texte reconnu, des paragraphes, des mots et des caractères.