Escrevi muito sobre projetos de visão computacional e aprendizado de máquina, como
sistemas de reconhecimento de objetos e
projetos de reconhecimento de faces . Eu também tenho uma
biblioteca de reconhecimento facial de código-fonte Python que de alguma forma chegou às
10 bibliotecas de aprendizado de máquina mais populares no Github . Tudo isso levou os recém-chegados ao Python e à visão de máquina a me fazerem
muitas perguntas.

Por experiência, há um problema técnico específico que muitas vezes confunde as pessoas. Não, essa não é uma questão teórica difícil ou um problema com GPUs caras. O fato é que quase todo mundo carrega imagens na memória rotacionada, mesmo sem saber. E os computadores
não detectam objetos
muito bem ou reconhecem rostos em imagens rotacionadas.
Como as câmeras digitais giram imagens automaticamente
Quando você tira uma foto, a câmera registra a posição do telefone, para que em outro programa a imagem seja exibida na orientação correta:

Mas a câmera não gira os dados de pixel dentro do arquivo. Como os sensores de imagem nas câmeras digitais são lidos linha a linha como um fluxo contínuo de informações em pixels, é mais fácil para a câmera armazenar sempre os dados em pixels na mesma ordem, independentemente da posição real do telefone.

Essa é a preocupação do programa para visualizar - gire a imagem corretamente antes de exibi-la na tela. Juntamente com os dados da própria imagem, a câmera também salva metadados - configurações da lente, dados de localização e, é claro, o ângulo de rotação da câmera. O visualizador deve usar essas informações para exibir corretamente.
O formato mais comum de metadados de imagem é chamado
EXIF (abreviação de Exchangeable Image File Format). Os metadados EXIF são incorporados em todos os arquivos jpeg. Você não pode vê-los na tela, mas eles são lidos por qualquer programa que sabe onde procurar.
Aqui estão os metadados EXIF dentro da imagem JPEG do nosso ganso da ferramenta
exiftool :

Veja o elemento 'Orientação'? Ele diz ao espectador que, antes de exibir na tela, a imagem deve ser girada 90 graus no sentido horário. Se o programa se esquecer de fazer isso, a imagem estará do seu lado!

Por que isso quebra tantos aplicativos de visão de máquina em Python?
Os metadados EXIF não faziam parte originalmente do formato JPEG. Eles foram introduzidos muito mais tarde, emprestando a idéia do formato TIFF. Para compatibilidade com versões anteriores, esses metadados são opcionais e alguns programas não se preocupam em analisá-los.
A maioria das bibliotecas de imagens Python, como numpy, scipy, TensorFlow, Keras, etc., se consideram
ferramentas científicas para pessoas sérias que trabalham com conjuntos de dados compartilhados. Eles não se importam com questões no
nível do consumidor , como a rotação automática da imagem, embora isso seja necessário para quase todas as fotografias do mundo tiradas com câmeras modernas.
Isso significa que, ao processar uma imagem com quase qualquer biblioteca Python, você obtém os dados da imagem original sem rotação. E adivinhe o que acontece quando você tenta fazer upload de uma foto do seu lado ou de cabeça para baixo no modelo de detecção de rosto ou objeto? O detector não dispara porque você forneceu dados incorretos.
Você pode pensar que os problemas surgem apenas nos programas de iniciantes e estudantes, mas não é assim! Mesmo a
versão demo da API principal da Google, Vision, não trata a orientação EXIF corretamente:
Demonstração A API do Google Vision não sabe como girar imagens orientadas a retrato tiradas de um telefone celular padrãoEmbora o Google Vision reconheça alguns animais ao seu lado, ele os marca com o rótulo comum "animal", porque os modelos de visão por computador são muito mais difíceis de reconhecer um ganso do que um ganso vertical. Aqui está o resultado, se você girar a imagem corretamente antes de enviá-la ao modelo:

Com a orientação correta, o Google detecta pássaros com uma marca de ganso mais específica e um indicador de confiança mais alto. Muito melhor!
Esse é um problema super óbvio quando você
vê claramente que a imagem está do lado , como nesta demonstração. Mas é aqui que tudo se torna insidioso - geralmente você não vê! Todos os programas normais do seu computador exibirão a imagem na orientação correta, e não como ela é realmente armazenada no disco. Portanto, quando você tenta visualizar uma imagem para ver por que seu modelo não está funcionando, ela será exibida corretamente e você não entenderá por que o modelo não está funcionando!
O Finder no Mac sempre exibe fotos giradas corretamente a partir do EXIF. Não há como ver se a imagem está realmente armazenada de ladoIsso inevitavelmente leva a muitos tickets abertos no Github: as pessoas reclamam que os projetos de código aberto estão com problemas e os modelos não são muito precisos. Mas o problema é muito mais simples - eles apenas colocam fotos giradas ou invertidas na entrada!
Correção
A solução é que, sempre que você carregar imagens em programas Python, verifique os metadados da orientação EXIF e gire as imagens, se necessário. É muito fácil de fazer, mas na Internet é surpreendentemente difícil encontrar exemplos de código que sejam adequados para todas as orientações.
Aqui está o código para carregar qualquer imagem em uma matriz numpy com a orientação correta:
import PIL.Image import PIL.ImageOps import numpy as np def exif_transpose(img): if not img: return img exif_orientation_tag = 274
A partir daqui, você pode transferir uma matriz de dados de imagem para qualquer biblioteca padrão de visão de máquina Python que espera uma matriz de entrada: por exemplo, Keras ou TensorFlow.
Como o problema é onipresente, publiquei essa função como uma biblioteca de pips chamada
image_to_numpy . Você pode instalá-lo da seguinte maneira:
instalação do pip3 image_to_numpy
Funciona com qualquer programa Python, corrigindo o carregamento de imagens, por exemplo:
import matplotlib.pyplot as plt import image_to_numpy
Veja o
arquivo leia -
me para mais detalhes.
Aproveite!