def load_basics(self): np.random.seed(0) camera, frustum = getcam() mesh = get_earthmesh(trans=np.array([0,0,5]), rotation = np.array([0,0,0])) lighting_3channel = LambertianPointLight( f=mesh.f, num_verts=len(mesh.v), light_pos=np.array([-1000,-1000,-1000]), vc=mesh.vc, light_color=np.array([1., 1., 1.])) lighting_1channel = LambertianPointLight( f=mesh.f, num_verts=len(mesh.v), light_pos=np.array([-1000,-1000,-1000]), vc=mesh.vc.mean(axis=1).reshape((-1,1)), light_color=np.array([1.])) bgcolor = np.array([0.,0.,0.]) renderers = [ ColoredRenderer(f=mesh.f, camera=camera, frustum=frustum, bgcolor=bgcolor, num_channels=3), TexturedRenderer(f=mesh.f, camera=camera, frustum=frustum, texture_image=mesh.texture_image, vt=mesh.vt, ft=mesh.ft, bgcolor=bgcolor), ColoredRenderer(f=mesh.f, camera=camera, frustum=frustum, bgcolor=bgcolor[0], num_channels=1)] lightings = {1: lighting_1channel, 3: lighting_3channel} return mesh, lightings, camera, frustum, renderers
def test_depth_image(self): # Create renderer import chumpy as ch from renderer import DepthRenderer rn = DepthRenderer() # Assign attributes to renderer from util_tests import get_earthmesh m = get_earthmesh(trans=ch.array([0,0,0]), rotation=ch.zeros(3)) m.v = m.v * .01 m.v[:,2] += 4 w, h = (320, 240) from camera import ProjectPoints rn.camera = ProjectPoints(v=m.v, rt=ch.zeros(3), t=ch.zeros(3), f=ch.array([w,w])/2., c=ch.array([w,h])/2., k=ch.zeros(5)) rn.frustum = {'near': 1., 'far': 10., 'width': w, 'height': h} rn.set(v=m.v, f=m.f, vc=m.vc*0+1, bgcolor=ch.zeros(3)) # import time # tm = time.time() # rn.r # print 'took %es' % (time.time() - tm) # print np.min(rn.r.ravel()) # print np.max(rn.r.ravel()) self.assertLess(np.abs(np.min(rn.r.ravel()) - 3.98), 1e-5) self.assertLess(np.abs(np.min(m.v[:,2]) - np.min(rn.r.ravel())), 1e-5) self.assertLess(np.abs(rn.r[h/2,w/2] - 3.98), 1e-5)
def test_project_points_without_derivatives(self): from util_tests import get_earthmesh cam_params = self.get_cam_params() mesh = get_earthmesh(trans=np.array([0,0,5]), rotation = np.array([0,0,0])) pp = ProjectPoints(f=cam_params['f'], rt=cam_params['rt'], t=cam_params['t'], k=cam_params['k'], c=cam_params['c']) pp.v = mesh.v np.testing.assert_array_equal(pp.r, pp.r_and_derivatives[0].squeeze())
def get_sphere_mesh(): from util_tests import get_earthmesh mesh = get_earthmesh(np.zeros(3), np.zeros(3)) # load_mesh(filename) v, f = mesh.v*64., mesh.f for i in range(3): mtx, f = loop_subdivider(v, f) v = mtx.dot(v.ravel()).reshape((-1,3)) v /= 200. v[:,2] += 2 return v, f
def test_project_points_without_derivatives(self): from util_tests import get_earthmesh cam_params = self.get_cam_params() mesh = get_earthmesh(trans=np.array([0, 0, 5]), rotation=np.array([0, 0, 0])) pp = ProjectPoints(f=cam_params['f'], rt=cam_params['rt'], t=cam_params['t'], k=cam_params['k'], c=cam_params['c']) pp.v = mesh.v np.testing.assert_array_equal(pp.r, pp.r_and_derivatives[0].squeeze())
def test_derivatives2(self): import chumpy as ch import numpy as np from renderer import DepthRenderer rn = DepthRenderer() # Assign attributes to renderer from util_tests import get_earthmesh m = get_earthmesh(trans=ch.array([0,0,4]), rotation=ch.zeros(3)) w, h = (320, 240) from camera import ProjectPoints rn.camera = ProjectPoints(v=m.v, rt=ch.zeros(3), t=ch.zeros(3), f=ch.array([w,w])/2., c=ch.array([w,h])/2., k=ch.zeros(5)) rn.frustum = {'near': 1., 'far': 10., 'width': w, 'height': h} rn.set(v=m.v, f=m.f, bgcolor=ch.zeros(3)) if visualize: import matplotlib.pyplot as plt plt.ion() plt.figure() for which in range(3): r1 = rn.r adder = np.random.rand(rn.v.r.size).reshape(rn.v.r.shape)*.01 change = rn.v.r * 0 + adder dr_pred = rn.dr_wrt(rn.v).dot(change.ravel()).reshape(rn.shape) rn.v = rn.v.r + change r2 = rn.r dr_emp = r2 - r1 #print np.mean(np.abs(dr_pred-dr_emp)) self.assertLess(np.mean(np.abs(dr_pred-dr_emp)), .024) if visualize: plt.subplot(2,3,which+1) plt.imshow(dr_pred) plt.clim(-.01,.01) plt.title('emp') plt.subplot(2,3,which+4) plt.imshow(dr_emp) plt.clim(-.01,.01) plt.title('pred') plt.draw() plt.show()
def test_vert_normals(self): from geometry import VertNormals import numpy as np mesh = get_earthmesh(np.zeros(3), np.zeros(3)) v, f = mesh.v*127., mesh.f vn1 = VertNormals(f=f, v=v) dr_predicted = vn1.dr_wrt(vn1.v).copy() eps = .00001 * np.random.randn(v.size).reshape(v.shape) v += eps vn2 = VertNormals(v=v, f=f) empirical_diff = (vn2.r - vn1.r).reshape((-1,3)) predicted_diff = dr_predicted.dot(eps.flatten()).reshape((-1,3)) if False: print np.max(np.abs(empirical_diff-predicted_diff)) print empirical_diff[:6] print predicted_diff[:6] self.assertTrue(np.max(np.abs(empirical_diff-predicted_diff)) < 6e-13)
def test_occlusion(self): if visualize: import matplotlib.pyplot as plt plt.ion() # Create renderer import chumpy as ch import numpy as np from opendr.renderer import TexturedRenderer, ColoredRenderer #rn = TexturedRenderer() rn = ColoredRenderer() # Assign attributes to renderer from util_tests import get_earthmesh m = get_earthmesh(trans=ch.array([0,0,4]), rotation=ch.zeros(3)) rn.texture_image = m.texture_image rn.ft = m.ft rn.vt = m.vt m.v[:,2] = np.mean(m.v[:,2]) # red is front and zero # green is back and 1 t0 = ch.array([1,0,.1]) t1 = ch.array([-1,0,.1]) v0 = ch.array(m.v) + t0 if False: v1 = ch.array(m.v*.4 + np.array([0,0,3.8])) + t1 else: v1 = ch.array(m.v) + t1 vc0 = v0*0 + np.array([[.4,0,0]]) vc1 = v1*0 + np.array([[0,.4,0]]) vc = ch.vstack((vc0, vc1)) v = ch.vstack((v0, v1)) f = np.vstack((m.f, m.f+len(v0))) w, h = (320, 240) rn.camera = ProjectPoints(v=v, rt=ch.zeros(3), t=ch.zeros(3), f=ch.array([w,w])/2., c=ch.array([w,h])/2., k=ch.zeros(5)) rn.camera.t = ch.array([0,0,-2.5]) rn.frustum = {'near': 1., 'far': 10., 'width': w, 'height': h} m.vc = v.r*0 + np.array([[1,0,0]]) rn.set(v=v, f=f, vc=vc) t0[:] = np.array([1.4, 0, .1-.02]) t1[:] = np.array([-0.6, 0, .1+.02]) target = rn.r if visualize: plt.figure() plt.imshow(target) plt.title('target') plt.figure() plt.show() im_orig = rn.r.copy() from cvwrap import cv2 tr = t0 eps_emp = .02 eps_pred = .02 #blur = lambda x : cv2.blur(x, ksize=(5,5)) blur = lambda x : x for tr in [t0, t1]: if tr is t0: sum_limits = np.array([2.1e+2, 6.9e+1, 1.6e+2]) else: sum_limits = [1., 5., 4.] if visualize: plt.figure() for i in range(3): dr_pred = np.array(rn.dr_wrt(tr[i]).todense()).reshape(rn.shape) * eps_pred dr_pred = blur(dr_pred) # central differences tr[i] = tr[i].r + eps_emp/2. rn_greater = rn.r.copy() tr[i] = tr[i].r - eps_emp/1. rn_lesser = rn.r.copy() tr[i] = tr[i].r + eps_emp/2. dr_emp = blur((rn_greater - rn_lesser) * eps_pred / eps_emp) dr_pred_shown = np.clip(dr_pred, -.5, .5) + .5 dr_emp_shown = np.clip(dr_emp, -.5, .5) + .5 if visualize: plt.subplot(3,3,i+1) plt.imshow(dr_pred_shown) plt.title('pred') plt.axis('off') plt.subplot(3,3,3+i+1) plt.imshow(dr_emp_shown) plt.title('empirical') plt.axis('off') plt.subplot(3,3,6+i+1) diff = np.abs(dr_emp - dr_pred) if visualize: plt.imshow(diff) diff = diff.ravel() if visualize: plt.title('diff (sum: %.2e)' % (np.sum(diff))) plt.axis('off') # print 'dr pred sum: %.2e' % (np.sum(np.abs(dr_pred.ravel())),) # print 'dr emp sum: %.2e' % (np.sum(np.abs(dr_emp.ravel())),) #import pdb; pdb.set_trace() self.assertTrue(np.sum(diff) < sum_limits[i])
def test_color_derivatives(self): mesh, lightings, camera, frustum, renderers = self.load_basics() for renderer in renderers: im_shape = renderer.shape lighting = lightings[renderer.num_channels] # Get pixels and dI/dC mesh = get_earthmesh(trans=np.array([0,0,5]), rotation = np.array([math.pi/2.,0,0])) mesh_verts = Ch(mesh.v) mesh_colors = Ch(mesh.vc) camera.set(v=mesh_verts) # import pdb; pdb.set_trace() # print '-------------------------------------------' #lighting.set(vc=mesh_colors, v=mesh_verts) lighting.vc = mesh_colors[:,:renderer.num_channels] lighting.v = mesh_verts renderer.set(v=mesh_verts, vc=lighting) r = renderer.r dr = renderer.dr_wrt(mesh_colors).copy() # Establish a random direction eps = .4 direction = (np.random.randn(mesh.v.size).reshape(mesh.v.shape)*.1 + np.sin(mesh.v*19)*.1).flatten() # Find empirical forward derivatives in that direction mesh_colors = Ch(mesh.vc+direction.reshape(mesh.vc.shape)*eps/2.) lighting.set(vc=mesh_colors[:,:renderer.num_channels]) renderer.set(vc=lighting) rfwd = renderer.r # Find empirical backward derivatives in that direction mesh_colors = Ch(mesh.vc-direction.reshape(mesh.vc.shape)*eps/2.) lighting.set(vc=mesh_colors[:,:renderer.num_channels]) renderer.set(vc=lighting) rbwd = renderer.r dr_empirical = (np.asarray(rfwd, np.float64) - np.asarray(rbwd, np.float64)).ravel() / eps dr_predicted = dr.dot(col(direction.flatten())).reshape(dr_empirical.shape) images = OrderedDict() images['shifted colors'] = np.asarray(rfwd, np.float64)-.5 images[r'empirical colors $\left(\frac{dI}{dC}\right)$'] = dr_empirical images[r'predicted colors $\left(\frac{dI}{dC}\right)$'] = dr_predicted images['difference colors'] = dr_predicted-dr_empirical nonzero = images['difference colors'][np.nonzero(images['difference colors']!=0)[0]] if visualize: matplotlib.rcParams.update({'font.size': 18}) plt.figure(figsize=(6*3, 2*3)) for idx, title in enumerate(images.keys()): plt.subplot(1,len(images.keys()), idx+1) im = process(images[title].reshape(im_shape), vmin=-.5, vmax=.5) plt.title(title) plt.imshow(im) plt.show() print 'color: median nonzero %.2e' % (np.median(np.abs(nonzero)),) print 'color: mean nonzero %.2e' % (np.mean(np.abs(nonzero)),) self.assertLess(np.mean(np.abs(nonzero)), 2e-2) self.assertLess(np.median(np.abs(nonzero)), 4.5e-3)
def test_lightpos_derivatives(self): mesh, lightings, camera, frustum, renderers = self.load_basics() for renderer in renderers: im_shape = renderer.shape lighting = lightings[renderer.num_channels] # Render a rotating mesh mesh = get_earthmesh(trans=np.array([0,0,5]), rotation = np.array([math.pi/2.,0,0])) mesh_verts = Ch(mesh.v.flatten()) camera.set(v=mesh_verts) # Get predicted derivatives wrt light pos light1_pos = Ch(np.array([-1000,-1000,-1000])) lighting.set(light_pos=light1_pos, v=mesh_verts) renderer.set(vc=lighting, v=mesh_verts) dr = renderer.dr_wrt(light1_pos).copy() # Establish a random direction for the light direction = (np.random.rand(3)-.5)*1000. eps = 1. # Find empirical forward derivatives in that direction lighting.set(light_pos = light1_pos.r + direction*eps/2.) renderer.set(vc=lighting) rfwd = renderer.r # Find empirical backward derivatives in that direction lighting.set(light_pos = light1_pos.r - direction*eps/2.) renderer.set(vc=lighting) rbwd = renderer.r # Establish empirical and predicted derivatives dr_empirical = (np.asarray(rfwd, np.float64) - np.asarray(rbwd, np.float64)).ravel() / eps dr_predicted = dr.dot(col(direction.flatten())).reshape(dr_empirical.shape) images = OrderedDict() images['shifted lightpos'] = np.asarray(rfwd, np.float64)-.5 images[r'empirical lightpos $\left(\frac{dI}{dL_p}\right)$'] = dr_empirical images[r'predicted lightpos $\left(\frac{dI}{dL_p}\right)$'] = dr_predicted images['difference lightpos'] = dr_predicted-dr_empirical nonzero = images['difference lightpos'][np.nonzero(images['difference lightpos']!=0)[0]] if visualize: matplotlib.rcParams.update({'font.size': 18}) plt.figure(figsize=(6*3, 2*3)) for idx, title in enumerate(images.keys()): plt.subplot(1,len(images.keys()), idx+1) im = process(images[title].reshape(im_shape), vmin=-.5, vmax=.5) plt.title(title) plt.imshow(im) plt.show() print 'lightpos: median nonzero %.2e' % (np.median(np.abs(nonzero)),) print 'lightpos: mean nonzero %.2e' % (np.mean(np.abs(nonzero)),) self.assertLess(np.mean(np.abs(nonzero)), 2.4e-2) self.assertLess(np.median(np.abs(nonzero)), 1.2e-2)
def test_vert_derivatives(self): mesh, lightings, camera, frustum, renderers = self.load_basics() for renderer in renderers: lighting = lightings[renderer.num_channels] im_shape = renderer.shape # Render a rotating mesh mesh = get_earthmesh(trans=np.array([0,0,5]), rotation = np.array([math.pi/2.,0,0])) mesh_verts = Ch(mesh.v.flatten()) camera.set(v=mesh_verts) lighting.set(v=mesh_verts) renderer.set(camera=camera) renderer.set(vc=lighting) # Get pixels and derivatives r = renderer.r dr = renderer.dr_wrt(mesh_verts) # Establish a random direction direction = (np.random.rand(mesh.v.size).reshape(mesh.v.shape)-.5)*.1 + np.sin(mesh.v*10)*.2 direction *= .5 eps = .2 # Render going forward in that direction mesh_verts = Ch(mesh.v+direction*eps/2.) lighting.set(v=mesh_verts) renderer.set(v=mesh_verts, vc=lighting) rfwd = renderer.r # Render going backward in that direction mesh_verts = Ch(mesh.v-direction*eps/2.) lighting.set(v=mesh_verts) renderer.set(v=mesh_verts, vc=lighting) rbwd = renderer.r # Establish empirical and predicted derivatives dr_empirical = (np.asarray(rfwd, np.float64) - np.asarray(rbwd, np.float64)).ravel() / eps dr_predicted = dr.dot(col(direction.flatten())).reshape(dr_empirical.shape) images = OrderedDict() images['shifted verts'] = np.asarray(rfwd, np.float64)-.5 images[r'empirical verts $\left(\frac{dI}{dV}\right)$'] = dr_empirical images[r'predicted verts $\left(\frac{dI}{dV}\right)$'] = dr_predicted images['difference verts'] = dr_predicted - dr_empirical nonzero = images['difference verts'][np.nonzero(images['difference verts']!=0)[0]] if visualize: matplotlib.rcParams.update({'font.size': 18}) plt.figure(figsize=(6*3, 2*3)) for idx, title in enumerate(images.keys()): plt.subplot(1,len(images.keys()), idx+1) im = process(images[title].reshape(im_shape), vmin=-.5, vmax=.5) plt.title(title) plt.imshow(im) print 'verts: median nonzero %.2e' % (np.median(np.abs(nonzero)),) print 'verts: mean nonzero %.2e' % (np.mean(np.abs(nonzero)),) plt.draw() plt.show() self.assertLess(np.mean(np.abs(nonzero)), 7e-2) self.assertLess(np.median(np.abs(nonzero)), 4e-2)
def test_cam_derivatives(self): mesh, lightings, camera, frustum, renderers = self.load_basics() camparms = { 'c': {'mednz' : 2.2e-2, 'meannz': 4.2e-2, 'desc': 'center of proj diff', 'eps0': 4., 'eps1': .1}, #'f': {'mednz' : 2.5e-2, 'meannz': 6e-2, 'desc': 'focal diff', 'eps0': 100., 'eps1': .1}, 't': {'mednz' : 1.2e-1, 'meannz': 3.0e-1, 'desc': 'trans diff', 'eps0': .25, 'eps1': .1}, 'rt': {'mednz' : 8e-2, 'meannz': 1.8e-1, 'desc': 'rot diff', 'eps0': 0.02, 'eps1': .5}, 'k': {'mednz' : 7e-2, 'meannz': 5.1e-1, 'desc': 'distortion diff', 'eps0': .5, 'eps1': .05} } for renderer in renderers: im_shape = renderer.shape lighting = lightings[renderer.num_channels] # Render a rotating mesh mesh = get_earthmesh(trans=np.array([0,0,5]), rotation = np.array([math.pi/2.,0,0])) mesh_verts = Ch(mesh.v.flatten()) camera.v = mesh_verts lighting.v = mesh_verts renderer.vc = lighting renderer.camera = camera for atrname, info in camparms.items(): # Get pixels and derivatives r = renderer.r atr = lambda : getattr(camera, atrname) satr = lambda x : setattr(camera, atrname, x) atr_size = atr().size dr = renderer.dr_wrt(atr()) # Establish a random direction tmp = np.random.rand(atr().size) - .5 direction = (tmp / np.linalg.norm(tmp))*info['eps0'] #direction = np.sin(np.ones(atr_size))*info['eps0'] #direction = np.zeros(atr_size) # try: # direction[4] = 1. # except: pass #direction *= info['eps0'] eps = info['eps1'] # Render going forward in that direction satr(atr().r + direction*eps/2.) rfwd = renderer.r # Render going backward in that direction satr(atr().r - direction*eps/1.) rbwd = renderer.r # Put back satr(atr().r + direction*eps/2.) # Establish empirical and predicted derivatives dr_empirical = (np.asarray(rfwd, np.float64) - np.asarray(rbwd, np.float64)).ravel() / eps dr_predicted = dr.dot(col(direction.flatten())).reshape(dr_empirical.shape) images = OrderedDict() images['shifted %s' % (atrname,)] = np.asarray(rfwd, np.float64)-.5 images[r'empirical %s' % (atrname,)] = dr_empirical images[r'predicted %s' % (atrname,)] = dr_predicted images[info['desc']] = dr_predicted - dr_empirical nonzero = images[info['desc']][np.nonzero(images[info['desc']]!=0)[0]] mederror = np.median(np.abs(nonzero)) meanerror = np.mean(np.abs(nonzero)) if visualize: matplotlib.rcParams.update({'font.size': 18}) plt.figure(figsize=(6*3, 2*3)) for idx, title in enumerate(images.keys()): plt.subplot(1,len(images.keys()), idx+1) im = process(images[title].reshape(im_shape), vmin=-.5, vmax=.5) plt.title(title) plt.imshow(im) print '%s: median nonzero %.2e' % (atrname, mederror,) print '%s: mean nonzero %.2e' % (atrname, meanerror,) plt.draw() plt.show() self.assertLess(meanerror, info['meannz']) self.assertLess(mederror, info['mednz'])
def test_distortion(self): mesh, lightings, camera, frustum, renderers = self.load_basics() renderer = renderers[1] lighting = lightings[renderer.num_channels] lighting.light_pos = -lighting.light_pos * 100. mesh = get_earthmesh(trans=np.array([0,0,-8]), rotation = np.array([math.pi/2.,0,0])) mesh_verts = Ch(mesh.v.flatten()) renderer.camera = camera camera.v = mesh_verts lighting.v = mesh_verts renderer.vc = lighting renderer.camera = camera camera.rt = np.array([np.pi, 0, 0]) # Get pixels and derivatives im_original = renderer.r.copy() #camera.k = np.zeros(5) #camera.k = np.arange(8,0,-1)*.1 #camera.k = np.array([ 0.00249999, 0.42208098, 0.45360267, 0.06808415, -0.38003062]) camera.k = np.array([ 5., 25., .3, .4, 1000., 5., 0., 0.]) im_distorted = renderer.r cr = renderer cmtx = np.array([ [cr.camera.f.r[0], 0, cr.camera.c.r[0]], [0, cr.camera.f.r[1], cr.camera.c.r[1]], [0, 0, 1] ]) from cvwrap import cv2 im_undistorted = cv2.undistort(im_distorted, cmtx, cr.camera.k.r) d1 = (im_original - im_distorted).ravel() d2 = (im_original - im_undistorted).ravel() d1 = d1[d1 != 0.] d2 = d2[d2 != 0.] self.assertGreater(np.mean(d1**2) / np.mean(d2**2), 44.) self.assertLess(np.mean(d2**2), 0.0016) self.assertGreater(np.median(d1**2) / np.median(d2**2), 650) self.assertLess(np.median(d2**2), 1.9e-5) if visualize: import matplotlib.pyplot as plt plt.ion() matplotlib.rcParams.update({'font.size': 18}) plt.figure(figsize=(6*3, 2*3)) plt.subplot(1,4,1) plt.imshow(im_original) plt.title('original') plt.subplot(1,4,2) plt.imshow(im_distorted) plt.title('distorted') plt.subplot(1,4,3) plt.imshow(im_undistorted) plt.title('undistorted by opencv') plt.subplot(1,4,4) plt.imshow(im_undistorted - im_original + .5) plt.title('diff') plt.draw() plt.show()
def test_distortion(self): mesh, lightings, camera, frustum, renderers = self.load_basics() renderer = renderers[1] lighting = lightings[renderer.num_channels] lighting.light_pos = -lighting.light_pos * 100. mesh = get_earthmesh(trans=np.array([0, 0, -8]), rotation=np.array([math.pi / 2., 0, 0])) mesh_verts = Ch(mesh.v.flatten()) renderer.camera = camera camera.v = mesh_verts lighting.v = mesh_verts renderer.vc = lighting renderer.camera = camera camera.rt = np.array([np.pi, 0, 0]) # Get pixels and derivatives im_original = renderer.r.copy() #camera.k = np.zeros(5) #camera.k = np.arange(8,0,-1)*.1 #camera.k = np.array([ 0.00249999, 0.42208098, 0.45360267, 0.06808415, -0.38003062]) camera.k = np.array([5., 25., .3, .4, 1000., 5., 0., 0.]) im_distorted = renderer.r cr = renderer cmtx = np.array([[cr.camera.f.r[0], 0, cr.camera.c.r[0]], [0, cr.camera.f.r[1], cr.camera.c.r[1]], [0, 0, 1]]) from cvwrap import cv2 im_undistorted = cv2.undistort(im_distorted, cmtx, cr.camera.k.r) d1 = (im_original - im_distorted).ravel() d2 = (im_original - im_undistorted).ravel() d1 = d1[d1 != 0.] d2 = d2[d2 != 0.] self.assertGreater(np.mean(d1**2) / np.mean(d2**2), 44.) self.assertLess(np.mean(d2**2), 0.0016) self.assertGreater(np.median(d1**2) / np.median(d2**2), 650) self.assertLess(np.median(d2**2), 1.9e-5) if visualize: import matplotlib.pyplot as plt plt.ion() matplotlib.rcParams.update({'font.size': 18}) plt.figure(figsize=(6 * 3, 2 * 3)) plt.subplot(1, 4, 1) plt.imshow(im_original) plt.title('original') plt.subplot(1, 4, 2) plt.imshow(im_distorted) plt.title('distorted') plt.subplot(1, 4, 3) plt.imshow(im_undistorted) plt.title('undistorted by opencv') plt.subplot(1, 4, 4) plt.imshow(im_undistorted - im_original + .5) plt.title('diff') plt.draw() plt.show()
def test_cam_derivatives(self): mesh, lightings, camera, frustum, renderers = self.load_basics() camparms = { 'c': { 'mednz': 2.2e-2, 'meannz': 4.3e-2, 'desc': 'center of proj diff', 'eps0': 4., 'eps1': .1 }, #'f': {'mednz' : 2.5e-2, 'meannz': 6e-2, 'desc': 'focal diff', 'eps0': 100., 'eps1': .1}, 't': { 'mednz': 1.2e-1, 'meannz': 3.0e-1, 'desc': 'trans diff', 'eps0': .25, 'eps1': .1 }, 'rt': { 'mednz': 8e-2, 'meannz': 1.8e-1, 'desc': 'rot diff', 'eps0': 0.02, 'eps1': .5 }, 'k': { 'mednz': 7e-2, 'meannz': 5.1e-1, 'desc': 'distortion diff', 'eps0': .5, 'eps1': .05 } } for renderer in renderers: im_shape = renderer.shape lighting = lightings[renderer.num_channels] # Render a rotating mesh mesh = get_earthmesh(trans=np.array([0, 0, 5]), rotation=np.array([math.pi / 2., 0, 0])) mesh_verts = Ch(mesh.v.flatten()) camera.v = mesh_verts lighting.v = mesh_verts renderer.vc = lighting renderer.camera = camera for atrname, info in camparms.items(): # Get pixels and derivatives r = renderer.r atr = lambda: getattr(camera, atrname) satr = lambda x: setattr(camera, atrname, x) atr_size = atr().size dr = renderer.dr_wrt(atr()) # Establish a random direction tmp = np.random.rand(atr().size) - .5 direction = (tmp / np.linalg.norm(tmp)) * info['eps0'] #direction = np.sin(np.ones(atr_size))*info['eps0'] #direction = np.zeros(atr_size) # try: # direction[4] = 1. # except: pass #direction *= info['eps0'] eps = info['eps1'] # Render going forward in that direction satr(atr().r + direction * eps / 2.) rfwd = renderer.r # Render going backward in that direction satr(atr().r - direction * eps / 1.) rbwd = renderer.r # Put back satr(atr().r + direction * eps / 2.) # Establish empirical and predicted derivatives dr_empirical = (np.asarray(rfwd, np.float64) - np.asarray(rbwd, np.float64)).ravel() / eps dr_predicted = dr.dot(col(direction.flatten())).reshape( dr_empirical.shape) images = OrderedDict() images['shifted %s' % (atrname, )] = np.asarray(rfwd, np.float64) - .5 images[r'empirical %s' % (atrname, )] = dr_empirical images[r'predicted %s' % (atrname, )] = dr_predicted images[info['desc']] = dr_predicted - dr_empirical nonzero = images[info['desc']][np.nonzero( images[info['desc']] != 0)[0]] mederror = np.median(np.abs(nonzero)) meanerror = np.mean(np.abs(nonzero)) if visualize: matplotlib.rcParams.update({'font.size': 18}) plt.figure(figsize=(6 * 3, 2 * 3)) for idx, title in enumerate(images.keys()): plt.subplot(1, len(images.keys()), idx + 1) im = process(images[title].reshape(im_shape), vmin=-.5, vmax=.5) plt.title(title) plt.imshow(im) print '%s: median nonzero %.2e' % ( atrname, mederror, ) print '%s: mean nonzero %.2e' % ( atrname, meanerror, ) plt.draw() plt.show() self.assertLess(meanerror, info['meannz']) self.assertLess(mederror, info['mednz'])
def test_occlusion(self): if visualize: import matplotlib.pyplot as plt plt.ion() # Create renderer import chumpy as ch import numpy as np from opendr.renderer import TexturedRenderer, ColoredRenderer #rn = TexturedRenderer() rn = ColoredRenderer() # Assign attributes to renderer from util_tests import get_earthmesh m = get_earthmesh(trans=ch.array([0,0,4]), rotation=ch.zeros(3)) rn.texture_image = m.texture_image rn.ft = m.ft rn.vt = m.vt m.v[:,2] = np.mean(m.v[:,2]) # red is front and zero # green is back and 1 t0 = ch.array([1,0,.1]) t1 = ch.array([-1,0,.1]) v0 = ch.array(m.v) + t0 if False: v1 = ch.array(m.v*.4 + np.array([0,0,3.8])) + t1 else: v1 = ch.array(m.v) + t1 vc0 = v0*0 + np.array([[.4,0,0]]) vc1 = v1*0 + np.array([[0,.4,0]]) vc = ch.vstack((vc0, vc1)) v = ch.vstack((v0, v1)) f = np.vstack((m.f, m.f+len(v0))) w, h = (320, 240) rn.camera = ProjectPoints(v=v, rt=ch.zeros(3), t=ch.zeros(3), f=ch.array([w,w])/2., c=ch.array([w,h])/2., k=ch.zeros(5)) rn.camera.t = ch.array([0,0,-2.5]) rn.frustum = {'near': 1., 'far': 10., 'width': w, 'height': h} m.vc = v.r*0 + np.array([[1,0,0]]) rn.set(v=v, f=f, vc=vc) t0[:] = np.array([1.4, 0, .1-.02]) t1[:] = np.array([-0.6, 0, .1+.02]) target = rn.r if visualize: plt.figure() plt.imshow(target) plt.title('target') plt.figure() plt.show() im_orig = rn.r.copy() from cvwrap import cv2 tr = t0 eps_emp = .02 eps_pred = .02 #blur = lambda x : cv2.blur(x, ksize=(5,5)) blur = lambda x : x for tr in [t0, t1]: if tr is t0: sum_limits = np.array([2.1e+2, 6.9e+1, 1.6e+2]) else: sum_limits = [1., 5., 4.] if visualize: plt.figure() for i in range(3): dr_pred = np.array(rn.dr_wrt(tr[i]).toarray()).reshape(rn.shape) * eps_pred dr_pred = blur(dr_pred) # central differences tr[i] = tr[i].r + eps_emp/2. rn_greater = rn.r.copy() tr[i] = tr[i].r - eps_emp/1. rn_lesser = rn.r.copy() tr[i] = tr[i].r + eps_emp/2. dr_emp = blur((rn_greater - rn_lesser) * eps_pred / eps_emp) dr_pred_shown = np.clip(dr_pred, -.5, .5) + .5 dr_emp_shown = np.clip(dr_emp, -.5, .5) + .5 if visualize: plt.subplot(3,3,i+1) plt.imshow(dr_pred_shown) plt.title('pred') plt.axis('off') plt.subplot(3,3,3+i+1) plt.imshow(dr_emp_shown) plt.title('empirical') plt.axis('off') plt.subplot(3,3,6+i+1) diff = np.abs(dr_emp - dr_pred) if visualize: plt.imshow(diff) diff = diff.ravel() if visualize: plt.title('diff (sum: %.2e)' % (np.sum(diff))) plt.axis('off') # print 'dr pred sum: %.2e' % (np.sum(np.abs(dr_pred.ravel())),) # print 'dr emp sum: %.2e' % (np.sum(np.abs(dr_emp.ravel())),) #import pdb; pdb.set_trace() self.assertTrue(np.sum(diff) < sum_limits[i])
def test_vert_derivatives(self): mesh, lightings, camera, frustum, renderers = self.load_basics() for renderer in renderers: lighting = lightings[renderer.num_channels] im_shape = renderer.shape # Render a rotating mesh mesh = get_earthmesh(trans=np.array([0, 0, 5]), rotation=np.array([math.pi / 2., 0, 0])) mesh_verts = Ch(mesh.v.flatten()) camera.set(v=mesh_verts) lighting.set(v=mesh_verts) renderer.set(camera=camera) renderer.set(vc=lighting) # Get pixels and derivatives r = renderer.r dr = renderer.dr_wrt(mesh_verts) # Establish a random direction direction = (np.random.rand(mesh.v.size).reshape(mesh.v.shape) - .5) * .1 + np.sin(mesh.v * 10) * .2 direction *= .5 eps = .2 # Render going forward in that direction mesh_verts = Ch(mesh.v + direction * eps / 2.) lighting.set(v=mesh_verts) renderer.set(v=mesh_verts, vc=lighting) rfwd = renderer.r # Render going backward in that direction mesh_verts = Ch(mesh.v - direction * eps / 2.) lighting.set(v=mesh_verts) renderer.set(v=mesh_verts, vc=lighting) rbwd = renderer.r # Establish empirical and predicted derivatives dr_empirical = (np.asarray(rfwd, np.float64) - np.asarray(rbwd, np.float64)).ravel() / eps dr_predicted = dr.dot(col(direction.flatten())).reshape( dr_empirical.shape) images = OrderedDict() images['shifted verts'] = np.asarray(rfwd, np.float64) - .5 images[ r'empirical verts $\left(\frac{dI}{dV}\right)$'] = dr_empirical images[ r'predicted verts $\left(\frac{dI}{dV}\right)$'] = dr_predicted images['difference verts'] = dr_predicted - dr_empirical nonzero = images['difference verts'][np.nonzero( images['difference verts'] != 0)[0]] if visualize: matplotlib.rcParams.update({'font.size': 18}) plt.figure(figsize=(6 * 3, 2 * 3)) for idx, title in enumerate(images.keys()): plt.subplot(1, len(images.keys()), idx + 1) im = process(images[title].reshape(im_shape), vmin=-.5, vmax=.5) plt.title(title) plt.imshow(im) print 'verts: median nonzero %.2e' % (np.median( np.abs(nonzero)), ) print 'verts: mean nonzero %.2e' % (np.mean(np.abs(nonzero)), ) plt.draw() plt.show() self.assertLess(np.mean(np.abs(nonzero)), 7e-2) self.assertLess(np.median(np.abs(nonzero)), 4e-2)
def test_color_derivatives(self): mesh, lightings, camera, frustum, renderers = self.load_basics() for renderer in renderers: im_shape = renderer.shape lighting = lightings[renderer.num_channels] # Get pixels and dI/dC mesh = get_earthmesh(trans=np.array([0, 0, 5]), rotation=np.array([math.pi / 2., 0, 0])) mesh_verts = Ch(mesh.v) mesh_colors = Ch(mesh.vc) camera.set(v=mesh_verts) # import pdb; pdb.set_trace() # print '-------------------------------------------' #lighting.set(vc=mesh_colors, v=mesh_verts) lighting.vc = mesh_colors[:, :renderer.num_channels] lighting.v = mesh_verts renderer.set(v=mesh_verts, vc=lighting) r = renderer.r dr = renderer.dr_wrt(mesh_colors).copy() # Establish a random direction eps = .4 direction = ( np.random.randn(mesh.v.size).reshape(mesh.v.shape) * .1 + np.sin(mesh.v * 19) * .1).flatten() # Find empirical forward derivatives in that direction mesh_colors = Ch(mesh.vc + direction.reshape(mesh.vc.shape) * eps / 2.) lighting.set(vc=mesh_colors[:, :renderer.num_channels]) renderer.set(vc=lighting) rfwd = renderer.r # Find empirical backward derivatives in that direction mesh_colors = Ch(mesh.vc - direction.reshape(mesh.vc.shape) * eps / 2.) lighting.set(vc=mesh_colors[:, :renderer.num_channels]) renderer.set(vc=lighting) rbwd = renderer.r dr_empirical = (np.asarray(rfwd, np.float64) - np.asarray(rbwd, np.float64)).ravel() / eps dr_predicted = dr.dot(col(direction.flatten())).reshape( dr_empirical.shape) images = OrderedDict() images['shifted colors'] = np.asarray(rfwd, np.float64) - .5 images[ r'empirical colors $\left(\frac{dI}{dC}\right)$'] = dr_empirical images[ r'predicted colors $\left(\frac{dI}{dC}\right)$'] = dr_predicted images['difference colors'] = dr_predicted - dr_empirical nonzero = images['difference colors'][np.nonzero( images['difference colors'] != 0)[0]] if visualize: matplotlib.rcParams.update({'font.size': 18}) plt.figure(figsize=(6 * 3, 2 * 3)) for idx, title in enumerate(images.keys()): plt.subplot(1, len(images.keys()), idx + 1) im = process(images[title].reshape(im_shape), vmin=-.5, vmax=.5) plt.title(title) plt.imshow(im) plt.show() print 'color: median nonzero %.2e' % (np.median( np.abs(nonzero)), ) print 'color: mean nonzero %.2e' % (np.mean(np.abs(nonzero)), ) self.assertLess(np.mean(np.abs(nonzero)), 2e-2) self.assertLess(np.median(np.abs(nonzero)), 4.5e-3)
def test_lightpos_derivatives(self): mesh, lightings, camera, frustum, renderers = self.load_basics() for renderer in renderers: im_shape = renderer.shape lighting = lightings[renderer.num_channels] # Render a rotating mesh mesh = get_earthmesh(trans=np.array([0, 0, 5]), rotation=np.array([math.pi / 2., 0, 0])) mesh_verts = Ch(mesh.v.flatten()) camera.set(v=mesh_verts) # Get predicted derivatives wrt light pos light1_pos = Ch(np.array([-1000, -1000, -1000])) lighting.set(light_pos=light1_pos, v=mesh_verts) renderer.set(vc=lighting, v=mesh_verts) dr = renderer.dr_wrt(light1_pos).copy() # Establish a random direction for the light direction = (np.random.rand(3) - .5) * 1000. eps = 1. # Find empirical forward derivatives in that direction lighting.set(light_pos=light1_pos.r + direction * eps / 2.) renderer.set(vc=lighting) rfwd = renderer.r # Find empirical backward derivatives in that direction lighting.set(light_pos=light1_pos.r - direction * eps / 2.) renderer.set(vc=lighting) rbwd = renderer.r # Establish empirical and predicted derivatives dr_empirical = (np.asarray(rfwd, np.float64) - np.asarray(rbwd, np.float64)).ravel() / eps dr_predicted = dr.dot(col(direction.flatten())).reshape( dr_empirical.shape) images = OrderedDict() images['shifted lightpos'] = np.asarray(rfwd, np.float64) - .5 images[ r'empirical lightpos $\left(\frac{dI}{dL_p}\right)$'] = dr_empirical images[ r'predicted lightpos $\left(\frac{dI}{dL_p}\right)$'] = dr_predicted images['difference lightpos'] = dr_predicted - dr_empirical nonzero = images['difference lightpos'][np.nonzero( images['difference lightpos'] != 0)[0]] if visualize: matplotlib.rcParams.update({'font.size': 18}) plt.figure(figsize=(6 * 3, 2 * 3)) for idx, title in enumerate(images.keys()): plt.subplot(1, len(images.keys()), idx + 1) im = process(images[title].reshape(im_shape), vmin=-.5, vmax=.5) plt.title(title) plt.imshow(im) plt.show() print 'lightpos: median nonzero %.2e' % (np.median( np.abs(nonzero)), ) print 'lightpos: mean nonzero %.2e' % (np.mean( np.abs(nonzero)), ) self.assertLess(np.mean(np.abs(nonzero)), 2.4e-2) self.assertLess(np.median(np.abs(nonzero)), 1.2e-2)