Date limite: 12 avril 2015 à 23h59
Deadline: 23h59 on April 12th, 2015
Le but de ce projet est de vous familiariser avec les images à haute plage dynamique (High Dynamic Range ou HDR), l'éclairage à base d'images (Image Based Lighting ou IBL), et de leurs applications. À la fin de ce travail, vous serez en mesure de créer des images HDR à partir d'ensembles d'images à plage dynamique faible (Low Dynamic Range ou LDR) et, aussi, d'ajouter des objets 3D dans les photos en utilisant des techniques d'éclairage à base d'images.
La photographie HDR est la méthode de capture des photos contenant une plage dynamique plus grande que ce que les photos normales contiennent (c'est-à-dire qu'elles contiennent des valeurs de pixels en dehors de la plage standard des images LDR entre 0-255 et contiennent plus de précision). La plupart des méthodes pour créer des images HDR impliquent la fusion de plusieurs images LDR à diverses expositions, ce que vous ferez dans ce projet.
Les images HDR sont utilisées dans une grande variété d'applications, telles que l'amélioration du contraste, l'art hyper-réaliste, des ajustements d'intensité post-traitement, et l'éclairage à base d'images. Nous allons nous concentrer sur leur utilisation dans l'éclairage à base d'images, spécifiquement sur la "ré-illumination" d'objets virtuels. Une façon de ré-illuminer un objet est de capturer une image HDR panoramique 360 degrés (omnidirectionnelle) d'une scène qui fournit des informations d'éclairage sur tous les angles incident à la caméra (d'où le terme éclairage à base d'images). La capture d'une telle image est difficile avec des caméras standards, car cela nécessite à la fois de l'assemblage de photos et de la conversion LDR à HDR. Une alternative plus facile consiste à capturer une photographie HDR d'un miroir sphérique ce qui fournit les mêmes informations d'éclairage omnidirectionnel (jusqu'à certaines limites physiques dépendant de la taille de la sphère et de la résolution de la caméra).
Dans ce TP, nous utiliserons l'approche du miroir sphérique. Avec cette image panoramique HDR, nous pouvons alors ré-illuminer des modèles 3D et les ajouter harmonieusement dans des photographies.
The goal of this project is to familiarize yourself with high dynamic range (HDR) imaging, image-based lighting (IBL), and their applications. By the end of this project, you will be able to create HDR images from sequences of low dynamic range (LDR) images and also learn how to composite 3D models seamlessly into photographs using image-based lighting techniques.
HDR photography is the method of capturing photographs containing a greater dynamic range than what normal photographs contain (i.e. they store pixel values outside of the standard LDR range of 0-255 and contain higher precision). Most methods for creating HDR images involve the process of merging multiple LDR images at varying exposures, which is what you will do in this project.
HDR images are widely used by graphics and visual effects artists for a variety of applications, such as contrast enhancement, hyper-realistic art, post-process intensity adjustments, and image-based lighting. We will focus on their use in image-based lighting, specifically relighting virtual objects. One way to relight an object is to capture an 360 degree panoramic (omnidirectional) HDR photograph of a scene, which provides lighting information from all angles incident to the camera (hence the term image-based lighting). Capturing such an image is difficult with standard cameras, because it requires both panoramic image stitching and LDR to HDR conversion. An easier alternative is to capture an HDR photograph of a spherical mirror, which provides the same omni-directional lighting information (up to some physical limitations dependent on sphere size and camera resolution).
In this homework, we will take the spherical mirror approach. With this panoramic HDR image, we can then relight 3D models and composite them seamlessly into photographs.
Le travail à effectuer est divisé en trois étapes principales:
Chacune de ces étapes sont décrites plus bas.
This homework is divided into three main steps:
The steps are described in more details below.
Dans cette partie du travail, vous devez capturer plusieurs expositions d'une balle métallique placée dans la scène d'intérêt, et fusionner ces expositions en une seule image à haute plage dynamique.
Ce que vous avez besoin:
You will need:
Pour collecter vos données,
To collect your data,
À cette étape, notre but est de construire une carte de radiance HDR à partir de plusieurs exposition LDR (Low Dynamic Range). Pour ce faire, nous utiliserons l'algorithme vu durant le cours, et décrit dans les sections 2.1 et 2.2 de Debevec et Malik 1997. Nous vous conseillons de lire cet article attentivement pour bien comprendre ce processus. Vous trouverez un résumé de l'algorithme ci-dessous.
La valeur de pixel observée Zij pour le pixel i d'une image j est une fonction de la radiance d'une scène (inconnue) et d'une durée d'exposition (connue):
Ei est la radiance de la scène au pixel i, et l'intégrale dans le temps de la radiance de la scène Ei x Δtj est l'exposition a un pixel donné. Afin de rendre le problème linéaire, nous résolvons pour g=ln(f-1), qui place les valeurs des pixels (de 0 à 255) sur le log des valeurs d'exposition:
(équation 2 dans l'article de Debevec). Résoudre g peut sembler impossible (et, en effet, nous pouvons uniquement retrouver g jusqu'à un facteur d'échelle) puisque nous ne connaissons ni g, ni Ei. La solution provient du fait que la scène soit statique. Ainsi, bien que nous ne puissions pas connaître la valeur absolue de Ei à chaque pixel i, nous savons que cette valeur reste constante sur toutes les images d'une séquence.
Pour rendre les résultats robustes, il nous faudra deux détails supplémentaires:
We want to build an HDR radiance map from several LDR exposures. It is highly recommended that you read Sections 2.1 and 2.2 in Debevec and Malik 1997 to help understand this process. Below is a summary.
The observed pixel value Zij for pixel i in image j is a function of unknown scene radiance and known exposure duration:
Ei is the unknown scene radiance at pixel i, and scene radiance integrated over some time Ei x Δtj is the exposure at a given pixel. We will not solve for f, but for g=ln(f-1) which maps from pixel values (from 0 to 255) to the log of exposure values:
(equation 2 in Debevec). Solving for g might seem impossible (and indeed, we only recover g up to a scale factor) because we know neither g nor Ei. The key observation is that the scene is static, and while we might not know the absolute value of Ei at each pixel i, we do know that the value remains constant across the image sequence.
To make the results robust, we consider two additional things:
Maintenant que nous avons une image HDR du miroir sphérique, il nous faut maintenant la convertir dans un format panoramique 360 degrés pouvant être utilisé dans un engin de rendu (voici un lien vers un résumé des différents formats). Pour cette partie du travail, vous allez implémenter la transformation passant de l'espace sphère miroir à l'espace équi-rectangulaire (latitude, longitude). La plupart des logiciels de rendu acceptent ce format, y compris le "Cycle" de "Blender", le logiciel que l'on utilisera à l'étape suivante.
Pour effectuer la transformation, votre tâche sera de déterminer la correspondance entre le domaine du miroir sphérique et le domaine équi-rectangulaire. Un conseil: calculez les normales de la sphère (N
) et assumez que la direction d'observation (V
) est constante (projection orthographique). Vous pouvez calculer les vecteurs de réflexion grâce à R = V - 2 .* dot(V,N) .* N
. Les vecteurs de réflexion doivent être ensuite convertis en considérant la latitude et la longitude (phi
et theta
) d'un pixel donné (en fixant la distance à l'origine, r
, à 1).
Pour générer une image équi-rectangulaire, créez tout d'abord une image vide, où les lignes correspondent à theta (l'élévation, ou la latitude), et les colonnes à phi (l'azimuth, ou la longitude). Dans Matlab [phis, thetas] = meshgrid([pi:pi/360:2*pi -pi/2:pi/360:pi/2], 0:pi/360:pi)
. Maintenant que vous avez les phi/theta pour l'image de la sphère miroir et pour l'image du domaine équi-rectangulaire, utilisez la fonction Matlab scatteredInterpolant
ou TriScatteredInterp
pour effectuer la transformation.
Finalement, sauvegardez le panorama en format HDR: hdrwrite(latlon, 'latlon.hdr')
.
Now that we have an HDR image of the spherical mirror, we'd like to use it for relighting (i.e. image-based lighting). However, many rendering programs don't accept the "mirror ball" format, so we need to convert it to a different 360 degree, panoramic format (there is a nice overview of many of these formats here). For this part of the project, you should implement the mirror ball to equirectangular (latitude longitude) transformation. Most rendering software accepts this format, including Blender's Cycles renderer, which is what we'll use in the next part of the project.
To perform the transformation, you need to figure out the mapping between the mirrored sphere domain and the equirectangular domain. Hint: calculate the normals of the sphere (N
) and assume the viewing direction (V
) is constant. You can calculate reflection vectors with R = V - 2 .* dot(V,N) .* N
, which is the direction that light is incoming from the world to the camera after bouncing off the sphere. The reflection vectors can then be converted, providing the latitude and longitude (phi
and theta
) of the given pixel (fixing the distance to the origin, r
, to be 1). Note that this assumes an orthographic camera (which is a close approximation as long as the sphere isn't too close to the camera).
Next, the equirectangular domain can be created by making an image in which the rows correspond to theta
and columns correspond to phi
in spherical coordinates, e.g. [phis, thetas] = meshgrid([pi:pi/360:2*pi 0:pi/360:pi], -pi/2:pi/360:pi/2)
. Now that you have the phi/theta for both the mirror ball image and the equirectangular domain, use matlab's scatteredInterpolant or TriScatteredInterp function to perform the transformation. Below is an example transformation.
Finally, save the panorama in an HDR format: hdrwrite(latlon, 'latlon.hdr')
.
Dans cette dernière étape, nous utiliserons notre image équi-rectangulaire HDR comme source lumineuse pour effectuer de l'éclairage à base d'images et insérer des objets 3D dans la scène. Cela se divise en trois étapes: la modélisation de la scène, le rendu et la composition. Dans cette étape, nous nous inspirerons d'un autre article du même Debevec, publié un an plus tard, soit en 1998.
Tout d'abord, téléchargez et installez la dernière version de Blender ici. Dans les fichiers fournis plus bas, trouvez le fichier .blend et ouvrez le avec le logiciel. Ce fichier .blend est celui qui a été utilisé pour créer le résultat dans le haut de la page. Notez que vous n'êtes pas obligés d'utiliser ce fichier, il ne vous est fourni qu'à titre d'exemple.
Next, we will use our equirectangular HDR image as an image-based light, and insert 3D objects into the scene. This consists of 3 main parts: modeling the scene, rendering, and compositing. Specific instructions follow below; if interested, see additional details in this other Debevec paper, published one year later.
Begin by downloading/installing the latest version of Blender here. In the example materials package below, locate the blend file and open it. This is the blend file used to create the result at the top of the page. The instructions below assume you will modify this file to create your own composite result, but feel free to create your own blend file from scratch if you are comfortable with Blender.
Pour insérer des objets dans une scène, nous devons, en plus de l'information d'illumination que nous avons capturée aux étapes précédentes, avoir une idée de la géométrie et des propriétés des surfaces de la scène. À cette étape, vous allez créer manuellement une géométrie approximative de la scène en utilisant Blender.
Une fois que le fichier .blend est ouvert dans Blender, ajoutez votre image d'arrière-plan à votre scène. Dans la fenêtre de visualisation 3D en bas à droite, trouvez "Background Images". Cliquez sur "Add image" et ensuite sur "Open" pour ajouter votre image d'arrière-plan de l'étape 5 de l'étape de collecte de données. Assurez-vous que votre point de vue soit par rapport à la perspective de la caméra en appuyant sur "View->Camera" (ou "View->Cameras->Active Camera"); vous devriez voir votre image à l'arrière-plan.
Ensuite, modélisez la "scène locale". Créez une scène 3-D simple (généralement, des plans suffisent) pour recréer la géométrie de la scène proche de l'endroit où vous voudriez insérer des objects. Pour de meilleurs résultats, cela devrait être fait proche d'où vous avez placé le miroir sphérique. Après que la scène 3-D ait été placée correctement, spécifiez les paramètres de surface ("materials"): sélectionnez une partie de la géométrie de la scène locale, allez à "Properties->Materials", ajoutez un matériel avec une BSDF "Diffuse" et modifiez la "Color" pour qu'elle ressemble approximativement à la couleur de la photo.
Ensuite, ajoutez votre image HDR (la carte équi-rectangulaire créée précédemment) à la scène. Dans la languette "Properties->World", assurez-vous que Surface="Background" et Color="Environment Texture". Ajoutez le nom de votre image HDR sauvegardée dans le champ approprié sous "Environment Texture".
Finalement, insérez des objets synthétiques dans la scène. Vous pouvez utiliser les modèles standards à l'intérieur du fichier .blend inclus sur cette page, ou vous pouvez trouver vos propres modèles (e.g. Turbosquid, Google 3D Warehouse, DModelz, etc). Ajoutez aussi des matériaux intéressants à vos objets insérés. Ce tutoriel est une superbe introduction à la création de matériaux dans Blender. Une fois tout terminé, votre scène devrait ressembler à l'image de droite ci-dessous.
To insert objects, we must have some idea of the geometry and surface properties of the scene, as well as the lighting information that we captured in previous stages. In this step, you will manually create rough scene geometry/materials using Blender.
With the sample blend file open, add your background image to the scene. In the 3D view window near the bottom right, locate "Background Images". Make sure this is checked, and click "Add image", then click "Open" and locate your background image from step 5 of data collection. Make sure your view is from the camera's perspective by pressing View->Camera (or View->Cameras->Active Camera); you should see your image in view.
Next, model the "local scene." That is, add simple geometry (usually planes suffice) to recreate the geometry in the scene near where you'd like to insert objects. For best results, this should be close to where you placed the spherical mirror. Feel free to use the sample scene provided and move the vertices of the plane to match the surface you'd like to recreate (ignore the inserted bunny/teapot/etc for now). Once you're happy with the placement, add materials to the local scene: select a piece of local scene geometry, go to Properties->Materials, add a Diffuse BSDF material, and change the "Color" to roughly match the color from the photograph.
Then, add your HDR image (the equirectangular map made above) to the scene. In the Properties->World tab, make sure Surface="Background" and Color="Environment Texture". Locate your saved HDR image in the filename field below "Environment Texture".
Finally, insert synthetic objects into the scene. Feel free to use the standard models that I've included in the sample blend file, or find your own (e.g. Turbosquid, Google 3D Warehouse, DModelz, etc). Add interesting materials to your inserted objects as well. This tutorial is a great introduction to creating materials in Blender. Once finished, your scene should now look something like the right image below.
Nous pouvons maintenant effectuer le rendu de la scène. Assurez-vous que "Cycles Render" soit sélectionné dans le haut de l'interface de Blender et, ensuite, de faire le rendu de la scène (F12). Votre rendu pourrait être trop clair/sombre, car il existe un facteur d'échelle inconnu pour l'illumination: il doit donc être déterminé manuellement. Pour ce faire, ajustez l'intensité lumineuse (languette "Properties->World", ajustez le réglage "Strength" sous "Color" en conséquence). Une fois que vous êtes satisfaits de la luminosité, sauvegardez le résultat du rendu sur votre disque dur.
Cela n'est pas tout à fait le résultat final. Pour insérer les objets harmonieusement, nous devons suivre une procédure de composition décrite par Debevec (Section 6 de l'article de 1998).
D'abord, nous allons faire le rendu de la scène "vide" (sans les objets). Créer une copie de votre scène blender et nommez-la ibl-empty.blend. Ouvrez votre copie, retirez tous les objets, mais conservez la géométrie de votre scène locale. Faites le rendu de cette scène et sauvegardez le résultat.
Finalement, nous aurons besoin d'un masque binaire des objets. Le masque doit être 0 où il n'y a pas d'objets insérés et plus grand que 0 autrement. Créez une autre copie de votre scène et ouvrez-la (e.g. ibl-mask.blend). Nous pouvons créer le masque facilement en utilisant Blender; cela se fait en manipulant le matériel des objets et leurs propriétés de rendu:
We can now render the scene to see a preview of what the inserted objects will look like. Make sure "Cycles Render" is selected at the top of Blender's interface, and then render the scene (F12). Your rendering might be too bright/dark, which is caused because we don't know the absolute scale of the lighting, so this must be set manually. To fix, adjust the light intensity (Properties->World tab, adjust "Strength" setting under "Color" accordingly). Once you're happy with the brightness, save the rendered result to disk.
This is not quite the final result. To seamlessly insert the objects, we need to follow the compositing procedure outlined by Debevec (Section 6 of the paper).
First, we'll render the "empty" scene (without inserted objects). Create a copy of your blender scene and name it something like ibl-empty.blend. Open up the copy, and delete all of the inserted objects (but keep the local scene geometry). Render this scene and save the result.
Finally, we need to create an object mask. The mask should be 0 where no inserted objects exist, and greater than 0 otherwise. Create another duplicate of your scene and open it up (e.g. ibl-mask.blend). We can create the mask quickly using Blender by manipulating object materials and rendering properties:
Après ces étapes, vous devriez obtenir des images similaires à celles-ci:
After these steps, you should have the following three rendered images:
Pour finir l'insertion d'objets, nous allons utilisez les images rendues précédemment pour effectuer une composition par "rendu différentiel". Cela peut être fait par une simple équation à appliquer pour chaque pixel. Si R
est l'image rendue avec les objets, E
l'image rendue sans les objets, M
le masque des objets et I
l'image d'arrière-plan. La composition finale est calculée avec:
composite = M.*R + (1-M).*I + (1-M).*(R-E).*c
Cette équation est décrite dans la section 6 de l'article de Debevec 1998. Les deux premiers termes copient les objets insérés dans l'image d'arrière-plan et le troisième terme, modulé par c
ajoute les effets d'illumination des objets insérés (ombres, caustiques, les inter-réflexions, etc.). Fixez c=1
initialement, mais ensuite essayez différentes valeurs pour obtenir des ombres et inter-réflexion plus sombres ou plus claires. Un exemple d'un résultat de composition obtenu en utilisant cette approche est affichée en haut de la page.
To finish the insertion, we will use the above rendered images to perform "differential render" compositing. This can be done using a simple pixel-wise equation. Let R
be the rendered image with objects, E
be the rendered image without objects, M
be the object mask, and I
be the background image. The final composite is computed with:
composite = M.*R + (1-M).*I + (1-M).*(R-E).*c
This equation is described in sec. 6 of the 1998 Debevec paper. The first two terms effectively paste the inserted objects into the background image, and the third term adds the lighting effects of the inserted objects (shadows, caustics, interreflected light, etc), modulated by c. Set c=1 initially, but try different values to get darker or lighter shadows/interreflections. An example of a final compositing result achieved using this is at the top of the page.
Quelques conseils pour résoudre g
:
w
devraient être implémentée en utilisant Eq. 4 de l'article (i.e. w = @(z) double(128-abs(z-128))
).lambda
pour retrouver g
. Initiallement essayez lambda=1
, résolvez g
et affichez-le. Il devrait être lisse et augmenter continuellement. Si lambda
est trop petit, g
va être bosselé.g
et combiner toutes vos expositions dans une image finale. Notez que cela produit les valeurs log de la radiance, donc assurez-vous de faire l'exponentielle du résultat et de sauvegarder la radiance absolue.Quelques conseils sur Blender:
Some hints on solving for g
:
w
should be implemented using Eq. 4 from the paper (i.e. w = @(z) double(128-abs(z-128))
).lambda
values for recovering g
. Try lambda=1
initially, then solve for g
and plot it. It should be smooth and continuously increasing. If lambda
is too small, g
will be bumpy.g
and combining all of your exposures into a final image. Note that this produces log radiance values, so make sure to exponentiate the result and save absolute radiance.Some tips on using Blender:
Essayez une de ces idées pour approfondir vos connaissances (et augmenter votre note):
Try one of these ideas to increase your understanding on this subject (and increase your score):
Comme lors des travaux précédents, celui-ci sera remis dans un format page Web. Rappel: le site Web n'a pas besoin d'être esthétiquement agréable; ne faites que décrire ce que vous avez fait.
Plus précisément, la page devrait:
As in the previous homework, this one will be handed in a webpage format. Remember: the aesthetics of the website will not be evaluated, but it is important that the information be presented clearly.
More precisely, the webpage should:
Ce travail est évalué sur 100 points. La répartition des points va comme suit:
g
et comment vous avez calculé la radiance. Illustrez vos résultats (vous pouvez utiliser une reproduction tonale simple pour afficher vos images HDR).This assignment is evaluated on 100 points, as follows:
Pour la remise de votre travail, créez un fichier tp5.zip
qui contient:
tp5/web
. Vos images doivent être dans un dossier tp5/web/images
.tp5/web/index.html
. De plus, assurez-vous qu'il n'y a aucun caractère spécial (accent, ponctuation, espace, etc.) dans les noms de vos fichiers, images, etc.tp5/code
. N'incluez pas les images que vous avez utilisées pour produire vos résultats dans ce dossier dans le but de ne pas alourdir le fichier.Finalement, veuillez téléverser votre fichier tp5.zip
sur Pixel (http://pixel.fsg.ulaval.ca) avant la date limite. La politique des retards mentionnée dans le plan de cours sera appliquée. Pour toutes questions concernant la procédure de remise ou le travail lui-même, posez vos questions sur Piazza!
Attention! La taille limite permise sur Pixel est de 50MB. Assurez-vous que la taille du fichier tp5.zip
n'excède pas 50MB.
For this homework, you must create a tp5.zip
file. In this file you'll put:
tp5/web
. Your images for this web page should be inside a folder named tp5/web/images
.tp5/web/index.html
. Make sure none of the files have special characters (e.g. accents, punctuation, spaces, etc.) in their filenames. tp5/code
. Do not include the images you have used to generate your results inside this folder, as this will likely generate huge files.
Finally, you should upload this file (tp5.zip
) on Pixel (http://pixel.fsg.ulaval.ca) before the deadline. The late submission policy described in the course plan will be applied. For any question regarding the submission process or the project as such, ask your questions on Piazza!
Beware! File size limit on Pixel is 50MB. Make sure that your tp5.zip
file size does not exceed 50MB.
Merci à Derek Hoiem et Kevin Karsch d'avoir créé le TP original qui a servi d'inspiration pour celui-ci!
Many thanks to Derek Hoiem and Kevin Karsch for creating the assignment which inspired this one!