-
Notifications
You must be signed in to change notification settings - Fork 106
Simple Optimization
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)