Data Analysis in Grasshopper

This is a introduction on how to approach a few basic techniques of analysis; speed, location and head-tracking. Treat this as a starting point of concepts that can be applied to further analysis.

This page introduces data formats, useful grasshopper concepts and helper scripts. The sub-page has examples of the above:

pageAnalysis Examples

Kinect Body Tracking Data

Formatted in a .csv file, openable in programs like Excel.

Each row corresponds to the frame number. Columns correspond to the body joint as in Microsoft's Body Joints Documentation.

Each joint value has position and rotation, formatted as: [joint index \ confidence \ pos-x \ pos-y \ pos-z \ rot-x \ rot-y \ rot-z]


Kinect Point Cloud Data

Kinect Point Cloud data uses the Intensity field commonly found in e57 files as the frame number. In Point Cloud applications that exposes this parameter, such as CloudCompare, you may use this field to review and scrub through your data.


Grasshopper Basics

Basic introduction below, or find on YouTube.


Key Grasshopper Concepts

Grasshopper concepts that will be helpful in working with Kinect data in Grasshopper.

Data Trees

Data in Grasshopper flows from left (inputs) to right (outputs). This data is in the form of trees. Branches denoted as {x}. Branches can have depth, denoted as {y;x}

You can go between depths by [grafting], [trimming] and [flattening]. [Trimming] takes a Depth parameter to specify how to cut the tree.

Grafting and flattening can be accessed via right-clicking inputs/outputs. Simplify is another useful tree operation that removes any unnecessary depth info.

When operating on branches with different lengths, note that the last item of the shorter branch will repeat itself to accommodate.

Throughout these exercises, a lot of the time you will want to match the length of data structures, e.g. a point cloud should consist of the same number of points as colour values per point.


Attractors

Commonly used as Point Attractor. The logic behind attractors can be generalised as assigning a value to many things, through the use of attractors. Attractors can be one or many as well, and in the form of points, planes, curves or other geometry.

Here is an example of using [Distance] values as Input for [Scale]:

Remapping

Usually these values need to be [Remapped]. Remapping takes values V, along a source domain S, and shrinks or stretches them to fit into a target domain T. It outputs an indiscriminate remap R, or a clipped remap C, that caps input values to the new domain if smaller or larger than the input domain.

Source domain S can be given the [Bounds] component to parametrically define the domain of the input values V.

Graph Mapping

[GraphMapper] is a component that gives you more nuance in remapping through a function. This graph can be defined by right-clicking the component > graph types.

The input values are the x and outputted as the y. Double-clicking the component allows you to adjust the domain. This cannot be done parametrically though so usually you input values remapped to domain 0-1. On the output end, these values can be re-scaled for use.


Working with Kinect Data

Rhino unit settings set to METERS

Helper Scripts:

Like with all grashopper plugins, for Volvox, Right Click > Properties > Unblock before unzipping and installing it.


Reading Kinect Body Tracking Data

Follow the prompts to navigate through the script: 1. Select a file 2. Pick a start/stop frame range, use the reference to know what is available, or browse your .csv. 3. Allow data through the Data Dam. (Data Dams are useful to stage your script into steps, only executing the next stage when you are ready)

The script essentially reads and deconstructs the .csv kinect body tracing data formatting into Rhino data.

The [List Item] towards the end exposes the data per joint. At the moment only the position of the joints is mapped to Rhino points, accounting for the Kinect's coordinate system.


Each Grasshopper Branch refers to a frame, note that the frame numbers are completely stripped now as branches start from {0}. Each branch has 32 items in it, corresponding to each body joint.


Some additional helpers to further choose a range of frames, previewing the bodies as curves, and extracting joint(s).

When working with multiple frames or joints, you will likely have to [Trim Tree] for a cleaner data structure. Single frames or single joints will not work with [Trim Tree]


Kinect Body Data Trees

By default, body data trees are where branches are frames, and each frame is a list of body joints. [Flip Matrix] is a key component, if you imagine branches and the data within a branch as a table, Flip Matrix swaps rows and columns. In this case, each branch becomes the joint, and within each branch the list specifies that joint at a frame.

Before: Branch {0} was frame 10, branch {1} was 11, with its items as the body joints indexed from 0 - 31. Index 8 of each frame is HAND_LEFT. After Flip matrix: Branch {8} is now all the positions of HAND_LEFT, with index 0 as frame 10, index 1 as frame 11, and so on. Polylining this data structure shows that this is the case.


Smoothing Data

One way to smooth data is to convert points to polylines and then smoothing them out. Other methods such as interpolating may also work. Polylines may be smoothed. Kinky curves interpolates data only if below a threshold angle (in radians). Note that when listing multiple joints, the tree has to be trimmed and flipped so that each branch is the one joint to be able to turned into a curve.


Loading Kinect Point Cloud Data

Using the Volvox plugin's [Load E57] to load point clouds without losing any additional data, such as the frame data mapped to the Kinect point cloud's intensity.

Volvox components often have a run R, and an abort A, input. Use buttons to trigger them.

Check for these additional data fields (keys) using the [List Key] and [Get Data] to verify. Use the same key name in [Cull Cloud] along with the domain specifying any frame ranges. Kinect Data is in meters, so a Scale of 1000 is applied for millimeter Rhino workspace.

This will output a single point cloud.


This helper will breakdown a single Kinect point cloud into a point cloud per frame. Use [Get Data] and some [Set] components to construct a branch of point indices corresponding to each frame, and Volvox's [Get Points] to use the point indices to pull the point cloud points into their respective branches.


Transforming Data

Transform any data by using the matrix transformation helper script below.

The generic Transform components can take transformation matrices. The Transformation matrix can be constructed from a single list of values from each row. Usually this in the form of 16 values, in the form of a 4x4 matrix.

If CloudCompare data, paste data into a panel, it is organised as 4 items with 4 values per item split with a [space] character. Use [Split the Text and flatten] with [Construct Matrix] as a 4x4 matrix.


Saving out Point Clouds

Construct a filepath and filename with the .e57 extension to export point clouds from Grasshopper.

Volvox components often have a run R, and an abort A, input. Use buttons to trigger them.

Last updated