Projet final: Réduction de bruit sur téléphone mobile

Par Mathieu Garon

Introduction

Le nombre d'appareils mobiles a excédé le nombre d'humains sur la terre depuis peu. Et avec les capacités que nous offrent l'internet, la communication ne se fait plus seulement qu'avec du texte, mais de plus en plus avec des photographies. L'idée d'avoir des performances élevées avec des appareils ayant une mécanique et une optique de qualité relativement médiocre est de plus en plus importante. C'est alors qu'un marché s’est développé sur le principe d'augmenter la qualité des images à l'aide d'algorithmes.

Le projet suivant présente une méthode pour enlever le bruit causé par le mouvement du photographe lors d'une exposition lent ou simplement lors de prise de photographies sans trépieds. Des méthodes ont été développées dans le but de retirer le bruit causer par un tel mouvement, il s'agit généralement de prédire le mouvement de l'utilisateur dans le but de modéliser le filtre qui cause le bruit sur l'image pour enfin faire une déconvolution de ce filtre sur l'image. L'action de prendre une photo avec un tel bruit peut être décrit avec la formule suivante :

v = convolution(u, k) + n

v étant la photo finale, k le filtre généré par le mouvement et n un bruit blanc additionnel. Avec la possibilité de prendre plusieurs images dans un cours laps de temps que nous offrent la majorité des appareils mobiles, il est possible de modéliser plusieurs filtres ayant moins d'impacts sur le résultat final. Une méthode donnant des résultats impressionnants a été proposée par Haichao Zhang dans l'article suivant. Par contre, l'idée de faire les calcule sur un appareil mobile devient impossible puisque le temps de calcules est de l'ordre des heures. Le texte qui suit implémente les idées de Mauricio Delbracio dans son article "Burst Deblurring: Removing Camera Shake Through Fourier Burst Accumulation". Qui présente une manière coutant un minimum de mémoire et de temps de calcul grâce à sa simplicité.
Figure 0: Amélioration d'images par algorithme


Figure 1: Mouvement de la caméra lors d'une prise d'une séquence d'images


Approche

Puisque la résolution d'équations pour trouver les filtres sont trop couteux en temps d'exécution, l''auteur propose de travailler dans le domaine de Fourier. Le filtre causer par le mouvement aura une direction aléatoire pour chaques images prises (Voir figure 1). Puisque le mouvement de la caméra suppose un ajout de lumière sur les autres pixels, le filtre ne peut pas être négatif. L'idée est que puisque les mouvements sont aléatoires pour chacun des images, des fréquences différentes dans les images seront atténués. Puisque le filtre n'augmente pas la magnitude de la transformé de fourier, il s'agit de regrouper dans l'image finale la plus haute magnitude des images subséquentes.



La procédure est simple, il s'agit de prendre M images le plus rapidement possible, d'appliquer l'homographie pour aligner chacune des images vers la première et appliquer les formules précédentes. Le projet présenté utilise l'algorithme de recherche des marqueurs FAST et BRIEF ainsi que RANSAC pour appareiller ceux-ci. Finalement, plus le paramètre p est élevé, plus il y aura un bruit dans l'image, des filtres peuvent être appliqués pour minimiser ce bruit.


Figure 2: Le graphique suivant présente un exemple ou M = 14 et les résultats en fonction de p.


Implémentation

Le principe est mathématiquement très simple, il s'agit simplement de faire des transformés de fouriers et des opérations de bases sur les images. Par contre, la difficulté de cet implémentation est d'être efficace sur un appareil mobile ayant des capacités relativement basse. Plusieurs technicalités doivent être mis en premier plan : la puissance du processeur, la quantité de RAM alloué pour l'application, le type de caméra sur l'appareil et ses méthodes de captures. Le programme à été écrit pour Android entièrement en Java. L'appareil mobile utilisé pour les tests est un MotoG avec la version d'android 5.0.2. Pour des soucis de compatibilité, l'ancien API de caméra à été utilisé. Le téléphone à un total de 1 Gb de RAM et un coeur ARM Cortex-A7.



Figure 3: Vue principale et vue des options de l'application android


Prise d'images

Pour le développement d'applications mobile, des considérations doivent être pris lorsqu'une prise d'image "hors norme" doit être fait c'est à dire, lorsque le contrôle des paramètres de celle-ci doivent être choisis par l'utilisateur. Dans le cas présent, les contraintes n'ont pas une répercussion significative, mais il est important de les prendres en considérations. En premier lieu, il faut laisser la possibilité à l'utilisateur de sélectionner le temps d'exposition puisque l'avantage de la méthode est la possibilité de faire de telle photographie avec un appareil mobile. Ensuite, il faut s'assurer de retirer les modes automatiques de certains paramètres. Finalement, la capture de données doit se faire en un clic et le plus rapidement possible. Cet aspect sera différent en fonction du matériel utilisé et affecte seulement l'ergonomie du logiciel. Avec le MotoG et l'API Camera(1) un temps de 700 ms par photo a été atteint. Une amélioration notoire pour cette section serait d'utiliser l'API Camera2 et un appareil plus récent. Si le matériel le permet, Camera2 contient un mode "Burst" accéléré par le matériel. Dans iOs l'API est très puissant pour ce type d'opération.

Vitesse du processeur

Il s'agit d'une contrainte importante, car la prise de l'image est suivie d'un traitement relativement long comparativement à la prise d'une image normale. En effet, aligner les images ainsi que de faire les fft M fois reste couteux sur un appareil mobile. Dans l'implémentation proposée, le temps de traitement pour une image est d'environ 10 secondes. Le temps pourrait être réduit considérablement avec les modifications suivantes: Utiliser une librairie de FFT native (C++) au lieu d'une libraire écrit entièrement en JAVA. Utiliser un algorithme de détection des marqueurs plus efficace que BRIEF comme SIFT. Utiliser un algorithme plus efficace que RANSAC. Il serait possible d'utiliser les capteurs dans l'appareil pour aligner les images, il s'agit de données "gratuites". Il serait possible d'optimiser la parallélisation des calculs.

Mémoire

Finalement, la quantité limité de mémoire RAM par application dans un téléphone de moins haute gamme comme le MotoG rend le traitement d'images très difficile. En effet pour un image de résolution acceptable (1000x1000) RGB, un buffer de 3Mb doit être alloué. Nécessairement, les calcules sont fait en double précision ce qui augmente la taille de l'image à 24Mb. Considérant que sur le MotoG, 24 Mb est alloué pour un application non natif, et que l'algorithme doit traiter M images, le code doit être rapidement optimisé. En premier lieu, l'algorithme ne nécessite pas que tout les images soit en mémoire en même temps, et nécessite trois buffers soit : le poid total (w) de l'image, l'image en cours de traitement, la valeur total des fft calculés (qui revient au double du buffer image pour stocker les réel et les nombres imaginaires). De plus, il est important de savoir que le code natif ne compte pas dans la limite calculé par android. L'utilisation d'OpenCV permet de mettre certains buffer en dehors de cette limite. Dans le cas de MotoG, le système s'exploitation lance un erreur après 95 Mb. Pour l'application, les contraintes suivantes on été appliqué pour permettre de faire les tests: Traitement sur des images grises. Photographie en nuances de gris Diminution de la résolution ~(1000x2000) Réutilisation des buffers.

Résultats





Figure 4: p=0 et p=8



Figure 5: Burst d'images

Discussion : En regardant de plus près, chaque image a un flou particulier. En regardant le résultat p=8, la définition de la bouteille ainsi que le V est augmenté par rapport à toutes les images. Avec un certain zoom sur les images, les deux branches du V ne sont jamais bien définies dans la même image, par contre, l'image 4 et 6 contiennent chacun une branche avec un gradient fort. Dans la sortie, l'information des deux images est gardée dans la même image. Ensuite on peu remarquer que les lignes verticales du V reste flou. Cela est dû au fait qu'il y avait toujours un aspect horizontal dans la prise des données, d'où l'importance du fait que la capture d'image suppose des mouvements totalement aléatoires.



Figure 6: zoom sur l'image 5 et 7 ainsi que le résultat p=8









Problèmes rencontrés

Un des aspects les plus importants pour ce type d'algorithme est l'alignement initial des images, non seulement c'est couteux en temps d'exécution, mais la précision doit être le plus parfait possible. Si plusieurs images sont déphasé une par rapport à l'autre, les résultats se retrouvent bruités. Dans le cas présent, l'implémentation ne protège pas l'utilisateur contre tout mauvaise alignement, ce qui peut engendrer des mauvais résultats. De plus, la détection des correspondances entre les images peut être difficile si l'image est trop flou par rapport à l'autre. De plus, un traitement semble être fait sur la photo lors des déplacements de l'appareil ce qui apporte des distortions à la photo, nécessairement des distortions non linéaires dans certaines sections de l'image rend l'alignement très difficile.

Finalement, beaucoup d'améliorations sont nécessaire en terme de materiel pour rendre l'application viable sur le marché. En effet, présentement l'application prend un total de 90 Mb de RAM dans le pire cas, ce qui peu être limité sur certains appareils, ensuite le temps de calcules est d'environ 1 seconde par photos pour un total de 5 secondes pour un burst de 5 photos, ce qui est long pour une prise d'image aujourd'hui. Le fait d'augmenter le nombre d'image peu permettre un meilleur résultat.