Como a máquina leu uma tabela nutricional?

Lucas de Brito Silva
Data Hackers
Published in
7 min readApr 7, 2021

Como foi possível ler tabelas nutricionais com OCR, Tesseract e muita visão computacional!

Ha um tempo atrás estava imerso em um projeto que trabalhava com a formação de um data lake de dados alimentícios, coletando desde produtos em geral até as informações nutricionais de uma massa de alimentos, todavia em determinado ponto percebeu-se que a maior parte das informações nutricionais estavam inseridas em imagens e não em textos, dificultando, assim, a questão de web scrapping com o framework Scrapy e Python.

Esse problema abriu oportunidade para o aprendizado de algo que está presente na tecnologia há muito tempo e ganhou percussão com David H. Shepard. Essa tecnologia é muito conhecida como Optical Character Recognition (OCR). Inclusive, o seguinte video é muito legal para ter uma noção do início do OCR:

Dessa forma o desafio era que a partir de uma imagem, fosse possível obter os dados de tabelas nutricionais em texto.

Sumário

  • Tesseract e PyTesseract;
  • Teoria das linhas da tabela;
  • EAST;
  • Symspell;
  • Fluxograma e Implementação.

Tesseract e PyTesseract

Procurando sobre OCR, cheguei a uma ferramenta que é líder de uso atualmente, além de ser conhecida pela sua grande eficiência. Essa ferramenta é o Tesseract.

Logo for Google’s Tesseract OCR software. Font: Wikipedia.
Logo for Google’s Tesseract OCR software. Font: Wikipedia.

O Tesseract é um engine open source com a licença da Apache 2.0 que atualmente pertence à Google, sendo que este visa aplicar o reconhecimento óptico de caracteres. Sua implementação incial aconteceu com a linguagem C, sendo desenvolvida pela HP. Para mais detalhes, fique a vontade para olhar o repositório no GitHub ou consultar o seguinte artigo, que também é bem completo quanto ao assunto:

Todavia, com o uso crescente da linguagem Python, a comunidade abraçou a causa e desenvolveu um wrapper que foi nomeado de Pytesseract, contemplando todas as funcionalidades que pertencem ao projeto original. O Pytesseract também é um projeto open source que se encontra disponível no GitHub ou pronto para o uso no Python Package Index (PyPI).

Essa engine e esse pacote foram essenciais para o desenvolvimento do projeto, a ponto de tornarem-se um requisito (o qual é abordado no repositório do projeto).

Teoria das linhas da tabela

Calories on the New Nutrition Facts Label. Font: FDA.

Como mencionado no início do projeto o desafio estava voltado a ler tabelas nutricionais e diferente de um ambiente controlado, quando se trata de tabelas nutricionais, temos varias palavras que por vezes são desconexas, além de linhas horizontais e linhas verticais que separam as palavras dos valores, dessa forma, a questão que fica é: como facilitar a leitura para a máquina nessa situação? Ou seja, a missão era remover essas linhas e colunas e deixar apenas as palavras e valores, de modo que não “desviássemos” a atenção da máquina para aquilo que ela não precisava se quer saber.

Para resolver esse problema duas coisas foram feitas.

A primeira foi utilizar de kernels horizontais e verticais para identificar onde essas linhas estavam, gerando uma imagem limiarizada. Para realizar esse trabalho, usamos o OpenCV uma biblioteca completa e muito popular para a área de imagens em Python. Abaixo segue o resultado das linhas encontradas.

image of binarized lines. Font: Author.
Image of binarized lines. Font: Author.

Mas após ter essas linhas identificadas, como deleta-las da imagem?

K-means

A resposta não foi nada mais nada menos que K-means, um algoritmo não supervisionado de aprendizado de máquina que normalmente é utilizado para clusterização, o qual não precisa de inputs externos para seu funcionamento, precisando determinar apenas o número de K, ou seja, a quantidade de agrupamentos necessários para o seu problema.

Mas a final de contas para que esse K-means? O que tem a ver com o problema das linhas?

Como descrito em sua breve introdução, o k-means é utilizado para agrupamentos, dessa forma em vez de deletar as linhas foi realizado um agrupamento de cores na imagem e sobrescrevemos (em vez de deletar) as linhas pela cor predominante da imagem, sendo que normalmente quando se trata de uma tabela nutricional, as cores predominantes são, respectivamente, para o fundo, linhas, letras e, às vezes, detalhes.

Por esse motivo, também, não foi utilizado o famigerado elbow method para definir a quantidade de Ks, pois temos uma situação com o número conhecidos de agrupamentos necessários.

O resultado desse processo é demonstrado na imagem abaixo, assim como as funções utilizadas para sobrescrever as linhas detectadas à priori. O código para uso do k-means pode ser encontrado detalhadamente na biblioteca sklearn ou no repositório do projeto.

Table before and after transformation, respectively.
Table before and after transformation, respectively. Font: Author.
Functions used to remove lines of an image. Font: Author.

EAST — Efficient and Accurate Scene Text Detector

Nessa etapa ainda não temos uma leitura por parte das máquinas, mas utilizamos o EAST, um scene text detector que também é open source com o código disponível no GitHub e, nesse projeto, foi utilizado com o objetivo de facilitar ainda mais o trabalho da máquina, tirando as distrações e focando no texto da imagem.

Como eu disse, o EAST sozinho apenas localiza onde tem texto, mas não realiza a leitura, processo o qual podemos assimilar a um analfabeto, que sabe que tem um texto naquele lugar, mas não faz ideia do que está escrito. Seu resultado é pode ser visualizado na imagem abaixo:

EAST: An Efficient and Accurate Scene Text Detector. Font: Youtube.
EAST: An Efficient and Accurate Scene Text Detector. Font: YouTube.

Há tutoriais e publicações excelentes na internet que ensinam a usar esse tipo de tecnologia, dos quais posso citar:

Após aplicarmos o EAST com uma série de filtros morfológicos, então fazemos uma leitura das palavras de no estilo ocidental, ou seja, de cima para baixo e da esquerda para direita, deixando mais próximo do que é realizado na leitura humana, como é demonstrado na imagem a seguir.

Reading orientation. Font: Author.
Reading orientation. Font: Author.

Nessa etapa, podemos assimilar não mais a um analfabeto, mas a uma criança que está aprendendo a realizar leitura e entende algumas coisas. Mas como corrigir ou melhorar a leitura dessa criança?

SymSpell

O SymSpell é um algoritmo alternativo para Symmetric Delete spelling correction algorithm, sendo que o SymSpell foi considerado 1000x mais veloz na realização dessa tarefa, trabalhando com um dicionário que é carregado na memória, além de contemplar uma série de linguagens. Seu repositório está no GitHub e pode ser acessado a partir do seguinte link.

Continuando com as nossas assimilações, nesse caso podemos dizer que o SymSpell é como um professor para a nossa leitura, o qual aplica correções das trabalhando com uma distância de similaridade entre as palavras.

Fluxograma e Implementação.

Todo o processo de leitura da imagem com a tabela nutricional até ter o texto corrigido e pronto para o uso resume-se na seguinte imagem.

Flowchart of the filters. Font: Author.
Flowchart of the filters. Font: Author.

Além disso, toda a implementação desse projeto encontra-se disponível tanto no Python Package Index (PyPI), podendo ser utilizada em apenas 3 linhas, como no exemplo a seguir.

Example of Nkocr use. Font: Author.

Vale dizer que esse projeto faz parte da comunidade open source e conta com novas participações de implementação, incluindo a sua! Sinta-se a vontade para contribuir com pull requests e issues.

--

--