Décidément, le refocusing est à la mode. Après Nokia, c'est au tour de Google de proposer la même fonctionnalité en natif avec la mise à jour de son application Camera pour Android. Même si dans l'idée les deux fonctionnalités sont similaires, l'approche de Google est totalement différente de celle de Nokia. Petit focus sur deux approches de refocus...

refocusExampleGoogle.png

Le refocus permet de changer la zone de mise au point de l'image a posteriori, c'est à dire après la prise de vue. Finies donc les images floues ! De plus, on peut parfois, comme sur un réflex, contrôler la profondeur de champ en floutant plus ou moins les parties de l'images en dehors de la zone de focus, ce qui permet de mettre en avant le sujet et de focaliser l'attention sur ce dernier. Un réflex, fait ça très bien, mais de façon définitive lors de la prise de vue. Les appareils photo compacts ou les smartphones ne peuvent en théorie pas avoir une profondeur de champ très réduite à cause de la miniaturisation des capteurs et des systèmes optiques. Il faut alors la recréer artificiellement à partir d'une ou plusieurs prises de vue.

Retour sur le cas de Lytro

Pour ne pas à avoir à repartir de zéro, je vous conseille de lire en préambule mon précédent article sur le refocus Nokia. Pour les feignants, je vais tâcher de vous faire un petit résumé : en substance, je vous expliquais que le principe de base de Nokia était d'effectuer une rafale d'images avec différentes mises au point. Ces différentes images comportent des régions plus ou moins nettes en fonction de la distance de l'objet par rapport à la distance de focus.

Pour refaire le focus sur une partie de l'image, il suffit alors de sauvegarder la totalité de ces images et de choisir celle qui est la plus nette dans la zone sélectionnée manuellement. Pour faire la mise au point sur toute l'image (focus étendu), on prend uniquement les zones nettes sur chacune des images de la plage de focus pour reconstruire une nouvelle image nette en tous points.

L'approche stéréo de Google

L'approche choisie par Google est différente puisqu'au lieu d’acquérir des images en faisant bouger la lentille pour changer le focus, cette fois, ils ont choisi de nous faire bouger l'appareil. On doit alors décrire un mouvement vertical avec le téléphone, le temps pour lui d'acquérir plusieurs photos en translation. La technique employée ici s'approche du coup plus de la stéréo-vision utilisée par Lytro. En effet, tout comme notre cerveau nous permet d'apprivoiser la profondeur d'une scène grâce aux différences entre les images capturées par nos deux yeux, Google reconstruit alors la 3D de la scène grâce aux différences de contenus entre les images successives.

Cela permet ensuite d'obtenir une carte de profondeur de la scène. L'approximation de dite de "la lentille mince" permet alors, via des lois optiques simples enseignées au lycée, de calculer la taille du flou correspondant au bokeh pour une ouverture et une distance au focus donnée. On peut alors flouter artificiellement un à un les pixels de l'image en fonction de l'information de profondeur de la scène.

refocusExample2Google.png

Changer le focus revient alors à recalculer le flou à appliquer à chacun des pixels pour la nouvelle distance au focus. On a donc un petit temps de calcul à chaque fois que l'on augmente la taille du flou ou que l'on change le point de focus pour faire un rendu sympa.

C'est si simple que ça ?

Dans le cas de Nokia, les limitations que j'avais mises en évidence sont évidemment toujours présentes : pour mémoire, sur les bords des objets, définir la limite entre un objet net et flou est difficile. De plus, il manque l'information contenue derrière les zones d'occultation, c'est à dire le bord des objets flous que l'on cherche à rendre nets. On voit donc des artefacts de fusion sur les images dans le cas de la génération d'une image infiniment nette, comme sur l'image ci-dessous.

Artefacts sur les bords des objets

Pour Google, les problèmes sont d'un autre ordre. En effet, il est très difficile d'estimer la 3D d'une scène de manière précise et continue. Contrairement à notre oeil qui fait ça naturellement, les ingénieurs ont ici eu besoin d'utiliser le plus d'images possible afin de rendre plus robuste cette estimation. Dans la réalité, cette phase d'estimation cache plusieurs étapes toutes aussi complexes et plus ou moins sensibles aux conditions de prise de vue, à savoir la calibration, la rectification et l'appariement.

Je vais essayer de résumer leur utilité de manière compréhensible :

  • La calibration permet de déterminer les différentes positions relatives de la caméra entre les différentes prises de vue. En effet, l'utilisateur tient la caméra à main levée donc rien ne dit que le mouvement de son bras est strictement rectiligne. On peut imaginer qu'il effectue de légères rotations ou un mouvement en S par exemple, qu'il faut estimer.[1]
  • La rectification, quant à elle, a pour but de compenser artificiellement ces légères rotations préalablement estimées pour faire en sorte que le mouvement soit approximativement assimilable à une translation. Cela permet de faire une hypothèse simplificatrice dans l'étape suivante.[2]
  • L'appariement sert enfin à repérer la position d'un même objet sur des images successives. En connaissant les positions relatives de la camera pour chacune des images et la position relative des objets au sein de ces images, on en déduit la position de l'objet et donc sa distance à la caméra.[3]

Bref, tout ça pour vous faire comprendre que ça n'est pas si simple que ça en a l'air. D'un côté Nokia effectue une simple mesure de netteté et fusionne ses images en fonction de cette dernière. De l'autre Google effectue une quantité non négligeable de calculs sur un paquet d'images afin de reconstituer la 3D de la scène et de faire un flou convainquant. Pourquoi diable ont-ils choisi un algorithme aussi compliqué ?

La stratégie de Google : la flexibilité

Ils ne sont pas si fous chez Google. S'ils ont choisi de faire autant de calculs, c'est pour une bonne raison : la flexibilité. L'approche de Nokia est limitée par l'ouverture de leur appareil photo intégré. Sur les smartphones, la miniaturisation de ce que l'on appelle les "camera modules" conduit à des diaphragmes tout petits. Pour une ouverture équivalente à un réflex, on a alors un flou beaucoup plus petit (ou une profondeur de champ plus grande, c'est équivalent). On ne peut pas physiquement avoir un bokeh aussi joli que sur un reflex. C'est d'ailleurs le point faible de l'approche de Nokia : à moins d'avoir des objets proches et éloignés de l'objectif, le bokeh initial sur les images est très petit, voire inexistant.

Avec une approche stéréoscopique, la reconstitution des zones d'occultations est possible dans une certaine mesure ! En effet, le mouvement de la caméra permet d'enregistrer plusieurs points de vue d'une même scène, ce qui permet de "voir" alors un peu derrière le bord des objets.

focusLampeGoogleRefocus.jpg

Ca permet du même coup de construire un flou plus grand que le flou d'origine de l'image. En théorie, l'ouverture maximale que l'on peut ainsi reconstituer sans artefacts est fonction de l'amplitude du mouvement effectué. En pratique, ils s'autorisent à aller un peu plus loin, quitte à faire des transitions pas forcément très esthétiques comme sur l'image ci-dessus.

Pour reconstruire parfaitement l'information, il est en théorie nécessaire de mesurer la disparité dans deux directions, c'est à dire d'acquérir des images verticalement ET horizontalement. C'est d'ailleurs ce qui est fait par Lytro au sein d'un unique caméra, avec sa disposition particulière de capteurs et ses réseaux de lentille. Google ne le fait pas. Il est fort à parier qu'étant donné que les images sont prises les unes après les autres, il est nécessaire de discriminer le mouvement de l'appareil et le mouvement des objets dans la scène. Ils partent alors du postulat qu'il est plus probable de voir un objet qui se déplace horizontalement que verticalement (voiture, piéton...). Du coup si un objet à bougé entre deux images (ce qu'on appelle un ghost), il y a un risque de biaiser l'estimation de la distance : on essaie de voir ainsi décorréler les mouvements dus à la caméra de ceux dus aux mouvements des objets pour éviter le problème.

Lytro évite le problème précédent, car son système optique lui permet de captuer simultanément les différentes prises de vue, c'est d'ailleurs ce qui justifie le prix de leur appareil. Nokia, pour sa part, acquiert également plusieurs images à la suite, donc peuvent potentiellement avoir du ghost entre leurs images. Cependant, lors du refocus, une seule image est choisie, ce qui élude le problème. Il n'y a que lorsque la profondeur de champs est étendue par fusion d'images qu'il est nécessaire de faire attention aux ghosts. N'ayant pu jouer avec autrement qu'avec des images de démo, je n'ai pas pu voir si leur antighost est réellement efficace ou pas.

Conclusions

Aujourd'hui les résultats de l'algorithme de Google ne sont pas extraordinaires, mais il s'agit déjà d'un algorithme plus flexible que celui de Nokia. Les principaux artefacts sont situés sur les bords des objets.[4] Le problème est que pour robustifier l'estimation de la carte de distances, il faut implémenter des méthodes assez gourmandes qui nécessitent du temps de calcul supplémentaire, ce qui nuit à l'ergonomie de l'application.

focusPlanteGoogleRefocus.jpg

Il est actuellement nécessaire d'attendre une petite dizaine de secondes avant la génération de l'image de sortie, le temps que tous les calculs soient effectués. Il y a bien entendu plusieurs pistes d'amélioration qui consistent à utiliser d'avantage les données contenues dans les autres images lors de la fusion ou de régulariser un peu moins fortement la carte de disparité sur les contours, mais je ne doute pas que les équipes de Google travaillent déjà dessus.

Si le rendu est actuellement largement suffisant pour faire de l'instagram-like, vous ne pourrez pas encore faire des impressions A4 de vos images dès demain, surtout que les images en sortie de l'algo sont limitées à 1Mpx pour le moment. Et même si je chipote, sortir une image aussi rapidement avec des algorithmes aussi complexes est déjà une prouesse en soi et il y a fort à parier qu'il risque d'évoluer au cours de futures mises à jour.

Source : Plus (ou moins) de détails sur le blog de Google dédié aux thématiques de recherche

Notes

[1] On peut par exemple citer le papier de Zhang qui est assez complet sur le sujet : A Flexible New Technique for Camera Calibration

[2] En bref et en barbare, cela permet de simplifier les équations des lignes épipolaires pour diminuer la complexité du matching. A ceci près qu'au delà de 3 positions, l'existence du plan épipolaire n'est plus garantie et que l'on ne peut plus garantir l'horizontalité et la verticalité des lignes épipolaires.

[3] Il existe plein de méthodes différentes qui permettent d'effectuer une telle étape. Elles sont toutes plus ou moins basées sur la même technique : il suffit grosso modo de trouver le pixel qui minimise la valeur absolue de la différence entre son voisinage et un patch (un groupement de pixels voisins) de l'image choisie.

[4] Ils considèrent que deux pixels proches ont des distances proches, ce qui n'est pas toujours le cas et peut conduire à des erreurs d'estimations.