Project 4: Nonlinear 3D Image Warps


Overview:

In this final project you will view and warp a 2D image into several 3D panoramas, and use the viewer you made in Project 1 to display each of  them. Your program will:
    --- Read in a mirror ball or 'light probe' image that you like,
    --- Find all the non-mirror-ball parts of the image and move them out of the way,
    --- Warp the image into the 3D half-sphere shape that caused it,
    --- Warp the half-sphere to form a full 3D sphere panorama,
    --- Warp the sphere to make a cube panorama around the same center point.  
    --- Design an interesting 2D warp of your own, and apply it to the sides of the cube.  
The work you did in Project 1 will then allow you to view any of the warps from any angle or position.

User Interface: Trouble again.  Your program needs to allow users to trigger or select each stage of your transformation (planar input image, matted, half-sphere, panorama sphere, panorama cube, 2D warps on cube surface).  The best way would be a Windows/MFC user-interface widget of some kind, such as a drop-down menu, pushbutton, or perhaps open a different child window within the main window for each stage of the transformation.  If MFC is too unfamiliar and troublesome, you may instead  use a #define statement in one of your header (.h) files to choose one result, and submit multiple executable files along with your code; one for each display action. 

Input Images:  Look around on the web using terms like gazing orb, spherical mirror, spherical panorama, light probe, mirror ball panorama, etc.  Here are ones I've found for you and converted as needed to  Windows BMP format. 

Probably the first 'light-probe' image ever used in computer graphics, by Gene Miller in 1982

CZsvoboda.bmp            Two images from a Czech panoramic imaging project
CZsvoboda2.bmp            

Here's an artist's site showing an 'equirectangular' image that appears to be an ordinary spherical mapping, with several to choose from here. They used freely available  'PanoTools' written in Java that are worth playing with; I think they originate with Dersh here.  Two images I like:

 housedeck_flat.bmp, and housedeck_src.bmp    

beach_probe.bmp           From the collection of light probe images from Paul Debevec's team. 
building_probe.bmp        Their website uses a high contrast 'HDR' format, and use their very nice 
Galileo_probe.bmp           downloadable HDR format viewer to choose exposure settings, as I did here.
Grace_probe.bmp            
StPeters_probe.bmp
Uffizi_probe.bmp

Here's a Cylindrical Panorama Page has some beautiful (but non-spherical) input images too.  Another site for some beautiful cylindrical panoramas from Germany.

At this site, Jonathan Cohen of ICT uses light probes as inputs and finds synthetic light source intensities and locations that will reasonably simulate the lights.

Photoshop plugin for mirrorball images, complete with a tutorial on how to remove the photographer from the scene by photographing the ball twice, from 2 different angles.

 


Detailed instructions:

---1) View: Be sure your Project 1 code can read in a BMP file that holds a mirror-ball image, and display it as a texture map on a planar grid of OpenGL vertices. You should be able to 'click-drag' the mouse to make 3D viewing changes for that plane.
        If you wish, your program may use 'hard-coded' constants for image size (xmax,ymax), for grid size, and for the center an the radius of the image of the mirror ball, but these should be set by #define statements in one of your header (.h) files and clearly marked, so that it is easy to adjust or modify them for a different image. 
(Never put numerical constants in your code that depend on user preferences or input images).  

---2) Matte:  Find all the image vertices that are not a part of the mirror ball, and move them out of the way.  For example, if the image vertices are at location (x,y,0),  you could change the 3D coordinates of all the vertices that fall within the mirror ball's  radius to (x,y,1), and all other the others to (0,0,0).  This would move the mirror-ball part of the image away from the origin and 'gather together' all the unwanted vertices at the origin, forming a cone-like shape in 3D.

---3) Half-Sphere Warp:  Construct a half-sphere colored by the light probe image.
     For each mirror-ball vertex,
      a) Convert rectilinear image grid coordinates (x,y) to polar coordinates (r, theta) in the image.
      b) Convert these polar coordinates to spherical coordinates of the mirror ball.  For simplicity, assume the mirror-ball image is orthographic, e.g. that rays from the camera to the mirror ball surface are parallel, so the distance from the mirror ball to the camera that photographed it doesn't matter, and center the sphere at the origin.
        Thinking in 3D now (see figure in Homework 2), convert (r,theta) to spherical coordinates on the mirror ball (phi,theta), where phi is latitude and theta is longitude (phi=0 at the north pole, pi at the south pole).  Remember that when r=0 we have a zero-diameter circle on the image that matches a zero-diameter circle around the 'north pole' of the sphere.  Increasing radius r from zero corresponds to increasing 'longitude' phi from zero on the mirror ball sphere; find the mapping from r to phi.
     c) Move the vertex in 3D; place it at angular position (phi,theta) on a sphere around the origin.  You'll need to figure out how to convert spherical coordinates (phi,theta,r_s) to Cartesian coordinates (x,y,z). 
        Now the previously planar grid image has become a textured half-sphere shape in 3D: its colors are the image colors mapped to the mirror ball points that reflected them to the camera.

---4) Panoramic Sphere Warp:  Move the vertices again to change a half-sphere to a full sphere panorama:
    For each mirror-ball vertex,
    a) find the vertex position in spherical coordinates (or just remember it from step 3) as  (phi, theta, r_s).
    b) Though the vertex hold colors that were SEEN on the mirror ball at this position, it these light values did not arrive at the mirror ball from the (phi,theta) directions from the environment.    As discussed in class, the incoming light direction is phi'=2*phi, and theta,r_s are unchanged.  Accordingly, find the new 3D position (phi',theta,r_s) for each vertex.
    c) Convert to x,y,z position, and move the vertex there.
        Now your previously planar grid image has become a textured sphere shape, with a funny little 'dent' at the back where vertices not on the mirror sphere have collected at the origin. 

---5) Panoramic Cube Warp:  Move the vertices again to change a sphere to an axis-aligned cube:
    For each mirror-ball vertex,
    a) Use its (x,y,z) coordinates to determine its cube face.  Test the coordinates to do this; results of (|x|>|y|), (|y|>|z|), (|z|>|x|) and sign of x,y, or z will determine whether to put the point on the front (x=+1), back(x=-1), top(z=+1), bottom(z=-1) etc.
    b) Move the point radially outwards from the sphere center to its position on a cube face. 

---6) 2D Free-Form Plane Warp:  For each side of the cube, make an interesting warp of your own design.  This can be any interesting rearrangement of the points, but the result must still have points constrained to the cube surface planes. One interesting class of warp to consider would first change vertex positions in 3D,  then transform them back to 2D using a projective camera matrix as described in Chapter 5.  In example shown in class, a flat 2D field of circles was warped in 3D by a sinusoid, then projectively viewed at an angle to give the appearance of endless polka-dotted waves that stretch towards the horizon.

Test Images:

You may wish to test your program using these simple grid-like test images to help understand the geometric changes made by your program.