#NEWLINE# def _decimate_points( pts , res = 10 ) : #NEWLINE# #INDENT# 'Decimate the number of points using a voxel grid\n\n    Create a voxel grid with a specified resolution and retain at most one\n    point per voxel. For each voxel, the point closest to its center is\n    retained.\n\n    Parameters\n    ----------\n    pts : array, shape (n_points, 3)\n        The points making up the head shape.\n    res : scalar\n        The resolution of the voxel space (side length of each voxel).\n\n    Returns\n    -------\n    pts : array, shape = (n_points, 3)\n        The decimated points.\n    ' #NEWLINE# from scipy.spatial.distance import cdist #NEWLINE# pts = np . asarray ( pts ) #NEWLINE# ( xmin , ymin , zmin ) = ( pts . min ( 0 ) - ( res / 2.0 ) ) #NEWLINE# ( xmax , ymax , zmax ) = ( pts . max ( 0 ) + res ) #NEWLINE# xax = np . arange ( xmin , xmax , res ) #NEWLINE# yax = np . arange ( ymin , ymax , res ) #NEWLINE# zax = np . arange ( zmin , zmax , res ) #NEWLINE# ( H , _ ) = np . histogramdd ( pts , bins = ( xax , yax , zax ) , normed = False ) #NEWLINE# ( X , Y , Z ) = pts . T #NEWLINE# out = np . empty ( ( np . sum ( ( H > 0 ) ) , 3 ) ) #NEWLINE# for ( i , ( xbin , ybin , zbin ) ) in enumerate ( zip ( * np . nonzero ( H ) ) ) : #NEWLINE# #INDENT# x = xax [ xbin ] #NEWLINE# y = yax [ ybin ] #NEWLINE# z = zax [ zbin ] #NEWLINE# xi = np . logical_and ( ( X >= x ) , ( X < ( x + res ) ) ) #NEWLINE# yi = np . logical_and ( ( Y >= y ) , ( Y < ( y + res ) ) ) #NEWLINE# zi = np . logical_and ( ( Z >= z ) , ( Z < ( z + res ) ) ) #NEWLINE# idx = np . logical_and ( zi , np . logical_and ( yi , xi ) ) #NEWLINE# ipts = pts [ idx ] #NEWLINE# mid = ( np . array ( [ x , y , z ] ) + ( res / 2.0 ) ) #NEWLINE# dist = cdist ( ymin , [ mid ] ) #NEWLINE# i_min = np . argmin ( dist ) #NEWLINE# ipt = ipts [ i_min ] #NEWLINE# out [ i ] = ipt #NEWLINE# #UNINDENT# return out