title: Point Cloud from Kinect using Freenect and Python
body: <p>I have an XBox 360 Kinect Sensor connected via Linux Mint.  I am trying to create a CSV file where the Z values represent the distance from the sensor-in short, I want to use the Kinect as a short-range 3D scanner.  I have the code below producing a CSV file but the values are quite strange and do not seem to represent the real world XYZ values.  Here is a sample of the resulting CSV file and all rows have similar values.
  x,y,z
  -0.22424937966362582,0.16117004627017431,-0.39249255932230664
  -0.22424937966362582,0.16050597521014062,-0.39249255932230664
  -0.22424937966362582,0.15984190415010693,-0.39249255932230664</p>
  
  <p>What do these number mean?  How can I get Z values in meters or centimeters? Where am I going wrong?</p>
  
  <p>Here is an example of the code I am running that was gleaned from this Github page <a href="http://hhttps://github.com/amiller/libfreenect-goodies" rel="nofollow">https://github.com/amiller/libfreenect-goodie</a>s</p>
  
  <p>Here is my Python code.</p>
  
  <pre><code>#!/usr/bin/python
  
  import sys, traceback
  import freenect
  import cv2
  import numpy as np
  import csv
  print "running"
  
  def get_depth():
      array,_ = freenect.sync_get_depth()
      array = array.astype(np.uint8)
      return array
  
  def depth2xyzuv(depth, u=None, v=None):
      if u is None or v is None:
          u,v = np.mgrid[:480,:640]  
      # Build a 3xN matrix of the d,u,v data
      C = np.vstack((u.flatten(), v.flatten(), depth.flatten(), 0*u.flatten()+1))
      # Project the duv matrix into xyz using xyz_matrix()
      X,Y,Z,W = np.dot(xyz_matrix(),C)
      X,Y,Z = X/W, Y/W, Z/W
      xyz = np.vstack((X,Y,Z)).transpose()
      xyz = xyz[Z&lt;0,:]
      # Project the duv matrix into U,V rgb coordinates using rgb_matrix() and xyz_matrix()
      U,V,_,W = np.dot(np.dot(uv_matrix(), xyz_matrix()),C)
      U,V = U/W, V/W
      uv = np.vstack((U,V)).transpose()
      uv = uv[Z&lt;0,:]
      return xyz
  def uv_matrix():
    """Returns a matrix you can use to project XYZ coordinates (in meters) into
        U,V coordinates in the kinect RGB image"""
    rot = np.array([[ 9.99846e-01,   -1.26353e-03,   1.74872e-02], 
                    [-1.4779096e-03, -9.999238e-01,  1.225138e-02],
                    [1.747042e-02,   -1.227534e-02,  -9.99772e-01]])
    trans = np.array([[1.9985e-02, -7.44237e-04,-1.0916736e-02]])
    m = np.hstack((rot, -trans.transpose()))
    m = np.vstack((m, np.array([[0,0,0,1]])))
    KK = np.array([[529.2, 0, 329, 0],
                   [0, 525.6, 267.5, 0],
                   [0, 0, 0, 1],
                   [0, 0, 1, 0]])
    m = np.dot(KK, (m))
    return m
  def xyz_matrix():
    fx = 594.21
    fy = 591.04
    a = -0.0030711
    b = 3.3309495
    cx = 339.5
    cy = 242.7
    mat = np.array([[1/fx, 0, 0, -cx/fx],
                    [0, -1/fy, 0, cy/fy],
                    [0,   0, 0,    -1],
                    [0,   0, a,     b]])
    return mat
  depth = get_depth()
  depthpoints = depth2xyzuv(depth)
  
  print "Create csv header..."
  f = open("/home/gerry/depthtest.csv",'a')
  f.write("x,y,z\n")
  f.close()
  print "writing to text file...please wait...."
  with open("/home/gerry/depthtest.csv", 'a') as f:
      csvwriter = csv.writer(f)
      csvwriter.writerows(depthpoints)   
  print "finished writing to text file..."
  print "done"
  </code></pre>