Example #1
0
 def test_channels(self):
     with open('tests/test_mocapbank.bvh') as f:
         mocap = Bvh(f.read())
     self.assertEqual(mocap.joint_channels('LeftElbow'), ['Zrotation', 'Xrotation', 'Yrotation'])
     self.assertEqual(mocap.joint_channels('Hips'),
                      ['Xposition', 'Yposition', 'Zposition', 'Zrotation', 'Xrotation', 'Yrotation']
                      )
Example #2
0
    def load_from_bvh(self, fname, exclude_bones=None, spec_channels=None):
        if exclude_bones is None:
            exclude_bones = {}
        if spec_channels is None:
            spec_channels = dict()
        with open(fname) as f:
            mocap = Bvh(f.read())

        joint_names = list(
            filter(lambda x: all([t not in x for t in exclude_bones]),
                   mocap.get_joints_names()))
        dof_ind = {'x': 0, 'y': 1, 'z': 2}
        self.len_scale = 0.0254
        self.root = Bone()
        self.root.id = 0
        self.root.name = joint_names[0]
        self.root.channels = mocap.joint_channels(self.root.name)
        self.name2bone[self.root.name] = self.root
        self.bones.append(self.root)
        for i, joint in enumerate(joint_names[1:]):
            bone = Bone()
            bone.id = i + 1
            bone.name = joint
            bone.channels = spec_channels[joint] if joint in spec_channels.keys(
            ) else mocap.joint_channels(joint)
            bone.dof_index = [dof_ind[x[0].lower()] for x in bone.channels]
            bone.offset = np.array(mocap.joint_offset(joint)) * self.len_scale
            bone.lb = [-180.0] * 3
            bone.ub = [180.0] * 3
            self.bones.append(bone)
            self.name2bone[joint] = bone

        for bone in self.bones[1:]:
            parent_name = mocap.joint_parent(bone.name).name
            if parent_name in self.name2bone.keys():
                bone_p = self.name2bone[parent_name]
                bone_p.child.append(bone)
                bone.parent = bone_p

        self.forward_bvh(self.root)
        for bone in self.bones:
            if len(bone.child) == 0:
                bone.end = bone.pos + np.array([
                    float(x)
                    for x in mocap.get_joint(bone.name).children[-1]['OFFSET']
                ]) * self.len_scale
            else:
                bone.end = sum([bone_c.pos
                                for bone_c in bone.child]) / len(bone.child)
Example #3
0
class bvhModel():
	def __init__( self ):
		self.Skeleton = []
		self.mocapdata = None
		self.FileName = ""
		
	def Load( self, pathname, filename ):
		self.PathName = pathname
		self.FileName = filename
		tempFile = pathname + filename
		print(tempFile)
		
		with open( tempFile ) as f:
			self.mocapdata = Bvh( f.read() )
		self.Skeleton = self.GetSkeleton()
		
		return tempFile

	def GetLength( self ):
		if self.mocapdata:
			return self.mocapdata.nframes
		return 0
		
	def GetSkeleton( self ):
		self.Skeleton = []
	
		def iterate_joints( joint ):
			self.Skeleton.append( str( joint ))
			for child in joint.filter( 'JOINT' ):
				iterate_joints( child )
		
		iterate_joints( next( self.mocapdata.root.filter( 'ROOT' )))
		
		return self.Skeleton
	
	def GetData( self ):
		return self.mocapdata
				
	def AsInputData( self, strType, globalGaugeRef, labelRef, gaugeRef ):
		'''
		This seems to convert a bvh to the corresponding CSV in rogerio's paper, which can be used as input to his classifier.
		'''
		data = []
		nFrames = self.GetLength()
		
		pos = self.FileName.rfind( "\\" ) + 1
		outputFile = "data_" + strType.lower() + "\\" + self.FileName[pos:-3] + "csv"
		
        #If an output file is not provided, process the bvh to get corresponding csv input data.
        #otherwise, load a previous version of the file that has been created and return
		if not os.path.isfile( outputFile ): 
			gaugeRef.SetValue( 0 )
			gaugeOffset = 0
			
			if strType.lower() != "standardized":
				labelRef.SetLabel( "Analizing: " + self.FileName )
				gaugeRef.SetRange( 2 * nFrames )
				gaugeOffset = nFrames
				
				print( "File: " + self.FileName + " ... analyzing", end = ' ' )

				# analyzing data to determine its minimum and maximum values
				minimumR = minimumP = [99999, 99999, 99999]
				maximumR = maximumP = [-99999, -99999, -99999]
				
				origin = [0,0,0]
				
				for frame in range( 1, nFrames ):
					globalGaugeRef.SetValue( globalGaugeRef.GetValue() + 1 )
					for joint in self.Skeleton:	
						jointName = joint.split(" ")[1]
						i = 0
						for channel in self.mocapdata.joint_channels( jointName ):
							channelValue = self.mocapdata.frame_joint_channel( frame, jointName, channel )
							
							if channel[1:] != "position":
								if minimumR[i] > channelValue:
									minimumR[i] = channelValue
								if maximumR[i] < channelValue:
									maximumR[i] = channelValue
							else:
								if frame == 1:
									origin[i] = channelValue
								if minimumP[i] > channelValue:
									minimumP[i] = channelValue
								if maximumP[i] < channelValue:
									maximumP[i] = channelValue
							i = (i+1) % 3
								
					gaugeRef.SetValue( frame + 1 )
				labelRef.SetLabel( "Normalizing: " + self.FileName )
				print( "normalizing" )
			else:
				gaugeRef.SetRange( nFrames )
				labelRef.SetLabel( "Loading: " + self.FileName )
				print( "File: " + self.FileName + " ... loading" )
			
			header = ""
			structure = ""
			
			for frame in range( 1, nFrames ):
				globalGaugeRef.SetValue( globalGaugeRef.GetValue() + 1 )
				frameData = []
				for joint in self.Skeleton:	
					jointName = joint.split(" ")[1]
					i = 0
					for channel in self.mocapdata.joint_channels( jointName ):
						if frame == 1:
							if header == "":
								header = jointName + "_" + channel
							else:
								header += "," + jointName + "_" + channel
							structure += jointName + "_" + channel + "\n"
								
						channelValue = self.mocapdata.frame_joint_channel( frame, jointName, channel )
						
						if channel[1:] != "position":
							if strType.lower() == "normalized":
								channelValue = ( channelValue - minimumR[i] ) / ( maximumR[i] - minimumR[i] )
							elif strType.lower() == "rescaled":
								channelValue = 2 * (( channelValue - minimumR[i] ) / ( maximumR[i] - minimumR[i] )) - 1
						else:
							if strType.lower() != "standardized":
								channelValue -= origin[i]
								
								if strType.lower() == "normalized":
									if i == 1:
										channelValue = ( channelValue - minimumP[i] ) / ( maximumP[i] - minimumP[i] )
									else:
										channelValue = 0
								elif strType.lower() == "rescaled":
									channelValue = 2 * (( channelValue - minimumP[i] ) / ( maximumP[i] - minimumP[i] )) - 1
								
						frameData.append( channelValue )
						i = (i+1) % 3
					
				data.append( frameData )
				gaugeRef.SetValue( frame + gaugeOffset + 1 )

			self.SaveAsCSV( data, header, outputFile )
			
			fileNode = open( "structure.txt","w" )
			fileNode.write( structure )
			fileNode.close()
			
		else:
			labelRef.SetLabel( "Loading previous version of file: " + self.FileName )
			print( "Loading previous version of file: " + self.FileName )
			gaugeRef.SetRange( 1 )
			gaugeRef.SetValue( 1 )
			globalGaugeRef.SetValue( globalGaugeRef.GetValue() + nFrames * 2 )
			
			data = np.array( read_csv( outputFile ) ).tolist()
			#data = np.array( read_csv( outputFile, header = None ) ).tolist()
			
		return np.array( data )
		
	def SaveAsCSV( self, data, header, outputFile ):
		fileNode = open( outputFile,"w" )
		
		fileNode.write( header + "\n" )
		for entry in data:
			entryStr = ""
			for value in entry:
				if entryStr != "":
					entryStr += ","
				entryStr += str( value )
			fileNode.write( entryStr + "\n" )
		fileNode.close()
with open('../Data/BVH/Vasso_Miserable_0.bvh') as data:
  mocap = Bvh(data.read())

#Get Mocap Tree
tree = [str(item) for item in mocap.root]
#['HIERARCHY', 'ROOT Hips', 'MOTION', 'Frames: 1068', 'Frame Time: 0.0333333']

#Get ROOT OFFSET
root = next(mocap.root.filter('ROOT'))['OFFSET']
#['3.93885', '96.9818', '-23.2913']

#Get all JOINT names
joints = mocap.get_joints_names() #54
mocap.get_joints_names()[17] #All Names
mocap.joint_offset('Head') #Offset
mocap.joint_channels('Neck') #Channels
mocap.get_joint_channels_index('Spine')
#
mocap.joint_parent_index('Neck') #Parent Index
mocap.joint_parent('Head').name # Parent Name
#mocap.joint_direct_children('Hips') #Direct Children

#Get Frames
mocap.nframes
mocap.frame_time
mocap.frame_joint_channel(22, 'Spine', 'Xrotation')

#SEARCH
[str(node) for node in mocap.search('JOINT', 'LeftShoulder')] #Single Item
[str(node) for node in mocap.search('JOINT')] #All Items
Example #5
0
from bvh import Bvh

with open('Male2_A1_Stand.bvh') as f:
    mocap = Bvh(f.read())

for name in mocap.get_joints_names():
    print(name + " : ", mocap.frame_joint_channels(0, name, mocap.joint_channels(name)))