Skip to content

Simple Optimization

mattloper edited this page Sep 8, 2014 · 3 revisions

Below, we step through what happens in the demonstration given by...

import opendr
opendr.demo('optimization')

First we will import some prerequisites and load a mesh.

from opendr.simple import *      
import numpy as np 
import matplotlib.pyplot as plt
    
from opendr.util_tests import get_earthmesh
m = get_earthmesh(trans=ch.array([0,0,0]), rotation=ch.zeros(3))                                             
w, h = 320, 240

Now we will create V, A, U, f: geometry, brightness, camera, renderer

V = ch.array(m.v)                                                               
A = SphericalHarmonics(vn=VertNormals(v=V, f=m.f),                              
                   components=[3.,2.,0.,0.,0.,0.,0.,0.,0.],
                   light_color=ch.ones(3))                                  
U = ProjectPoints(v=V, f=[w,w], c=[w/2.,h/2.], k=ch.zeros(5),              
              t=ch.zeros(3), rt=ch.zeros(3))                                
f = TexturedRenderer(vc=A, camera=U, f=m.f, bgcolor=[0.,0.,0.],                 
                 texture_image=m.texture_image, vt=m.vt, ft=m.ft,           
                 frustum={'width':w, 'height':h, 'near':1,'far':20})     

Next we parametrize the vertices:

translation, rotation = ch.array([0,0,8]), ch.zeros(3)                          
f.v = translation + V.dot(Rodrigues(rotation))                                  

We next simulate an observation with a rendering. You could also load in your own image observation instead.

observed = f.r 
np.random.seed(1)
translation[:] = translation.r + np.random.rand(3)
rotation[:] = rotation.r + np.random.rand(3) *.2
A.components[1:] = 0

Next, we will create two energies: a raw energy with a difference between images, and another which is a difference between Gaussian pyramids. The pyramid helps with convergence, and the raw objective helps with final registration:

E_raw = f - observed
E_pyr = gaussian_pyramid(E_raw, n_levels=6, normalization='size')

We will also define a callback so we can see what's happening during the optimization:

def cb(_):
    import cv2
    cv2.imshow('Absolute difference', np.abs(E_raw.r))
    cv2.waitKey(1)                  

Finally, we will perform the optimization. Note that by default, if the function being minimized produces a vector, the optimizer minimizes its sum of squared values.

print 'OPTIMIZING TRANSLATION, ROTATION, AND LIGHT PARMS'    
free_variables=[translation, rotation, A.components]
ch.minimize({'pyr': E_pyr}, x0=free_variables, callback=cb) 
ch.minimize({'raw': E_raw}, x0=free_variables, callback=cb) 
Clone this wiki locally