Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

color_render custom TF op passes all test #14

Open
wants to merge 49 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
3e21908
Bring in BL current and history
mattloper Jul 11, 2014
9145ca8
Removed contexts/setup.py
mattloper Jul 12, 2014
b0f0ae4
Added num_channels to renderers. Colored renderer can now have that s…
mattloper Jul 14, 2014
84bc00f
lighting.py: added lambertian spotlight
mattloper Jul 15, 2014
8cc590f
Add generated stuff in contexts to .gitignore
algrs Jul 19, 2014
2c1b0ed
Switch to strict relative imports.
algrs Jul 19, 2014
b291e06
Replaced "assertTrue" with "assertGreater"/"assertLess" so we know ho…
mattloper Jul 19, 2014
9406134
loosened unit tests slightly for linux
mattloper Jul 19, 2014
12b544e
more loosening of unit tests for linux
mattloper Jul 19, 2014
0ff6c80
lighting.py: added camcoord option for lambertian spotlight
mattloper Jul 22, 2014
31bbe1d
topology.py: support non-watertight meshes
mattloper Jul 28, 2014
a2373a8
util_tests.py: fixed for __array_priority__ change
mattloper Jul 29, 2014
90025c0
Added fields to setup (like "description") and added README.txt
mattloper Jul 23, 2014
03df9d1
Makefile: added upload option
mattloper Jul 23, 2014
39667cd
setup.py: require chumpy >= .51
mattloper Jul 23, 2014
a0aa109
Attempt to fix cythonize problems for pip install
mattloper Jul 23, 2014
e47a8a0
Moved tests into main dir, to get rid of relative import madness.
mattloper Jul 23, 2014
cb9d4b7
Incremented version for pipy upload.
mattloper Jul 23, 2014
369d6ab
renderer.py: Added overdraw=True as default for BoundaryRenderer
mattloper Jul 23, 2014
2286686
setup.py: incremented version
mattloper Jul 23, 2014
8963b58
added matplotlib as a req, so that demos will run.
mattloper Jul 25, 2014
15d5a33
setup.py: added more information for pypi
mattloper Jul 26, 2014
a08f98c
README.txt: fixed some markdown
mattloper Jul 26, 2014
b5637e1
Don't compile mesa on mac, add cvwrap in case opencv isn't available,…
mattloper Aug 26, 2014
2880eae
Actually do what I meant to do in last commit
mattloper Aug 26, 2014
fd34422
Updated to make pyramids work with greyscale (ie renderer.num_channel…
mattloper Aug 28, 2014
64bdd86
__init__.py: updated demo('optimization') example
mattloper Aug 28, 2014
d8b15ce
test_renderer.py: fix import
mattloper Aug 28, 2014
2d3b7b2
Merge branch 'ml_master'
algrs Feb 24, 2015
cbf05de
Add double sided rendering to LambertianPointLight.
algrs Feb 24, 2015
7a89ea4
Fix to prev
algrs Feb 24, 2015
2861d82
Leave no pdb unturned
algrs Feb 25, 2015
d803386
Implement ProjectPoints.compute_r without calling cv2.projectPoints w…
Apr 21, 2015
99a126d
fix for tests
Apr 21, 2015
53c6de5
Failing test that changes to ProjectPoints didn't change anything
algrs Apr 21, 2015
b64493e
Return squeezed R for backward compatibility
Apr 27, 2015
7e0961e
Loosened tests slightly for buildbot
algrs May 18, 2015
8c61bdd
Remove monkey patch to setuptools that appears to no longer be necessary
algrs Jul 6, 2015
c521273
removed superflous copy operation in camera.unproject_points
Jul 24, 2015
aedc1e9
Merge mattloper into master
algrs Nov 12, 2015
ee00ad1
Fix bad zip downloads during install PR #1
Mar 17, 2016
c39ccf9
Fix of unit test bug PR #2
Mar 18, 2016
1a37333
Test in CircleCI (#4)
paulmelnikow May 30, 2016
479a143
Fix dependencies in setup.py and keep version consistent and RELEASE …
sonnyhu May 31, 2016
ca23ab6
Don't build until after dependencies are installed (#6)
paulmelnikow Jun 2, 2016
96675e6
Update chumpy (#7)
dlsmith Aug 1, 2016
418a65b
convert color_render to TF
febman Oct 13, 2016
6c38136
test fail when overdraw
febman Oct 14, 2016
e65cae7
test passed
febman Oct 18, 2016
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 52 additions & 32 deletions camera.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,39 @@ def is_valid(self):
return True, ''

def compute_r(self):
return self.r_and_derivatives[0].squeeze()
#return self.r_and_derivatives[0].squeeze()
#return self.get_r_and_derivatives(self.v.r, self.rt.r, self.t.r, self.f.r, self.c.r, self.k.r)[0].squeeze()
# method self.r_and_derivatives will compute derivatives as well
#see http://docs.opencv.org/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html
v_t = self.v.r.reshape((-1,3)).copy()
if np.any(self.rt.r != 0.):
v_t = (v_t).dot(cv2.Rodrigues(self.rt.r)[0].T)
if np.any(self.t.r != 0.):
v_t += self.t.r

x_y = v_t[:,:2] / v_t[:,[2]]
uv = x_y
if np.any(self.k.r != 0.):
k = self.k.r
# According to this link: http://docs.opencv.org/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html
# k can have three lengths: (k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6]])
if len(k) == 4:
k1, k2, p1, p2 = k
elif len(k) == 5:
k1, k2, p1, p2, k3 = k
elif len(k) == 8:
k1, k2, p1, p2, k3, k4, k5, k6 = k
else:
raise AttributeError('k has wrong length, got %d, expect 4, 5 or 8' % len(k))
x2_y2 = x_y ** 2.
r2 = x2_y2.sum(axis=1)
r4 = r2 ** 2.
xy = x_y.prod(axis=1)
uv = x_y * (1 + k1 * r2 + k2 * r4 + k3 * r2 * r4)[:,np.newaxis]
uv += 2 * np.vstack([p1 * xy, p2 * xy]).T
uv += np.array([p2, p1]) * (r2[:,np.newaxis] + 2 * x2_y2)
uv = self.f.r * uv + self.c.r
return uv.squeeze()

def compute_dr_wrt(self, wrt):
if wrt not in [self.v, self.rt, self.t, self.f, self.c, self.k]:
Expand Down Expand Up @@ -108,7 +139,7 @@ def unproject_points(self, uvd, camera_space=False):
cam = ProjectPoints3D(**{k: getattr(self, k) for k in self.dterms if hasattr(self, k)})

try:
xy_undistorted_camspace = cv2.undistortPoints(np.asarray(uvd[:,:2].reshape((1,-1,2)).copy()), np.asarray(cam.camera_mtx), cam.k.r)
xy_undistorted_camspace = cv2.undistortPoints(np.asarray(uvd[:,:2].reshape((1,-1,2))), np.asarray(cam.camera_mtx), cam.k.r)
xyz_camera_space = np.hstack((xy_undistorted_camspace.squeeze(), col(uvd[:,2])))
xyz_camera_space[:,:2] *= col(xyz_camera_space[:,2]) # scale x,y by z
if camera_space:
Expand All @@ -129,6 +160,11 @@ def unproject_depth_image(self, depth_image, camera_space=False):
xyz = self.unproject_points(uvd, camera_space=camera_space)
return xyz.reshape((depth_image.shape[0], depth_image.shape[1], -1))

def project_depth_point(self, xyz):
cam = ProjectPoints3D(**{k: getattr(self, k) for k in self.dterms if hasattr(self, k)})
uvd = cam.camera_mtx.dot(xyz)
uv = uvd[:2] / uvd[-1]
return uv

@depends_on('f','c')
def camera_mtx(self):
Expand Down Expand Up @@ -156,59 +192,43 @@ class ProjectPoints3D(ProjectPoints):
def compute_r(self):
result = ProjectPoints.compute_r(self)
return np.hstack((result, col(self.z_coords.r)))

@property
def z_coords(self):

try:
assert(self.v.r.shape[1]==3)
return RigidTransform(v=self.v, rt=self.rt, t=self.t)[:,2]
except:
import pdb; pdb.set_trace()

assert(self.v.r.shape[1]==3)
return RigidTransform(v=self.v, rt=self.rt, t=self.t)[:,2]

def compute_dr_wrt(self, wrt):
result = ProjectPoints.compute_dr_wrt(self, wrt)
if result is None:
return None

if sp.issparse(result):
drz = self.z_coords.dr_wrt(wrt).tocoo()
result = result.tocoo()
result.row = result.row*3/2

IS = np.concatenate((result.row, drz.row*3+2))
JS = np.concatenate((result.col, drz.col))
data = np.concatenate((result.data, drz.data))

result = sp.csc_matrix((data, (IS, JS)), shape=(self.v.r.size, wrt.r.size))
else:
try:
bigger = np.zeros((result.shape[0]/2, 3, result.shape[1]))
bigger[:, :2, :] = result.reshape((-1, 2, result.shape[-1]))
drz = self.z_coords.dr_wrt(wrt)
if drz is not None:
if sp.issparse(drz):
drz = drz.todense()
bigger[:,2,:] = drz.reshape(bigger[:,2,:].shape)

result = bigger.reshape((-1, bigger.shape[-1]))
except:
import pdb; pdb.set_trace()


return result


bigger = np.zeros((result.shape[0]/2, 3, result.shape[1]))
bigger[:, :2, :] = result.reshape((-1, 2, result.shape[-1]))
drz = self.z_coords.dr_wrt(wrt)
if drz is not None:
if sp.issparse(drz):
drz = drz.todense()
bigger[:,2,:] = drz.reshape(bigger[:,2,:].shape)
result = bigger.reshape((-1, bigger.shape[-1]))
return result


def main():

import unittest
from test_camera import TestCamera
suite = unittest.TestLoader().loadTestsFromTestCase(TestCamera)
unittest.TextTestRunner(verbosity=2).run(suite)



if __name__ == '__main__':
main()

20 changes: 20 additions & 0 deletions circle.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
general:
branches:
ignore:
- /zz.*/ # Don't run tests on deprecated branches.

machine:
environment:
PYTHONPATH: /usr/local/lib/python2.7/dist-packages

dependencies:
pre:
- sudo apt-get update
# Is gfortran needed? This was copied from `.travis.yml` which included it.
- sudo apt-get install -qq python-dev gfortran pkg-config liblapack-dev
post:
- make all

test:
override:
- make test
36 changes: 33 additions & 3 deletions common.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ def dImage_wrt_2dVerts_bnd(observed, visible, visibility, barycentric, image_wid
plt.subplot(122)
plt.imshow(xdiffbnd)
plt.title('xdiffbnd')
import pdb; pdb.set_trace()
# import pdb; pdb.set_trace()

idxs = np.isnan(xdiffnb.ravel())
xdiffnb.ravel()[idxs] = xdiffbnd.ravel()[idxs]
Expand Down Expand Up @@ -317,12 +317,20 @@ def dr_wrt_vc(visible, visibility, f, barycentric, frustum, vc_size, num_channel
return result


def draw_visibility_image(gl, v, f, boundarybool_image=None):
def draw_visibility_image(gl, v, f, boundarybool_image=None, x0=None, x1=None, y0=None, y1=None):
v = np.asarray(v)
gl.Disable(GL_TEXTURE_2D)
gl.DisableClientState(GL_TEXTURE_COORD_ARRAY)

result = draw_visibility_image_internal(gl, v, f)

# Crop
if x0 != None and isinstance(x0, int):
result[:y0] = -1
result[y1:] = -1
result[y0:y1, :x0] = -1
result[y0:y1, x1:] = -1

if boundarybool_image is None:
return result

Expand All @@ -333,6 +341,13 @@ def draw_visibility_image(gl, v, f, boundarybool_image=None):
return result
gl.PolygonMode(GL_FRONT_AND_BACK, GL_LINE)
result2 = draw_visibility_image_internal(gl, v, f[faces_to_draw])

if x0 != None and isinstance(x0, int):
result2[:y0] = -1
result2[y1:] = -1
result2[y0:y1, :x0] = -1
result2[y0:y1, x1:] = -1

gl.PolygonMode(GL_FRONT_AND_BACK, GL_FILL)
bbi = boundarybool_image

Expand Down Expand Up @@ -438,14 +453,29 @@ def draw_texcoord_image(glf, v, f, vt, ft, boundarybool_image=None):
return result


def draw_barycentric_image(gl, v, f, boundarybool_image=None):
def draw_barycentric_image(gl, v, f, boundarybool_image=None, x0=None, x1=None,
y0=None, y1=None):
v = np.asarray(v)
without_overdraw = draw_barycentric_image_internal(gl, v, f)
# Crop
if x0 != None and isinstance(x0, int):
without_overdraw[:y0] = -1
without_overdraw[y1:] = -1
without_overdraw[y0:y1, :x0] = -1
without_overdraw[y0:y1, x1:] = -1

if boundarybool_image is None:
return without_overdraw

gl.PolygonMode(GL_FRONT_AND_BACK, GL_LINE)
overdraw = draw_barycentric_image_internal(gl, v, f)
# Crop
if x0 != None and isinstance(x0, int):
overdraw[:y0] = -1
overdraw[y1:] = -1
overdraw[y0:y1, :x0] = -1
overdraw[y0:y1, x1:] = -1

gl.PolygonMode(GL_FRONT_AND_BACK, GL_FILL)

bbi = np.atleast_3d(boundarybool_image)
Expand Down
2 changes: 1 addition & 1 deletion contexts/draw_triangle_shaders_2_1.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def main():

im = gl.getImage()
cv2.imshow('a', im)
import pdb; pdb.set_trace()
# import pdb; pdb.set_trace()



Expand Down
2 changes: 1 addition & 1 deletion contexts/draw_triangle_shaders_3_2.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ def main():
im = gl.getImage()
cv2.imshow('a', im)
print gl.GetError()
import pdb; pdb.set_trace()
# import pdb; pdb.set_trace()



Expand Down
9 changes: 7 additions & 2 deletions lighting.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,12 +180,17 @@ def lambertian_spotlight(v, vn, pos, dir, spot_exponent, camcoord=False, camera_


class LambertianPointLight(Ch):
terms = 'f', 'num_verts', 'light_color'
terms = 'f', 'num_verts', 'light_color', 'double_sided'
dterms = 'light_pos', 'v', 'vc', 'vn'

def on_changed(self, which):
if not hasattr(self, '_lpl'):
self.add_dterm('_lpl', maximum(multiply(a=multiply()), 0.0))
if getattr(self, 'double_sided', False):
from chumpy.ch import abs as absolute
self.add_dterm('_lpl', absolute(multiply(a=multiply())))
self._lpl.a = self._lpl.x
else:
self.add_dterm('_lpl', maximum(multiply(a=multiply()), 0.0))
if not hasattr(self, 'ldn'):
self.ldn = LightDotNormal(self.v.r.size/3)
if not hasattr(self, 'vn'):
Expand Down
2 changes: 1 addition & 1 deletion occlusion_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,4 +137,4 @@ def test_occlusion(self):
visualize = True
suite = unittest.TestLoader().loadTestsFromTestCase(TestOcclusion)
unittest.TextTestRunner(verbosity=2).run(suite)
import pdb; pdb.set_trace()
# import pdb; pdb.set_trace()
29 changes: 29 additions & 0 deletions render_tf/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
all: color_render.so

UNAME := $(shell uname)

ifeq ($(UNAME),Darwin)
OSFLAGS = -undefined dynamic_lookup
else
OSFLAGS =
endif


# Testing for OS X v Linux
OS = $(shell uname -s)

ifeq ($(OS), Darwin)
LIBS = -framework GLUT -framework OpenGL -framework Cocoa
else
LIBS = -lGL -lGLU -lglut
endif


D1 = /usr/local/lib/python2.7/dist-packages/tensorflow/include
D2 = /usr/local/lib/python2.7/site-packages/tensorflow/include

color_render.so: color_render.cc
g++ -std=c++11 -O2 -shared $(OSFLAGS) color_render.cc -o color_render.so -fPIC -I $(D1) -I $(D2) $(LIBS)

clean:
rm -rf *.so *.pyc
Empty file added render_tf/__init__.py
Empty file.
Loading