Review do ABBYY FlexiCapture Engine


Uma das funcionalidades interessantes da nova versão é a capacidade de configuração rápida para a extração de dados de documentos simples. Esse recurso já é implementado com sucesso no FlexiLayout Studio 10. Além disso, uma API foi adicionada à nova versão do produto, fornecendo acesso programático completo a essa funcionalidade. Elaboramos também uma ferramenta fácil de usar (também disponível na forma de código-fonte), que permite o ajuste em apenas alguns minutos à tarefa do usuário e a criação de um rápido protótipo de trabalho, sem aprofundar-se muito às especificações da tecnologia.

Este artigo foi escrito por desenvolvedores para desenvolvedores, e contará sobre as possibilidades e as limitações dessa tecnologia – algo que você não vai encontrar em materiais de marketing .

Um dos problemas conhecidos dos usuários de tecnologias de captura de dados é o elevado investimento inicial de tempo e esforço para configurar o trabalho com os tipos desejados de imagens. O desenvolvedor-integrador deve aprender a trabalhar com uma variedade de ferramentas e entender as especificações de tecnologias complexas, que muitas vezes não correspondem ao seu perfil de trabalho principal e experiência anterior. Só então ele pode criar um protótipo mais simples e avaliar a eficácia e a viabilidade do projeto inteiro.
A nova ferramenta permite adiar a aquisição de uma familiaridade mais profunda com a tecnologia até a fase de ajuste fino da solução, antes do lançamento, ou mesmo até a segunda versão. Ela não pode substituir um tipo de ferramenta avançada como o FlexiLayout Studio, mas facilita o trabalho em casos simples ou até em casos mais complexos, para chegar rapidamente a um protótipo fácil e funcional.

Para extrair os dados através da API são necessárias apenas algumas linhas de código, dentre as quais podemos ver:

// Cria uma instância do processador e configurá-lo com uma ou mais definições de documentos
 IFlexiCaptureProcessor processor = engine.CreateFlexiCaptureProcessor();
 processor.AddDocumentDefinitionFile( sampleFolder + "Invoice_eng.fcdot" );

Essa linha única de código ajusta o funcionamento para um determinado tipo de documento. A extensão de arquivo FCDOT (modelo de documento FlexiCapture) contém uma descrição dos dados de captura com as limitações escolhidas, o método de encontrar os dados na imagem, as configurações de reconhecimento e, opcionalmente, as configurações de exportação de dados de um documento.

Trabalhar com exemplos torna tudo mais simples – o arquivo necessário de definição de documento já vem em anexo. Mas como conseguir tal definição de documento para a tarefa atual, apenas para “sentir” como vai funcionar?

Antes do lançamento da versão 10, para executar essa tarefa era necessário instalar a versão desktop do FlexiCapture e aprender a trabalhar pelo menos com o editor de identificação de documentos (para trabalho com documentos com uma estrutura rígida e pontos de referência bem definidos). Além disso, na maioria dos mais casos também era necessário aprender a trabalhar com uma ferramenta de especificação flexível de marcação de documentos – o FlexiLayout Studio. Mas mesmo assim temos dúvidas se você conseguiria criar mesmo a versão mais simples da primeira vez, pois quase certamente você precisaria ler cuidadosamente o guia de trabalhos das duas ferramentas ou fazer um treinamento.

Mas o que mudou agora? Agora temos uma fácil ferramenta de exemplos, a Automatic Template Generation, feita sob a forma de assistente e que vai ajudá-lo a obter um protótipo funcional satisfatório dentro de alguns minutos. Vejamos um exemplo de como isso funciona.

Tarefa

Suponha que queiramos criar um aplicativo de registro de notas fiscais em algum sistema de contabilidade e temos várias notas digitalizadas. Selecionaremos as notas do mesmo tipo e tentaremos criar um protótipo de definição de documentos (modelo de documento) para a nossa aplicação.

Já avisamos com a antecedência sobre as possibilidades e limitações:

  • não podemos fazer um modelo universal que funcione bem com notas fiscais aleatórias – nosso modelo vai funcionar bem com mais ou menos o mesmo tipo de notas, é desejável que elas venham a partir de uma única fonte
  • Na versão atual, não podemos descrever as estruturas complexas, como tabelas; para isso você precisará aprender a usar o FlexiLayout Studio
  • mas podemos capturar completamente dados simples como número, data, valor, etc.

Solução

Então, vamos começar. Primeiramente, precisamos de uma pasta com várias (3-5) imagens de interesse para digitalizarmos. Essa será uma pasta com imagens para treinamento (training images). Nesta etapa, é desejável termos imagens de boa qualidade, para que os dados de saída não saiam com “ruídos” e o modelo seja para casos ideais de reconhecimento.

1. Execute o assistente e especifique o caminho para a nossa pasta:

Screen1

2. Escolha o idioma:

Screen2

3. “Desenhamos” os campos de captura e os nomeamos.

Screen3

 

4. Agora, precisamos desenhar os elementos de referência (reference elements). Este é o único passo não trivial em todo o processo. Os elementos de referência – são alguns elementos (fixos) da imagem selecionados estatisticamente (normalmente texto) sobre os quais são pesquisados os campos com conteúdo variável. Normalmente, como no nosso exemplo (veja a imagem), os nomes dos campos são bons candidatos para o papel de elemento de referência.

Screen4

Pra você notar:

  • NB. Não precisa ter o elemento de referência em todos os campos. Isso pode ser uma linha constante em documentos pequenos em relação ao qual os campos são localizados de forma fixa. Não precisa criar elementos demais de referência para não criar confusões desnecessárias. O texto do elemento de referência pode variar, o principal é preservar a semântica. É importante também que o texto seja único – por exemplo, se em um documento estão presentes simultaneamente “Total” e ” Total a pagar”, a palavra “Total” será uma má referência.

5. Em seguida, passamos sequencialmente por todas as imagens em nosso pacote de treinamento e verificamos a marcação. O sistema oferece a opção de marcação para cada imagem obtida a partir dos resultados de treinamento nas imagens já verificadas. Nossa tarefa é corrigir erros: corrigir a geometria dos campos, desenhar os campos não identificados, retirar os desnecessários. No nosso caso, não há erro de aplicação após a primeira imagem, mas há pequenos problemas com o reconhecimento.

Screen5

Pra você notar:

  • NB. Os problemas de identificação acontecem porque nós usamos as configurações padrão de reconhecimento onde poderíamos especificá-las (por exemplo, identificar o tipo de fonte – impressora matricial – e limitar os alfabetos possíveis ou criar uma expressão regular para alguns campos). Na API essa possibilidade já existe agora, mas este instrumento ainda não tem tal funcionalidade ainda.
  • NB. Um campo pode estar ausente em algumas imagens .
  • NB. Através do menu “Template\Modify Language and Fields” é possível retornar à edição do idioma e dos campos a qualquer momento, caso algo tenha sido esquecido.

6. Depois que terminamos o treinamento sobre as imagens selecionadas, vocês são convidados a verificar o padrão resultante. Nós respondemos “sim ” e escolhemos como uma pasta de teste aquela , onde todas as imagens que temos são do tipo desejado.
Na sequência, para cada imagem na pasta são oferecidos os resultados da aplicação. Nossa tarefa é apertar “Succeeded” ou “Failed” para coletar as estatísticas. Se o modelo padrão não foi aplicado sobre alguma imagem, mas a imagem nos parece do tipo desejado, podemos adicioná-la ao pacote para o teste, clicando em “Add current image to the training batch”. Depois de completar o teste será possivel treinar mais as imagens adicionadas e, assim, melhorar o modelo de forma consistente.

Screen6

Pra você notar:

  • NB. Nesta fase, é possível misturar em um pacote de treinamento as imagens de qualidade inferior para conhecer os erros mais comuns, mas é importante não exagerar.
  • NB. É possível interromper o trabalho com o aplicativo a qualquer momento. Ao reiniciar, você pode continuar a partir do ponto onde terminou. Além disso, podemos sempre voltar ao nosso “projeto” se, em uma semana ou um mês, aparecerem novas imagens que queiramos melhorar.

7. Uma vez satisfeitos com o resultado, a última coisa que precisamos fazer é exportar o padrão criado para o arquivo FCDOT onde tudo começou, e voltar a escrever os códigos da nossa aplicação.

Screen7

 

Resultado

Como resultado nós criamos um modelo padrão aplicado na imagem com boa qualidade (superior a 90), mas há alguns problemas com o reconhecimeto do campo, uma vez que não foram levados em conta determinados tipos de fontes e tipos de dados dos campos (data, número, etc.). Para o protótipo , foi muito bom.

Mais uma vez chamamos a atenção que a ferramenta descrita não é universal. Se você precisa de algo unicersal, você não terá outra saída além de aprender a usar o FlexiLayout Studio e a linguagem das descrições flexíveis. Mas para as tarefas realmente simples, como “extrair alguns campos” , esta ferramenta funciona muito bem e te permite obter a solução de maneira mais rápida e fácil.

Um pouco sobre a API

A ferramenta descrita está inteiramente escrita e ao alcance de todos na API, junto ao código-fonte, e os nossos clientes podem modificá-la dependendo das suas necessidades ou usá-la como base para o desenvolvimento de ferramentas para os usuários finais. Para os usuários finais essa funcionalidade pode ser útil para a configuração rápida do sistema para novos documentos.

Funcionamento do exemplo no nível de chamadas da API (veja os comentários):

Código:

CENÁRIO 1 – LINEAR.FAZEMOS DE UMA MANEIRA PREVISÍVEL DO COMEÇO AO FIM. MAIS FÁCIL PARA O ENTENDIMENTO.

// Criamos um pacote de treinamento e preenchemos com imagens
 ITrainingBatch trainingBatch = engine.CreateTrainingBatch( rootFolder, "_TrainingBatch", "English" );
 try {
 trainingBatch.AddImageFile( rootFolder + "\\00.jpg" );
 trainingBatch.AddImageFile( rootFolder + "\\01.jpg" );
// Na primeira imagem identificamos a estrutura do documento
 ITrainingPage firstPage = trainingBatch.Pages[0];
 // Antes de começar precisamos preparar a página. Nesta fase, a imagem é analisada e extraída
 // objetos simples (que pode ser usado na interface do usuário para os prompts de usuário)
 firstPage.PrepareLayout();
 // O usuário "desenha" a imagem os campos e os elementos de referência. Emulando este processo
 for( int j = 0; j < firstPage.ImageObjects.Count; j++ ) {
 ITrainingImageObject obj = firstPage.ImageObjects[j];
 string text = obj.RecognizedText;
 // O usuário “vê” o texto
 if( text == "978-1-4095-3439-6" ) {
 // “Desenha” os campos
 ITrainingField isbnField = trainingBatch.Definition.Fields.AddNew( "ISBN", TrainingFieldTypeEnum.TFT_Field );
 firstPage.SetFieldBlock( isbnField, obj.Region );
 break;
 }
 }
 for( int j = 0; j < firstPage.ImageObjects.Count; j++ ) {
 ITrainingImageObject obj = firstPage.ImageObjects[j];
 string text = obj.RecognizedText;
 // O usuário “ve” o texto do elemento de referência
 if( text == "ISBN" ) {
 // “Desenha” o elemento de referência
 ITrainingField isbnTag = trainingBatch.Definition.Fields.AddNew( "ISBNTag", TrainingFieldTypeEnum.TFT_ReferenceText );
 firstPage.SetFieldBlock( isbnTag, obj.Region );
 break;
 }
 }
 assert( trainingBatch.Definition.Fields.Count == 2 );
 // A estrutura é definida e a marcação verificada
 trainingBatch.SubmitPageForTraining( firstPage );
// Conferimos o layout de todas as páginas sequencialmente
 for( int i = 1; i < trainingBatch.Pages.Count; i++ ) {
 ITrainingPage page = trainingBatch.Pages[i];
 // Além da extração de objetos simples, o sistema tenta prever a marcação
 page.PrepareLayout();
 // O usuário verificou a marcação
 trainingBatch.SubmitPageForTraining( page );
 }
// Exportamos a marcação flexível. Na base dela o modelo é criado com apenas uma chamada CreateDocumentDefinitionFromAFL
 trainingBatch.Definition.ExportToAFL( rootFolder + "\\_TrainingBatch\\NewTemplate.afl" );
 } finally {
 trainingBatch.Close();
 }

CENÁRIO 2 – NÃO-LINEAR. O USUÁRIO ITERA PELAS PÁGINAS E EM QUALQUER MOMENTO PODE ALTERAR A DESCRIÇÃO. MAIS CONVENIENTE PARA O USUÁRIO.

Código:

 // Criamos um pacote de treinamento e preenchemos com imagens
 ITrainingBatch trainingBatch = engine.CreateTrainingBatch( rootFolder, "_TrainingBatch", "English" ); try { trainingBatch.AddImageFile( rootFolder + "\\00.jpg" ); trainingBatch.AddImageFile( rootFolder + "\\01.jpg" );
 // Listamos as páginas até o usuário não verificar a marcação em todas
 ITrainingPage page = trainingBatch.PrepareNextPageNotSubmittedForTraining(); while( page != null ) { // O usuário pode a qualquer momento desenhar mais campos, o ciclo de verificação será feito novamente. Nesta / / emulação assumimos que o usuário especifica todos os campos obrigatórios já na primeira página
 If( page == trainingBatch.Pages[0] ) { for( int j = 0; j < page.ImageObjects.Count; j++ ) { TrainingImageObject obj = page.ImageObjects[j]; string text = obj.RecognizedText;
// O usuário “vê” o texto
 if( text == "978-1-4095-3439-6" ) {
 // “Desenha” o campo
 ITrainingField isbnField = trainingBatch.Definition.Fields.AddNew( "ISBN", TrainingFieldTypeEnum.TFT_Field ); page.SetFieldBlock( isbnField, obj.Region ); break;
 }
 }
 for( int j = 0; j < page.ImageObjects.Count; j++ ) {
 ITrainingImageObject obj = page.ImageObjects[j];
 string text = obj.RecognizedText;
// O usuário “vê” o texto do elemento de referência
 if( text == "ISBN" ) {
 // “Desenha” o elemento de “referência”
ITrainingField isbnTag = trainingBatch.Definition.Fields.AddNew( "ISBNTag", TrainingFieldTypeEnum.TFT_ReferenceText ); page.SetFieldBlock( isbnTag, obj.Region );
 break;
 }
 } assert( trainingBatch.Definition.Fields.Count == 2 );
 }
 // O usuário verificou a marcação
 trainingBatch.SubmitPageForTraining( page );
 // Damos o próximo para a verificação
 page = trainingBatch.PrepareNextPageNotSubmittedForTraining(); } //
 Exportamos a marcação flexível. Na base dela o modelo é criado com apenas uma chamada CreateDocumentDefinitionFromAFL
 trainingBatch.Definition.ExportToAFL( rootFolder + "\\_TrainingBatch\\NewTemplate.afl" ); } finally { trainingBatch.Close();

Conclusão

Além da nova ferramenta descrita, agora temos entre os novos recursos interessantes para os desenvolvedores :

  • Ferramentas avançadas de pré-tratamento de imagens. Dentre as quais estão o avançado removedor de ruídos e filtro personalizável, que funciona no domínio da freqüência, como os wavelets . Após a customização, este filtro pode melhorar significativamente a qualidade das fotografias (leve desfocagem de luz, ruídos ) .
  • API para o acesso de opções de reconhecimento de palavra e caracteres. Isso permite que, em alguns casos, quando um modelo de extração de dados é bem conhecido, possamos programar a seleção da opção mais adequada para este modelo e assim melhoremos a qualidade do resultado na saída.
  • De acordo com nossos leitores! O bom suporte a Java (o JAR está incluído na ferramenta) contém a estrutura de objetos, interfaces e DLLs, com todos os adaptadores necessários para a chamadas JNI. Em 99% dos casos, você pode usá-los diretamente. Apenas não há suporte a callbacks, que os usuários podem realizar por conta própria se precisarem.

 

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *

*