Created
September 26, 2019 19:11
-
-
Save decrispell/b0dbcf81ce3d55abe18eedc7ede88407 to your computer and use it in GitHub Desktop.
Compute surface normals from 3-plane "xyz" image data
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import numpy as np | |
def normals_from_xyz(xyz, smooth_sigma=None): | |
""" | |
Given a 3-plane float image containing x,y,z coordinates, | |
compute the surface normals at each pixel. | |
Returns a 3-plane floating point image with nx,ny,nz per pixel. | |
""" | |
if smooth_sigma is not None: | |
xyz = np.array(xyz) # make copy of input | |
for p in range(3): | |
xyz[:,:,p] = gaussian_filter(xyz[:,:,p], sigma=smooth_sigma) | |
dx_du, dx_dv = np.gradient(xyz[:,:,0]) | |
dy_du, dy_dv = np.gradient(xyz[:,:,1]) | |
dz_du, dz_dv = np.gradient(xyz[:,:,2]) | |
grad_u = np.stack((dx_du, dy_du, dz_du), axis=2) | |
grad_v = np.stack((dx_dv, dy_dv, dz_dv), axis=2) | |
# compute surface normals as cross product of dx/du and dx/dv | |
xyz_norm = np.cross(grad_u, grad_v, axis=2) | |
xyz_norm /= np.expand_dims(np.linalg.norm(xyz_norm, axis=2), axis=2) | |
return xyz_norm |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment