Comment tester le code de traitement d'image unitaire?

14

Je travaille dans le traitement d'images (principalement OCR) et je me demande comment intégrer des tests unitaires dans mon développement.

J'utilise déjà des tests unitaires pour un type de code plus "commun" mais quand je traite du code de traitement d'image, je ne sais pas comment le traiter. Ce type de code a toujours besoin d'une entrée / sortie de données d'image et se moquer de cela n'est pas évident. Pour l'instant, je fais principalement des tests d'intégration, mais ils prennent un certain temps à s'exécuter et j'aimerais avoir des idées sur la façon de décomposer ce type de code en tests unitaires afin de pouvoir les exécuter plus rapidement.

Modifier: l'analyse d'un personnage peut passer par de nombreuses étapes impliquant plusieurs opérations de rotation, de mise à l'échelle et morphologiques. Ces étapes changent souvent au fur et à mesure du développement de l'algorithme. Ainsi, l'entrée et la sortie attendues peuvent beaucoup évoluer lors des tests. Chaque caractère peut mesurer 100 x 100 pixels, il est donc hors de question de les coder en dur dans le code ou de travailler avec les données générées.

rold2007
la source
Pouvez-vous esquisser un exemple de fonction où vous avez du mal à créer un test unitaire?
Doc Brown
1
Trop court pour une vraie réponse et pas vraiment un test unitaire: nous traitons les données à la main (comme dans: passer par un grand nombre d'échantillons - je dépasse généralement 1000 pour de telles tâches de classification, mais cela dépend de la taille globale de votre échantillon ) et en comparant automatiquement les résultats finaux aux données traitées manuellement. J'ai mis en place un petit framework pour le faire, il va devenir open source dans quelques semaines, mais voici
Birgit P.
Pour votre exemple, vous pouvez facilement tester la rotation, la mise à l'échelle, etc. sous forme de petites unités de tests. La rotation d'une image donnée à 45 degrés ne devrait pas changer grand-chose. Cela vaut également pour les opérations de mise à l'échelle et morphologiques. Il est cependant difficile de tester quelque chose où la sortie attendue évolue pendant la mise en œuvre. Vous pouvez essayer de faire une mesure de qualité et dire qualité> = some_quality. Pour vous assurer que votre qualité ne se dégrade pas, mais cela peut également être difficile. En dehors de cela, tout ce que vous pouvez faire est d'avoir des tests qui prouvent que les pièces sous-jacentes ne sont pas cassées. Comme échelle / rotation / etc.
martiert
@martiert: Je ne teste pas la rotation, la mise à l'échelle, etc. car je les appelle depuis une 3ème bibliothèque qui, je crois, est bien testée. L'algorithme OCR est composé de plusieurs de ces opérations. Mais comme vous le dites, tester quelque chose où évolue une sortie est difficile. C'est peut-être un bon avertissement, nous n'avons pas le choix, mais de dépendre des tests d'intégration ...
rold2007
@Birgit P .: Solution intéressante. Comme vous le dites, il s'agit toujours de tests d'intégration. Avoir un framework comme le vôtre aiderait à configurer ces tests plus rapidement mais ils ne fonctionneront pas plus vite ...
rold2007

Réponses:

12

Je travaille avec des logiciels d'enregistrement vidéo / d'analyse / de streaming et nous avons rencontré un problème très similaire. Ci-dessous était notre solution, je ne sais pas comment cela fonctionnera à long terme, mais pour l'instant cela semble fonctionner.

Enregistrez les images d'entrée / sortie en tant que ressources dans votre projet de test unitaire. Demandez ensuite à un test unitaire de vérifier que lorsqu'une entrée spécifique est donnée, cette sortie spécifique est produite.

9/10 fois lorsque vous refactorisez le code et ajoutez d'autres fonctionnalités, vous vous attendez à ce que le comportement de vos routines de gestion d'image ne change pas, donc si tout d'un coup les tests unitaires commencent à échouer, cela est probablement dû à une erreur.

D'un autre côté, si vous apportez des modifications à l'algorithme réel, cela entraînera également l'échec du test unitaire. Dans ce cas, vous devrez vérifier manuellement / visuellement que les résultats sont corrects et s'ils semblent bons, puis mettre à jour les ressources d'image pour que le test unitaire réussisse à nouveau.

Dans notre projet, nous avons fini par développer des sources vidéo «fausses» (ou simulées si vous voulez), qui peuvent nous alimenter en données à la fois pour l'entrée et la sortie. Mais les données elles-mêmes ne sont pas fausses, elles ont en fait été capturées à l'aide de classes d'enregistrement de données auxiliaires à partir d'un système en cours d'exécution lorsque nous avons effectué des tests manuels et vérifié que tout fonctionnait.

DXM
la source
D'accord, c'est OK de s'appuyer sur certains fichiers concrets dans vos tests lorsque vous testez des routines de travail avec des fichiers (vous le voyez plus souvent avec des tests d'intégration).
Kemoda
1
Si vous exécutez une entrée dans toute la chaîne de traitement, puis vérifiez la sortie, vous n'êtes pas un test unitaire mais un test d'intégration.
tdammers
@tdammers: Je n'ai jamais dit de l'exécuter à travers toute la chaîne. Exécutez une entrée à travers une "unité", pas toute la chaîne. Et bien sûr, si la sortie de cela se trouve être autre chose que des images, il vous suffit d'avoir une entrée enregistrée en tant que ressources d'image.
DXM
@DXM: Je comprends votre solution mais je pense que nous pourrions ne pas avoir les mêmes contraintes. Mes données d'entrée / sortie changent beaucoup pendant le développement de l'algorithme. Comment gérez-vous ces changements réguliers? En OCR, je peux avoir une précision de plus de 99%, donc les tests sur seulement quelques images peuvent me donner un faux sentiment de succès tandis que les tests d'intégration pourraient me dire plus tard que j'ai effectivement aggravé l'algorithme ...
rold2007