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) 
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.