Kinect

Depth camera, speaker direction, and skeleton tracking

Kinect to OSC

OSC stands for Open Sound Control and is a generally useful UDP based protocol for realtime data.

R. Luke DuBois and Surya Mattu built on top of Microsoft's Body Basics example to send the Kinect 2's skeleton data out via OSC: ITPKinect2OSC This project requires a working install of MS Visual Studio (version??) on a PC to build.

The problem is that browsers are unable to receive OSC data so we need to take another step to get it into the "live web" world

Node OSC to WebSocket

Fortunately, there is a node library for OSC (actually several) called osc-min and using a node script that incorporates it along with socket.io-client we are able to relay the OSC data generated by the ITPKinect2OSC project to a websocket server!

This example (kinectosctows.js) assumes it is being run on the same machine as the ITPKinect2OSC application and connects to a remote node server running socket.io.

Socket.io Server

A node server running socket.io is required to serve out the kinect data to the browsers via websocket connections. It should be programmed to receive the data as sent by the above script:

		socket.on('kinect', function(data) {
			socket.broadcast.emit('kinect', data);
			//console.log(util.inspect(data, {depth: 10}));
		});		
		
Here is a full server example: kinectwsserver.js

Web Client

Finally, we can write a webpage which receives the data and does something with it:

<html>
	<head>
		<script type="text/javascript" src="/socket.io/socket.io.js"></script>
		<script type="text/javascript">
			var joints = [];
		
			var socket = io.connect();
			
			socket.on('connect', function() {
				console.log("Connected");
			});
	
			socket.on('kinect', function (data) {
				// Format the data as it comes in a way that we can draw in 2D
				joints[data.position] = {x: (data.x)*canvas.width/2+canvas.width/2,
									y: (data.y*-1)*canvas.height/2+canvas.height/2};
			});

			var canvas;
			var context;

			var color = "rgb("+
			  Math.floor(Math.random()*128+127)+","+
			  Math.floor(Math.random()*128+127)+","+
			  Math.floor(Math.random()*128+127)+")";

			var initcanvas = function() {			
				canvas = document.getElementById('mycanvas');
				context = canvas.getContext('2d');	

				setInterval(clearDrawing, 1000/30);
			};
			
			var clearDrawing = function() {
				context.clearRect(0,0,canvas.width,canvas.height);
				context.beginPath();
				context.strokeStyle=color;
				context.fillStyle=color;
				context.lineWidth = 5;
				
				// Connect the dots
				var lastJoint = null;
				for (var i = 0; i < joints.length; i++) {
					if (joints[i] != null) {
						if (lastJoint == null) {
							context.moveTo(joints[i].x,joints[i].y);
							context.fillText(i,joints[i].x-5,joints[i].y-5);
						}
						else {
							context.lineTo(joints[i].x,joints[i].y);
							context.fillText(i,joints[i].x-5,joints[i].y-5);
						}
						lastJoint = joints[i];
					}
				}
				context.stroke();			
			}
			
			document.addEventListener("DOMContentLoaded", initcanvas, false);
		</script>
		<style>
			body {
				background-color: #000000;
			}
			#canvas_div {
				position: absolute;
				top: 0px;
				left: 0px;
				width: 854px;
				margin: 0, auto;
				z-index: 2;
			}			
		</style>		
	</head>
	<body>
		<div id="content_wrapper">
			<div id="canvas_div">
				<canvas width="854" height="480" id="mycanvas"></canvas>
			</div>
		</div>
	</body>
</html>