Como código de processamento de imagem para teste de unidade?

14

Estou trabalhando no processamento de imagens (principalmente OCR) e me pergunto como devo integrar testes de unidade no meu desenvolvimento.

Já estou usando testes de unidade para um tipo mais "comum" de código, mas ao lidar com código de processamento de imagem, não tenho certeza de como lidar com isso. Esse tipo de código sempre precisa de alguma entrada / saída de dados de imagem e zombar disso não é óbvio. Por enquanto, estou fazendo testes de integração, mas eles demoram um pouco para serem executados e eu gostaria de algumas idéias sobre como dividir esse tipo de código em testes de unidade, para que eu possa executá-los mais rapidamente.

Editar: a análise de um personagem pode passar por várias etapas que envolvem múltiplas operações de rotação, escala e morfologia. Essas etapas mudam frequentemente à medida que o algoritmo está sendo desenvolvido. Assim, a entrada e a saída esperada podem evoluir muito durante o teste. Cada caractere pode ter 100x100 pixels, portanto, é difícil codificá-los no código ou trabalhar com dados gerados.

rold2007
fonte
Você pode esboçar um exemplo de uma função em que você tem problemas para criar um teste de unidade?
Doc Brown
1
Muito curto para uma resposta real e não um teste de unidade: estamos processando dados manualmente (como em: passamos por um grande número de amostras - geralmente vou além de 1000 para essas tarefas de classificação, mas isso depende do tamanho geral da amostra ) e comparando os resultados finais com os dados processados ​​manualmente. Eu configurei um pequeno framework para fazer isso, ele será aberto em poucas semanas, mas esta é a descrição - você pode clonar o processo: birgitplays.wordpress.com/2012/09/15/…
Birgit P.
Para o seu exemplo, você pode testar facilmente a rotação, o dimensionamento etc. como pequenas unidades de teste. Girar uma determinada imagem 45 graus não deve mudar muito. Isso também vale para operações morfológicas e de escala. Testar algo em que a saída esperada evolui durante a implementação é, no entanto, difícil. Você pode tentar fazer uma medida de qualidade e dizer qualidade> = alguma_qualidade. Para garantir que sua qualidade não seja degradante, mas isso também pode ser difícil. Fora isso, tudo o que você pode fazer é fazer testes que comprovem que as partes subjacentes não estão quebradas. Como dimensionar / girar / etc.
martiert
@martiert: Eu não estou testando rotação, dimensionamento, etc, como eu os chamo de uma terceira biblioteca que acredito que seja bem testada. O algoritmo OCR é composto por muitas dessas operações. Mas, como você diz, testar algo em que uma saída evolui é difícil. Talvez seja um bom aviso não temos a escolha, mas a depender de testes de integração ...
rold2007
@ Birgit P .: Solução interessante. Como você diz, ainda é teste de integração. Ter um quadro como a sua seria de ajuda para configurar estes testes mais rápido, mas eles não vão correr mais rápido ...
rold2007

Respostas:

12

Trabalho com software de gravação de vídeo / análise / streaming e enfrentamos um problema muito semelhante. Abaixo estava nossa solução, sem saber como isso funcionaria a longo prazo, mas por enquanto parece funcionar.

Salve imagens de entrada / saída como recursos em seu projeto de teste de unidade. Faça com que o teste de unidade verifique se, quando uma entrada específica é fornecida, essa saída específica é produzida.

9/10 vezes quando você refatorar o código e adicionar outra funcionalidade, você esperaria que o comportamento de suas rotinas de manipulação de imagens não mudasse; portanto, se todos os testes de unidade repentinos começarem a falhar, provavelmente ocorrerá um erro.

Por outro lado, se você fizer alterações no algoritmo real, isso também resultará em falha no teste de unidade. Nesse caso, você precisaria verificar manualmente / visualmente se os resultados estão corretos e, se ficarem bem, atualize os recursos da imagem para fazer o teste de unidade passar novamente.

Em nosso projeto, acabamos desenvolvendo fontes de vídeo "falsas" (ou zombarias, se você quiser), que podem fornecer dados para entrada e saída. Mas os dados em si não são falsos; na verdade, foram capturados usando classes auxiliares de gravação de dados de um sistema em execução quando executamos testes manuais e verificamos que tudo estava funcionando.

DXM
fonte
Concorde, não há problema em confiar em alguns arquivos concretos em seus testes quando você estiver testando rotinas trabalhando com arquivos (você vê isso mais frequentemente nos testes de integração).
Kemoda # 28/12
1
Se você executar alguma entrada por toda a cadeia de processamento e depois verificar a saída, não fará testes de unidade, mas testes de integração.
tdammers
@ Tdammers: Eu nunca disse para passar por toda a cadeia. Execute alguma entrada através de uma "unidade", não de toda a cadeia. E com certeza, se a saída disso for algo diferente de imagens, você só precisará ter a entrada salva como recursos de imagem.
DXM
@ DXM: Entendo sua solução, mas acho que podemos não ter as mesmas restrições. Meus dados de entrada / saída mudam bastante enquanto o algoritmo é desenvolvido. Como você lida com essas mudanças regulares? Em OCR eu posso ter mais de% de precisão 99 de modo a testar em apenas um par de imagens pode me dar uma falsa sensação de sucesso, enquanto os testes de integração pode me dizer mais tarde que eu realmente piorou o algoritmo ...
rold2007