Classificação de documentos a partir das suas cores

Desafio 1 do programa Mandacaru.dev (Módulo Bromélia)



Contextualização:

Inúmeras áreas de diferentes organizações (usualmente como parte de um processo de um backoffice) recepcionam documentos dos seus clientes para formação de kits de documentação. Tais kits são, por exemplo, compartilhados com outros stakeholders das empresas. Conforme pode-se pressupor, um desafio nesse cenário refere-se ao fato de que o cliente pode enviar documentos, porém sem necessariamente indicar a qual tipo se o documento se refere (RG, CNH ou CPF, por exemplo). Dessa forma, ao invés de demandar um trabalho manual para essa leitura e classificação dos documentos, podemos construir um modelo de aprendizado que tenha capacidade de ler um conjunto de documentos (em .jpg, por exemplo) e, subsequentemente, realizar a classificação em três tipos distintos: RG, CNH e CPF.

Para esse desafio utilizaremos um dataset público de RG, CNH e CPF (incluindo as imagens). Este repositório apresenta o conjunto de dados denominado Brazilian Identity Document Dataset (BID Dataset), o primeiro conjunto de dados público de documentos de identificação brasileiros.

Link do dataset: https://github.com/ricardobnjunior/Brazilian-Identity-Document-Dataset

Proposta de resolução:

Quando se pensa em classificação de imagens por Redes Neurais, frequêntemente a utilização de Redes Neurais Convolucionais é a primeira a ser lembrada. Entretanto, ao invés de delegar ao modelo a tarefa de procurar atributos/caracteristicas em uma imagem, foi vislumbrado a possibilidade de simplificar a tafera já entregando a um modelo de predição um atributo pertinente da imagem. A proposta surgiu da percepção de que os três tipos documentos possuem cores diferentes, onde o CPF possui uma cor predominantemente azul, o RG possui verde e a CNH possui verde-azulado (ou o contrário), assim, ao invés do modelo avaliar toda a imagem, ele avaliaria somente a informação da cor para realizar a classificação. A maneira mais conhecida de verificar/trabalhar computacionalmente com as informações de cores de uma imagem é através da visualização do histograma dos valores das mesmas em algum padrão de codificação de cores. Com essa representação das cores das imagens em forma de histograma, também temos o benefício de reduzir drasticamente o tamanho conjunto de dados e eliminamos os eventuais problemas de gargalo de mémoria, pois mudamos o formato dado de uma matriz tridimensional para um simples vetor. Dessa maneira, também simplificamos a arquitetura da Rede Neural para classificar algo semelhante a um sinal (informação com forma de onda).

Roteiro

1. Análise das cores dos documentos
    1.1 Visualizando as amostras dos documentos
    1.2 Canais de cores de uma imagem
    1.3 Comparando os canais de cores entre tipos de documento
2. Melhorando as imagens escuras
    2.1 Equalização de histograma
    2.2 Ganho na intensidade das cores
3. Achados no sistema de cores HSV
    3.1 Distinção entre imagens claras e escuras
    3.2 Padrões distinguíveis entre os documentos
4. Ajustando os histogramas
    4.1 Borramento
    4.2 Média móvel
5. Pré-processamento
    5.1 Resumo do pipeline
    5.2 Avaliação de memória
6. Classificador
    6.1 Treinamento
    6.2 Validação
        6.2.1 Modelo 1: RGB + 100 HSV
        6.2.2 Modelo 2: 100 HSV
7. Conclusão

1. Análise das cores dos documentos

A solução proposta não partiu de algum tutorial ou alguma referência, então, para a resolução desse desafio, vários testes foram feitos para se verificar a viabilidade da ideia. Pela quantidade de testes feitos, não seria possível mostrar todas em um único notebook e ainda assim mantê-lo sucinto, então serão mostradas somente as técnicas mais efetivas que foram realmente utilizadas, mas as demais também serão comentadas, e todas terão um link de refência para o notebook com o registro do referido teste.

Com o objetivo de manter o notebook mais enxuto, os códidos da execução dos processamentos e plots aqui mostrado serão mantidos em um módulo préambulo.

1.1 Visualizando as amostras dos documentos

O primeiro procedimento mais intuitivo ao se analisar imagens é, obviamente, olhar para elas. No plot estão somentente algumas amostras, nelas podemos ver que temos imagens com orientações diferentes, e verificando os arquivos foi possível que existem imagens com qualidades difentes, umas mais claras, outras mais escuras e outras com ruídos.

Verificando a natureza do conjunto de dados na fonte do mesmo, nos é informado que trata-se de um conjunto de dados gerado artificialmente, pois é ilegal disponibilizar imagens de domentos reais.

Notebook Teste de Hipótese 1

1.2 Canais de cores de uma imagem

Como falado na proposta da resolução, a maneira mais conhecida de verificar/trabalhar computacionalmente com as informações de cores de uma imagem é através da visualização do histograma. Um histograma nada mais é do que a contagem da frêquencia de um determinado valor. Para visualizar o padrão das cores, escolhemos o padrão mais utilizado em processamento digital de imagens que é o RGB (Red, Green, Blue). Como a composição das cores de uma imagem depende desses três valores, observando o formato do histograma dos mesmo também é uma forma de analisar as cores de uma imagem.

Aqui também pode notar que, independente do trabalho da imagem, podemos reduzí-la a em histograma com um tamanho já definido, que é 256. No caso, para para submeter a um modelo, devemos juntar os três histogramas em um único vetor, resultando em um vetor de 768, que várias vezes menor do que a matriz da imagem original.

Notebook Teste de Hipótese 1

1.3 Comparando os canais de cores entre tipos de documento

Acabamos de ver uma mandeira de tentar visualizar a informção das cores de uma imagem. Agora precisamos comparar a forma do histograma dos diferentes tipos de documentos.

Apesar de conseguirmos identificar bem a "forma" do histograma das cores visualmente, computacionalmente ainda tratamos ela como seus valores numéricos para tentar identificar essa forma. Apesar de conseguirmos comprimir qualquer imagem para um vetor com o mesmo comprimento, as escalas das contagem das cores ainda ficam diferentes, por que uma imagem maior que outra possui mais pixels, consequentemente a contagem dessas duas imagens ficam em escalas diferentes.

Para resolver esse problema, precisamos normalizar os valores de cada imagem com base na escala da mesma. Dessa maneira, com os histogramas em uma mesma escala (de 0 à 1), podemos calcular a média dos histogramas dos documentos da mesma categoria.

Obs.: Para o cálculo da média, e os outros testes também, foi utilizado um conjunto de dados amostral que representa uma pequena parcela do conjunto total.

Notebook Teste de Hipótese 1.4

Comparando as médias dos histogramas das amostras boas e da ruins podemos ver que os dois são bem separaveis e que os histogramas das amostras escuras possuem um padrão de concentração dos histogramas no centro. Assim vemos mais uma vez a necessidade de aplicar algum pré-processamento nessas amotras, bem como de identificar quando realizar esse pré-processamento.

2. Melhorando as imagens escuras

Foi possível ver o problema poderia ser fácilmente resolvido se todas as imagens tivessem uma nitidez parecida, pois cada documento possui um certo padrão na sua cor. A maior parte do tempo investido para resolver o problema foi investigando formas de melhorar as imagens escuras e aproximar o seu histograma das imagens "ideais".

2.1 Equalização de histograma

Uma das maneiras de melhorar a nitidez de uma imagem é equalizando o seu histograma para aumentar o contraste da mesma. Uma imagem com baixo contraste possui um histograma bem concentrado em uma região, que é como podemos ver no histograma da imagem abaixo, e equalizando a mesma consiguimos distribuir essa intensidade concentrada e deixar a forma do histograma mais espalhada (como na imagem boa de referência). Foram testado dois tipos de equalização: a global e a local, onde a equalização local apresentou resultados melhores. Para a equalizaçã local foi utilizado o método Contrast Limited Adaptive Histogram Equalization.

Notebook Teste de Hipótese 1.1

Podemos ver que a imagem melhorou um pouco, mas ela ainda está escura.

2.2 Ganho na intensidade das cores

Para clarear uma imagem, devemos dar um ganho na intensidade das cores, que nada mais é do que aumentar os valores RGB de cada pixel. Entretanto, há diferentes formas de fazermos isso: aplicando um ganho com um valor constante em todos os canais; aplicando um ganho percentual ao multiplicar os valores por RGB por uma porcentagem ou aplicando um ganho baseado na nossa percepção de cor (que possui pesos diferentes).

Notebook Teste de Hipótese 1.2

2.2 Ganho na intensidade das cores

Dentre dos diferentes métodos de aumento de brilho, destacou-se o método do aumento do brilho percentual. Outro resultado interessante foi a utlização da equalização CLAHE aplicada ao aumento percentual do brilho, onde a diferenciação de cores foi maiores e a nitidez do brilho foi menor, resultando em canais de cores mais espalhados. O método do aumento percentual do brilho é bastante sensível aos valores de entrada da função, pois em seu cálculo há a multipplicação de cada canal de cor em x percentual o peso do referido canal na sua composição para visualização humana, dessa maneira, se utilizado em escala, o percentual deve ser bem ajustado. Já com o acrescimo da equalização, temos mais segurança de que os canais de cores não vai ficar tão saturados, e ainda assim conseguir uma boa correção na digitalização escura da imagem com canais de cores mais representativos.

3. Achados no sistema de cores HSV

Vários testes também foram realizados utilizando a codificação de cores HSV a fim de se averiguar as vantagens e desvantagens desse sistema de cores em relação ao RGB. Neste notebook serão mostrados os principais achados desses testes.

Notebook Teste de Hipótese 1.4
Notebook Teste de Hipótese 1.5
Notebook Teste de Hipótese 1.6

3.1 Distinção entre imagens claras e escuras

Verificamos anteriormente dois métodos para melhorar a nitidez das imagens mais escuras, entretanto, também precisamos de algum método para identificar computacionalmente quando uma imagem é escura ou não. Um dos achados derivado dos testes no sistema de cores HSV é que, através da média do média dos valores de 'Value', conseguimos identificar facilmente quando uma imagem é clara ou escura. Também foi possível fazer essa identificação pelo padrão RGB, avaliando a média do histograma em uma certa região, mas pelo HSV conseguimos uma separabilidade ainda melhor.

Notebook Teste de Hipótese 1.5

3.2 Padrões distinguíveis entre os documentos

Outro achado interassante avaliando o padrão HSV é que foi possível identificar um alto grau de significância nos 100 primeiros valores do histograma da Matiz (Hue), permitindo assim utilizarmos mais atributos significantes para um modelo preditivo. Poderíamos também utilizar todo o histograma da Matiz, mas em análises vimos que o 100 primeiros valores eram os que apresentavam os padrões mais distinguíveis entre os tipos de documentos.

4. Ajustando os histogramas

Durante os testes feitos, outras ideias de métodos surgiam para tentar aproximar o histograma das imagens escuras paras as imagens ideais, bem como maneiras de facilitar ainda mais a tarefa de classificação dos histogramas.

4.1 Borramento

Uma dessas ideias foi utilizar o borramento de imagens. Depois de tanto olhar para os histogramas, passamos a interpretá-los como sanais, e percemos que a imagem em si não precisa ficar tão nítida como uma imagem ideal, precisamos somente que o seu histograma fique próximo dos histogramas das imagens ideais independente do resto.

A estratégia de borrar as imagens baseou-se na intuição de que o procedimento de aplicar um kernel de média (um dos métodos de borramento) iria fazer com que a cor de fundo, que é a predominante, sobrepusesse as outras cores que estariam em minoria. Dessa maneira, aumentando a significância da cor de fundo predominante, poderíamos concentrar a forma do histograma na referida cor predominante, e assim aumentar a distinção entre os histogramas dos diferentes tipos de documentos.

Esses testes foram feito juntamentos com os procedimentos de aumento de brilho e equalização de histograma, justamente para avaliarmos se seria possível aproximar mais ou não o histograma das imagens escuras melhoradas.

Notebook Teste de Hipoté 1.10

Como foi possível ver, conseguimos aproximar consideravelmente a forma do histograma das imagens melhoradas e ainda mantem a distinção entre os tipos de documentos, mesmo aplicando um kernel grande para a média (borramento).

4.2 Média móvel

Outro ajuste vislumbrado que poderia ser feito foi aplicar um filtro de média móvel nos histogramas com o objetivo de diminuir os que pareciam ruídos. Como comentado anteriormente, em um dado momento os histogramas passaram a ser visualizados como uma forma de onda, e os picos nessas formas de ontem podem ser ruídos, o que poderia atrapalhar o classificador na hora de avaliar os vetores de histograma, pois um ruído pode ficar deslocado entre forma de onda e não ter sentido semântico. Dessa maneira, mesmo que o histograma não seja um sinal, aplicamos uma média móvel na expectativa de deixar a informação mais "fácil" de ser interpretada computacionalmente.

Notebook Teste de Hipótese 1.9
Notebook Teste de Hipótese 1.11

5. Pré-processamento

Notebook do Pré-processamento.ipynb)

5.1 Resumo do pipeline

1. Identificar as imagens escuras através do Value do HSV;
    Nas imagens escuras:
    1.1 Equalização local (CLAHE);
    1.2 Ganho de intensidadep percentual;
2. Borrar as imagens;
3. Calcular histograma do RGB e HSV;
4. Normalizar histograma;
5. Calcular média móvel.

5.2 Avaliação de memória

Um dos nossos objetivos vilumbrados foi realizar reduzir o tamanho do conjunto para evitarmos problemas de memória e também para acelerar os procedimentos de treinamento e validação dos modelos. A avaliação da memória foi feita com os dados da frente do CPF, não foi realizado em todo o conjunto pois carregar todo os arquivos, mesmo fazendo desalocamento de memória, levaria bastante tempo.

Espaço ocupado das imagens do CPF em memória RAM: 1.76 GB

Espaço ocupado pelo vetores de histograma em memória RAM: 103.52 MB

Economia de 94.27 %

Notebook Teste de Memória

6. Classificador

6.1 Treinamento

Após desenvolver e executar o pipeline do pré-processamento dos dados, podemos iniciar o treinamento e validação preliminar dos modelos de classificação.

Existem diferentes classificações que podemos tentar realizar dependendo da abstração escolhida para separar os documentos:
1. Separar os documentos entre os abertos e os "normais" (frente e verso), e depois classificá-los em suas respectivas categorias;
1.1. Categorizar os documentos no seu respectivo tipo (CNH, RG, CPF);
1.2. Categorizar os documentos no seu respectivo tipo e também segmentantá-los (CNH Frente, CNH Verso, RG Frente e etc);
2. Categorizar os documentos no seu respectivo tipo (CNH, RG, CPF), sem distinguir entre abertos e "normais".

Além disso, podemos utilizar como entrada dos modelos diferentes atributos:
1. A junção dos histogramas dos canais de cores do padrão RGB;
2. A junção dos histogramas dos canais de cores do padrão RGB + os 100 valores do histograma da matriz(hue) do padrão HSV;
3. Os 100 valores do histograma da matriz(hue) do padrão HSV.

Com os testes realizados, foi possível ver com clareza que segmentar demais os targets atrapalha na predição da rede neural, onda a classificação sob a avaliação para 3 targets mostrou resultados bem melhores. A interpretação que podemos ter sobre isso é que o histograma entre o verso e a frente dos documentos são bem semelhantes, dificultando assim a avaliação da rede neural para diferenciá-los.

Em relação às diferentes combinações de atributos, observamos que utilizar os histogramas do RGB + os 100 primeiros valores do histograma da matriz do HSV, bem como utilizar somente os 100 primeiros valores do histograma da matriz do HSV, apresentaram bons resultados para a classificação dos documentos, em contra partida, utilizar os histogramas do RGB não apresentou resultados tão bons. A partir disso, podemos perceber que os 100 primeiros valores do histograma da matriz do HSV foram bem significantes como abributos para a diferenciação dos documentos, pois tanto acompanhados dos histogramas do RGB como sozinhos apresentaram bons resultados.

Também foram testados diferentes arranjos de redes neurais, entretanto, a variedade de combinações sendo pouca por conta da simplicação do problema inicial, que era o nosso objetivo. Testamos redes neurais com 1 camada oculta densa, 2 camadas ocultas densas e 2 camadas ocultas densas com 1 de BatchNormalization. A utilização de 1 camada densa e 2 camadas densas apresentaram bons resultados, mas não mostraram diferenças significativas, em termos de acurácia geral. A utilização do BatchNormalization apenas acelerou o treinamento para convergir mais rápido, não apresentando aumento ou decremento na acurária.

Para a validação final dos modelos, por conta dos melhores resultados apresentados, escolhemos avaliar dois modelos: um com os histogramas do RGB + os 100 primeiros valores do histograma da matriz do HSV; e o outro que utiliza somente os 100 primeiros valores do histograma da matriz do HSV. A arquitetura dos dois casos foi escolhida com base nos melhores resultados, as variações eram quase insignificantes, mas precisávamos de um critério para a escolha dos mesmos. As arquiteruras escolhidas foram: 2 camadas ocultas densas com 1 de BatchNormalization para o primeiro caso; e 1 camada oculta densa com 1 de BatchNormalization para o segundo caso.

Notebook do Treinamento dos Modelos

6.2.1 Modelo 1: RGB + 100 HSV

6.2.2 Modelo 2: 100 HSV

6.2 Validação

Após realizar os testes das diferentes possibilidades de criação dos modelos, elegemos duas redes neurais para avaliarmos com mais critérios e validarmos. Escolhemos avaliar dois modelos: um com os histogramas do RGB + os 100 primeiros valores do histograma da matriz do HSV; e o outro que utiliza somente os 100 primeiros valores do histograma da matriz do HSV. No treinamento, utilizamos somente um conjunto de treino e de testes, sem validação, e analisamos somente a acurária retornada pelo verbose do treinamento dos modelos. Na validação, as métricas utilizadas foram a precisão, recall, f1-score e matriz de confusão.

Notebook Validação dos Modelos

6.2.1 Modelo 1: RGB + 100 HSV

6.2.2 Modelo 2: 100 HSV

7. Conclusão

Obs.: Os comentários das avaliações foram retiradas de Notebook Validação dos Modelos

Avaliando somente a acurácia retornada pelo verbose do treinamento dos modelos, podemos ver que que o modelo 1 aparesentou uma variância menor do que o modelo 2:

categorical_accuracy val_categorical_accuracy
Modelo 1 0.9730 0.9805
Modelo 2 0.9637 0.9703

Entretanto, como nessa etapa foram utilizados somente os conjuntos de treinamento e teste, temos que ter cuidado com as interpretações dos resultados, pois o modelo mesmo que o modelo 1 tenha sido com estável e tenha apresentado uma acurácria maior, possa ser que tenha acontecido overfiting. Dessa maneira, faz-se necessário continuar avaliando as outras métricas.

Partindo para a análise do classification_report com a precisão, revocação e escore-f1, temos:

Modelo 1:
Documento precision recall f1-score
CNH 0.99 0.98 0.98
CPF 0.99 0.98 0.99
RG 0.98 0.99 0.98

Modelo 2:
Documento precision recall f1-score
CNH 0.98 0.97 0.98
CPF 0.97 0.98 0.97
RG 0.97 0.98 0.97

Olhando rapidamente para as duas tabelas, podemos perceber que as diferenças foram pouco significativas, com o modelo 1 apresentando os melhores resultados. As diferenças entre as métricas dos dois modelos foram de poucos décimos, com o modelo 1 apresentando os valores mais estáveis, incluindo o f1-score um valor estável para todas as classes.

Analisando as matrizes de confusão, podemos ver que o modelo 1 apresentou menos falso-positivos entre CNH e RG (e também o contrário), enquanto o modelo 2 apresentou menos falsos positivos envolvendo os CPF.

Os gráficos de acurária e de loss dos dois modelos possuem basicamente a mesma forma, onde ambos convergiram rapidamente com 20 épocas. A 'validação' nos gráficos, que se refere ao conjunto de testes, apresentou resultados melhores que o de treino, o que é estranho, pois os dados de testes até então não foram vistos no treinamento.

Para a divisão dos conjuntos de treino, testes e validação, utilizamos uma divisão pseudo-aleatória, entretanto, o treinamento mais adequado seria com a divisão estratificada, pois o número de imagens para as classes de CNH e RG são maiores que a do CPF por conta dos documentos abertos. A função de divisão estratificada que estavamos tentando utilizar não estava funcionando, e não tivemos tempos de buscar alternativas para utilizar a mesma técnica, entretanto, avaliamos que, por conta de diferenciação do CPF ser alta por conta da cor bem diferente dos outros documentos, o treinamento não saiu tão prejudicado (como podemos ver pelo resultados).

Podemos concluir que, no geral, o modelo 1 apresentou melhores resultados que o modelo 2, mesmo que por poucas diferenças. Entretanto, o modelo 2 poderia ser escolhido por poder otimizar ainda mais as operações e o tempo de avaliação do modelo, pois o modelo 2 utiliza somentre os 100 primeiros valores do histograma do padrão HSV, enquanto o modelo utiliza 850 valores(750 RGB + 100 HSV). Outro critério de desempate poderia ser avaliar qual documento seria submetido com mais fequência ao modelo na prática e escolher o modelo que apresenta menos falso-positivos para o referido documento.

As imagens do conjunto de dados foram criadas artificialmente, através de redes neurais, para possibilitar a disponibilização de amostras de documentos sem violar a privacidade e segurança de dados sensíveis. Os autores desse banco de imagens criaram três tipos de qualidade de imagem: boa; média e ruim. O maior empenho na criação desse modelo foi verificar técnicas que podessem ser utilizadas para melhorar as imagens ruins que prejudicavam sensivelmente a classificação através das cores, pois as imagens documentos mais escuras possuem um histograma bem diferente das imagens claras e nítidas. Outro custo que surgiu por conta das imagens escuras foi no próprio pipeline dp pré-processamento das imagens por conta das correções. Entretanto, em uma utilização real, esses modelos não teriam a mesma dificuldade por conta de fotos escuras, pois os serviços que pedem fotos de documentos já exigem que as fotos fornecidas sejam nítidas, logo, nesse contexto, a utilização do modelo 2 poderia ser até mais viavél por conta das otimizações que seriam possíveis. Ainda assim, na prática, esse mesmo pipeline do pré-processamento pode ser uma solução mais robusta do que as convencionais por aceitar também fotos pouco níticas ou com ruídos.