├── .gitignore ├── README.md ├── examples └── run.py ├── pyfreenect2.cpp ├── pyfreenect2.hpp ├── pyfreenect2.py ├── rebuild.sh ├── setup.py ├── src ├── Frame.cpp ├── FrameMap.cpp ├── Freenect2.cpp ├── Freenect2Device.cpp ├── Registration.cpp ├── SmartFrame.cpp ├── SmartFrame.h ├── SmartPtr.hpp └── SyncMultiFrameListener.cpp └── test.py /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | dist/ 3 | pyfreenect2.egg-info/ 4 | *.pyc 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | pyfreenect2 2 | =========== 3 | 4 | Python bindings to [libfreenect2](https://github.com/OpenKinect/libfreenect2). 5 | 6 | Requirements 7 | --------- 8 | 9 | - Python2 (python3 support : https://github.com/LovelyHorse/py3freenect2) 10 | - Numpy 11 | - Scipy (as appropriated by python version) : 12 | - Python Imaging Library (used for scipy.misc.im* functions) : http://www.pythonware.com/products/pil/ 13 | - OpenCV 14 | 15 | Installation 16 | --------- 17 | 18 | To install, run `sudo python setup.py install`. 19 | 20 | Usage 21 | --------- 22 | 23 | For usage, see `test.py`. 24 | 25 | 26 | TODO List 27 | --------- 28 | * ~~Make `test.py` actually display the frames~~ 29 | * Implement Registration.apply (in py_Registration_apply) 30 | * Make the pipeline argument of Freenect2Device's constructor actually do something 31 | * Test everything 32 | 33 | You can probably find more TODOs in [Issues](https://github.com/tikiking1/pyfreenect2/issues) or by `grep -R TODO .`. 34 | -------------------------------------------------------------------------------- /examples/run.py: -------------------------------------------------------------------------------- 1 | import pyfreenect2 2 | import cv2 3 | import scipy.misc 4 | import signal 5 | import numpy as np 6 | 7 | pf = pyfreenect2.PyFreeNect2() 8 | 9 | cv2.startWindowThread() 10 | cv2.namedWindow("RGB") 11 | while True: 12 | extracted_frame = pf.get_new_frame(get_BGR = True) 13 | resized = scipy.misc.imresize(extracted_frame.BGR, size = 0.5) 14 | cv2.imshow("RGB", resized) 15 | cv2.waitKey(20) 16 | print "done" 17 | 18 | -------------------------------------------------------------------------------- /pyfreenect2.cpp: -------------------------------------------------------------------------------- 1 | #include "pyfreenect2.hpp" 2 | #include 3 | 4 | static PyMethodDef pyfreenect2Methods[] = { 5 | // Freenect2 6 | { "numberOfDevices", py_numberOfDevices, METH_VARARGS, NULL }, 7 | { "getDefaultDeviceSerialNumber", py_getDefaultDeviceSerialNumber, METH_VARARGS, NULL }, 8 | // Freenect2Device 9 | { "Freenect2Device_new", py_Freenect2Device_new, METH_VARARGS, NULL }, 10 | { "Freenect2Device_start", py_Freenect2Device_start, METH_VARARGS, NULL }, 11 | { "Freenect2Device_stop", py_Freenect2Device_stop, METH_VARARGS, NULL }, 12 | { "Freenect2Device_close", py_Freenect2Device_close, METH_VARARGS, NULL }, 13 | { "Freenect2Device_setColorFrameListener", py_Freenect2Device_setColorFrameListener, METH_VARARGS, NULL }, 14 | { "Freenect2Device_setIrAndDepthFrameListener", py_Freenect2Device_setIrAndDepthFrameListener, METH_VARARGS, NULL }, 15 | /** Configure depth processing. */ 16 | { "Freenect2Device_setDeepConfiguration", py_Freenect2Device_setDeepConfiguration, METH_VARARGS, NULL }, 17 | { "Freenect2Device_getSerialNumber", py_Freenect2Device_getSerialNumber, METH_VARARGS, NULL }, 18 | { "Freenect2Device_getFirmwareVersion", py_Freenect2Device_getFirmwareVersion, METH_VARARGS, NULL }, 19 | { "Freenect2Device_getColorCameraParams", py_Freenect2Device_getColorCameraParams, METH_VARARGS, NULL }, 20 | { "Freenect2Device_getIRCameraParams", py_Freenect2Device_getIRCameraParams, METH_VARARGS, NULL }, 21 | // SyncMultiFrameListener 22 | { "SyncMultiFrameListener_new", py_SyncMultiFrameListener_new, METH_VARARGS, NULL }, 23 | { "SyncMultiFrameListener_waitForNewFrame", py_SyncMultiFrameListener_waitForNewFrame, METH_VARARGS, NULL }, 24 | { "SyncMultiFrameListener_release", py_SyncMultiFrameListener_release, METH_VARARGS, NULL }, 25 | // Registration 26 | { "Registration_new", py_Registration_new, METH_VARARGS, NULL }, 27 | { "Registration_apply", py_Registration_apply, METH_VARARGS, NULL }, 28 | // FrameMap 29 | { "FrameMap_getFrame", py_FrameMap_getFrame, METH_VARARGS, NULL }, 30 | // Frame 31 | { "Frame_getHeight", py_Frame_getHeight, METH_VARARGS, NULL }, 32 | { "Frame_getWidth", py_Frame_getWidth, METH_VARARGS, NULL }, 33 | { "Frame_getData", py_Frame_getData, METH_VARARGS, NULL }, 34 | { "Frame_getDepthData", py_Frame_getDepthData, METH_VARARGS, NULL }, 35 | // Sentinel 36 | { NULL, NULL, 0, NULL} 37 | }; 38 | 39 | PyMODINIT_FUNC init_pyfreenect2() { 40 | 41 | /// enables debug of libfreenect2 42 | ///libfreenect2::setGlobalLogger(libfreenect2::createConsoleLogger(libfreenect2::Logger::Debug)); 43 | 44 | import_array(); 45 | Py_InitModule("_pyfreenect2", pyfreenect2Methods); 46 | import_array(); 47 | } 48 | -------------------------------------------------------------------------------- /pyfreenect2.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | //////////////////////////////////////////////////////////////////////////////// 12 | // GLOBAL FUNCTIONS // 13 | //////////////////////////////////////////////////////////////////////////////// 14 | 15 | libfreenect2::Freenect2& getGlobalFreenect2(); 16 | 17 | PyObject *py_numberOfDevices(PyObject *self, PyObject *args); 18 | PyObject *py_getDefaultDeviceSerialNumber(PyObject *self, PyObject *args); 19 | 20 | //////////////////////////////////////////////////////////////////////////////// 21 | // Freenect2Device // 22 | //////////////////////////////////////////////////////////////////////////////// 23 | 24 | PyObject *py_Freenect2Device_new(PyObject *self, PyObject *args); 25 | void py_Freenect2Device_destroy(PyObject *deviceCapsule); 26 | 27 | PyObject *py_Freenect2Device_start(PyObject *self, PyObject *args); 28 | PyObject *py_Freenect2Device_stop(PyObject *self, PyObject *args); 29 | PyObject *py_Freenect2Device_close(PyObject *self, PyObject *args); 30 | 31 | PyObject *py_Freenect2Device_setColorFrameListener(PyObject *self, PyObject *args); 32 | PyObject *py_Freenect2Device_setIrAndDepthFrameListener(PyObject *self, PyObject *args); 33 | /** Configure depth processing. */ 34 | PyObject *py_Freenect2Device_setDeepConfiguration(PyObject *self, PyObject *args); 35 | 36 | PyObject *py_Freenect2Device_getSerialNumber(PyObject *self, PyObject *args); 37 | PyObject *py_Freenect2Device_getFirmwareVersion(PyObject *self, PyObject *args); 38 | PyObject *py_Freenect2Device_getColorCameraParams(PyObject *self, PyObject *args); 39 | PyObject *py_Freenect2Device_getIRCameraParams(PyObject *self, PyObject *args); 40 | 41 | void py_Freenect2Device_ColorCameraParams_destroy(PyObject *colorCameraParamsCapsule); 42 | void py_Freenect2Device_IRCameraParams_destroy(PyObject *irCameraParamsCapsule); 43 | 44 | //////////////////////////////////////////////////////////////////////////////// 45 | // SyncMultiFrameListener // 46 | //////////////////////////////////////////////////////////////////////////////// 47 | 48 | PyObject *py_SyncMultiFrameListener_new(PyObject *self, PyObject *args); 49 | void py_SyncMultiFrameListener_destroy(PyObject *object); 50 | 51 | PyObject *py_SyncMultiFrameListener_waitForNewFrame(PyObject *self, PyObject *args); 52 | PyObject *py_SyncMultiFrameListener_release(PyObject *self, PyObject *args); 53 | 54 | //////////////////////////////////////////////////////////////////////////////// 55 | // FrameMap // 56 | //////////////////////////////////////////////////////////////////////////////// 57 | 58 | void py_FrameMap_destroy(PyObject *object); 59 | 60 | PyObject *py_FrameMap_getFrame(PyObject *self, PyObject *args); 61 | 62 | //////////////////////////////////////////////////////////////////////////////// 63 | // Frame // 64 | //////////////////////////////////////////////////////////////////////////////// 65 | 66 | void py_Frame_destroy(PyObject *object); 67 | 68 | PyObject *py_Frame_getHeight(PyObject *self, PyObject *args); 69 | PyObject *py_Frame_getWidth(PyObject *self, PyObject *args); 70 | PyObject *py_Frame_getData(PyObject *self, PyObject *args); 71 | PyObject *py_Frame_getDepthData(PyObject *self, PyObject *args); 72 | 73 | //////////////////////////////////////////////////////////////////////////////// 74 | // Registration // 75 | //////////////////////////////////////////////////////////////////////////////// 76 | 77 | PyObject *py_Registration_new(PyObject *self, PyObject *args); 78 | void py_Registration_destroy(PyObject *object); 79 | 80 | PyObject *py_Registration_apply(PyObject *self, PyObject *args); 81 | -------------------------------------------------------------------------------- /pyfreenect2.py: -------------------------------------------------------------------------------- 1 | import _pyfreenect2 2 | import numpy as np 3 | from collections import namedtuple 4 | from ctypes import * 5 | import types 6 | 7 | ExtractedKinectFrame = namedtuple("ExtractedKinectFrame", 8 | ['RGB', 'BGR', 'IR', 'DEPTH']) 9 | 10 | def swap_c0c2(a): 11 | a2 = a.copy() 12 | a2[:,:,0] = a[:,:,2] 13 | a2[:,:,2] = a[:,:,0] 14 | return a2 15 | 16 | class PyFreeNect2(object): 17 | def __init__(self): 18 | 19 | 20 | self.serialNumber = getDefaultDeviceSerialNumber() 21 | self.kinect = Freenect2Device(self.serialNumber) 22 | 23 | self.frameListener = SyncMultiFrameListener(Frame.COLOR, 24 | Frame.IR, 25 | Frame.DEPTH) 26 | self.kinect.setColorFrameListener(self.frameListener) 27 | self.kinect.setIrAndDepthFrameListener(self.frameListener) 28 | self.kinect.start() 29 | self.registration = Registration(self.kinect.ir_camera_params, 30 | self.kinect.color_camera_params) 31 | print "%s setup done" % (self.__class__.__name__) 32 | 33 | def get_new_frame(self, get_BGR = False): 34 | frames = self.frameListener.waitForNewFrame() 35 | rgbFrame = frames.getFrame(Frame.COLOR) 36 | depthFrame = frames.getFrame(Frame.DEPTH) 37 | 38 | rgb_frame = rgbFrame.getRGBData() 39 | #rgb_to_bgr(rgb_frame) 40 | #bgr_to_rgb(rgb_frame) 41 | 42 | depth_frame = depthFrame.getDepthData() 43 | 44 | bgr_frame = swap_c0c2(rgb_frame) if get_BGR else None 45 | 46 | ## TODO :: IR 47 | ext_k =ExtractedKinectFrame(RGB = rgb_frame, 48 | BGR = bgr_frame, 49 | DEPTH = depth_frame, 50 | IR = None) 51 | self.frameListener.release(frames) 52 | return ext_k 53 | 54 | def __del__(self): 55 | self.kinect.stop() 56 | 57 | ## todo :: call close method? was in original pyfreect test.py 58 | #self.kinect.close() 59 | 60 | class PyFreenect2Error(Exception): 61 | def __init__(self, message): 62 | super(PyFreenect2Error, self).__init__(message) 63 | class DeveloperIsALazyBastardError(Exception): 64 | def __init__(self, message): 65 | super(DeveloperIsALazyBastardError, self).__init__(message) 66 | 67 | ################################################################################ 68 | # GLOBAL FUNCTIONS # 69 | ################################################################################ 70 | 71 | def numberOfDevices(): 72 | return _pyfreenect2.numberOfDevices() 73 | 74 | def getDefaultDeviceSerialNumber(): 75 | if numberOfDevices() == 0: 76 | raise PyFreenect2Error("Could not find a Kinect v2") 77 | else: 78 | return _pyfreenect2.getDefaultDeviceSerialNumber() 79 | 80 | ################################################################################ 81 | # Freenect2Device # 82 | ################################################################################ 83 | 84 | class DeepConfig(Structure): 85 | _fields_ = [("MinDepth", c_float), ("MaxDepth", c_float),("EnableBilateralFilter", c_bool),("EnableEdgeAwareFilter", c_bool)] 86 | 87 | class Freenect2Device: 88 | def __init__(self, serialNumber, pipeline=None): 89 | if pipeline is not None: 90 | raise DeveloperIsALazyBastardError("pyfreenect2.PacketPipeline is not yet implemented") 91 | self._capsule = _pyfreenect2.Freenect2Device_new(serialNumber) 92 | def start(self): 93 | return _pyfreenect2.Freenect2Device_start(self._capsule) 94 | def stop(self): 95 | _pyfreenect2.Freenect2Device_stop(self._capsule) 96 | def close(self): 97 | _pyfreenect2.Freenect2Device_close(self._capsule) 98 | def setColorFrameListener(self, listener): 99 | if not isinstance(listener, SyncMultiFrameListener): 100 | raise TypeError("Argument to Freenect2Device.setColorFrameListener must be of type Freenect2Device.SyncMultiFrameListener") 101 | else: 102 | print "listener capsule : " , listener._capsule 103 | _pyfreenect2.Freenect2Device_setColorFrameListener(self._capsule, listener._capsule) 104 | def setIrAndDepthFrameListener(self, listener): 105 | if not isinstance(listener, SyncMultiFrameListener): 106 | raise TypeError("Argument to Freenect2Device.setIrAndDepthFrameListener must be of type Freenect2Device.SyncMultiFrameListener") 107 | else: 108 | _pyfreenect2.Freenect2Device_setIrAndDepthFrameListener(self._capsule, listener._capsule) 109 | 110 | def setDeepConfiguration(self, conf): 111 | if not isinstance(conf, DeepConfig): 112 | raise TypeError("Argument to Freenect2Device.setConfig must be of type Freenect2Device.DeepConfig") 113 | else: 114 | _pyfreenect2.Freenect2Device_setDeepConfiguration(self._capsule, conf) 115 | 116 | @property 117 | def serial_number(self): 118 | return _pyfreenect2.Freenect2Device_getSerialNumber(self._capsule) 119 | @property 120 | def firmware_version(self): 121 | return _pyfreenect2.Freenect2Device_getFirmwareVersion(self._capsule) 122 | @property 123 | def color_camera_params(self): 124 | return _pyfreenect2.Freenect2Device_getColorCameraParams(self._capsule) 125 | @property 126 | def ir_camera_params(self): 127 | return _pyfreenect2.Freenect2Device_getIRCameraParams(self._capsule) 128 | 129 | ################################################################################ 130 | # SyncMultiFrameListener # 131 | ################################################################################ 132 | 133 | class SyncMultiFrameListener: 134 | def __init__(self, *args): 135 | types = 0 136 | for arg in args: 137 | types |= int(arg) 138 | self._capsule = _pyfreenect2.SyncMultiFrameListener_new(types) 139 | def waitForNewFrame(self): 140 | return FrameMap(_pyfreenect2.SyncMultiFrameListener_waitForNewFrame(self._capsule)) 141 | def release(self,frames): 142 | _pyfreenect2.SyncMultiFrameListener_release(self._capsule,frames._capsule) 143 | 144 | ################################################################################ 145 | # FrameMap # 146 | ################################################################################ 147 | 148 | class FrameMap: 149 | def __init__(self, capsule): 150 | self._capsule = capsule 151 | def getFrame(self, frame_type): 152 | if not frame_type in (1, 2, 4): 153 | raise ValueError("frame_type must be one of Frame.COLOR, Frame.IR, or Frame.DEPTH") 154 | else: 155 | return Frame(_pyfreenect2.FrameMap_getFrame(self._capsule, frame_type)) 156 | 157 | ################################################################################ 158 | # Frame # 159 | ################################################################################ 160 | 161 | class Frame: 162 | COLOR = 1 163 | IR = 2 164 | DEPTH = 4 165 | def __init__(self, capsule): 166 | self._capsule = capsule 167 | def getHeight(self): 168 | return _pyfreenect2.Frame_getHeight(self._capsule) 169 | def getWidth(self): 170 | return _pyfreenect2.Frame_getWidth(self._capsule) 171 | def getRGBData(self): 172 | ## todo fix fliplr necessity 173 | ## todo fix BGR :/ 174 | BGR = np.fliplr(_pyfreenect2.Frame_getData(self._capsule)) 175 | RGB = swap_c0c2(BGR) 176 | return RGB 177 | 178 | def getDepthData(self): 179 | ## todo fix fliplr necessity 180 | return np.fliplr(_pyfreenect2.Frame_getDepthData(self._capsule)) 181 | 182 | ################################################################################ 183 | # Registration # 184 | ################################################################################ 185 | 186 | class Registration: 187 | def __init__(self, ir_camera_params, color_camera_params): 188 | self._capsule = _pyfreenect2.Registration_new(ir_camera_params, color_camera_params) 189 | def apply(self, rgbFrame, depthFrame): 190 | return _pyfreenect2.Registration_apply(self._capsule, rgbFrame, depthFrame) 191 | -------------------------------------------------------------------------------- /rebuild.sh: -------------------------------------------------------------------------------- 1 | sudo rm /usr/local/lib/python2.7/dist-packages/pyfreenect2-0.0.0-py2.7-linux-x86_64.egg 2 | sudo python2 setup.py install 3 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, Extension 2 | 3 | import numpy 4 | 5 | libfreenect2_module = Extension("_pyfreenect2", 6 | libraries=["freenect2"], 7 | sources=["pyfreenect2.cpp", 8 | "src/Frame.cpp", 9 | "src/FrameMap.cpp", 10 | "src/Freenect2.cpp", 11 | "src/Freenect2Device.cpp", 12 | "src/Registration.cpp", 13 | "src/SyncMultiFrameListener.cpp", 14 | "src/SmartFrame.cpp"], 15 | extra_compile_args = ["-fpermissive"], 16 | include_dirs=[numpy.get_include()], 17 | define_macros=[("NPY_NO_DEPRECATED_API", "NPY_1_7_API_VERSION")]) 18 | 19 | setup(name="pyfreenect2", 20 | ext_modules=[libfreenect2_module], 21 | py_modules=["pyfreenect2"], 22 | install_requires=["numpy"]) 23 | -------------------------------------------------------------------------------- /src/Frame.cpp: -------------------------------------------------------------------------------- 1 | #include "../pyfreenect2.hpp" 2 | #include 3 | #include "SmartFrame.h" 4 | 5 | using libfreenect2::Frame; 6 | 7 | void py_Frame_destroy(PyObject *frameCapsule) { 8 | delete ((SPFrame*) PyCapsule_GetPointer(frameCapsule, "Frame")); 9 | } 10 | 11 | PyObject *py_Frame_getHeight(PyObject *self, PyObject *args) { 12 | PyObject *frameCapsule = NULL; 13 | if(!PyArg_ParseTuple(args, "O", &frameCapsule)) 14 | return NULL; 15 | SPFrame *spFrame = (SPFrame*) PyCapsule_GetPointer(frameCapsule, "Frame"); 16 | Frame *frame = spFrame->acquire(); 17 | int height = frame->height; 18 | spFrame->release(); 19 | return PyInt_FromSize_t(height); 20 | } 21 | 22 | PyObject *py_Frame_getWidth(PyObject *self, PyObject *args) { 23 | PyObject *frameCapsule = NULL; 24 | if(!PyArg_ParseTuple(args, "O", &frameCapsule)) 25 | return NULL; 26 | SPFrame *spFrame = (SPFrame*) PyCapsule_GetPointer(frameCapsule, "Frame"); 27 | Frame *frame = spFrame->acquire(); 28 | int width = frame->width; 29 | spFrame->release(); 30 | return PyInt_FromSize_t(width); 31 | } 32 | 33 | PyObject *py_Frame_getData(PyObject *self, PyObject *args) { 34 | PyObject *frameCapsule = NULL; 35 | if(!PyArg_ParseTuple(args, "O", &frameCapsule)) 36 | return NULL; 37 | SPFrame *spFrame = (SPFrame*) PyCapsule_GetPointer(frameCapsule, "Frame"); 38 | Frame *frame = spFrame->acquire(); 39 | 40 | // frames are apparently 4 channel (4 bytes per pixel) 41 | npy_intp dims[] = {frame->height, frame->width, 4 }; 42 | 43 | // this should be elsewhere, however, fails without it. 44 | import_array(); 45 | 46 | PyArrayObject *array = (PyArrayObject*) PyArray_SimpleNewFromData(3, 47 | dims, 48 | NPY_UINT8, 49 | frame->data); 50 | spFrame->release(); 51 | return (PyObject*) array; 52 | } 53 | 54 | PyObject *py_Frame_getDepthData(PyObject *self, PyObject *args){ 55 | 56 | PyObject *frameCapsule = NULL; 57 | if(!PyArg_ParseTuple(args, "O", &frameCapsule)) 58 | return NULL; 59 | SPFrame *spFrame = (SPFrame*) PyCapsule_GetPointer(frameCapsule, "Frame"); 60 | Frame *frame = spFrame->acquire(); 61 | 62 | npy_intp dims[] = {frame->height, frame->width, 4}; 63 | 64 | import_array(); 65 | 66 | PyArrayObject *array = (PyArrayObject*) PyArray_SimpleNewFromData(3, 67 | dims, 68 | NPY_UINT8, 69 | frame->data); 70 | spFrame->release(); 71 | return (PyObject*) array; 72 | } 73 | -------------------------------------------------------------------------------- /src/FrameMap.cpp: -------------------------------------------------------------------------------- 1 | #include "../pyfreenect2.hpp" 2 | #include 3 | #include "SmartFrame.h" 4 | 5 | using libfreenect2::Frame; 6 | using libfreenect2::FrameMap; 7 | 8 | void py_FrameMap_destroy(PyObject *frameMapCapsule) { 9 | delete ((SPFrameMap*) PyCapsule_GetPointer(frameMapCapsule, "FrameMap")); 10 | } 11 | 12 | PyObject *py_FrameMap_getFrame(PyObject *self, PyObject *args) { 13 | Frame::Type type = (Frame::Type) 0; 14 | PyObject *frameMapCapsule = NULL; 15 | if(!PyArg_ParseTuple(args, "OI", &frameMapCapsule, &type)) 16 | return NULL; 17 | SPFrameMap *frameMap = (SPFrameMap*) PyCapsule_GetPointer(frameMapCapsule, "FrameMap"); 18 | SPFrameMap::iterator it = frameMap->find(type); 19 | return PyCapsule_New(new SPFrame(it->second), "Frame", py_Frame_destroy); 20 | } 21 | -------------------------------------------------------------------------------- /src/Freenect2.cpp: -------------------------------------------------------------------------------- 1 | #include "../pyfreenect2.hpp" 2 | 3 | using libfreenect2::Freenect2; 4 | 5 | Freenect2 freenect2; 6 | Freenect2& getGlobalFreenect2() { return freenect2; } 7 | 8 | PyObject *py_numberOfDevices(PyObject *self, PyObject *args) { 9 | if(!PyArg_ParseTuple(args, "")) 10 | return NULL; 11 | return PyInt_FromLong(freenect2.enumerateDevices()); 12 | } 13 | 14 | PyObject *py_getDefaultDeviceSerialNumber(PyObject *self, PyObject *args) { 15 | if(!PyArg_ParseTuple(args, "")) 16 | return NULL; 17 | std::string serialNumber = freenect2.getDefaultDeviceSerialNumber(); 18 | return PyString_FromString(serialNumber.c_str()); 19 | } 20 | -------------------------------------------------------------------------------- /src/Freenect2Device.cpp: -------------------------------------------------------------------------------- 1 | #include "../pyfreenect2.hpp" 2 | #include 3 | 4 | using libfreenect2::Freenect2Device; 5 | using libfreenect2::FrameListener; 6 | 7 | PyObject *py_Freenect2Device_new(PyObject *self, PyObject *args) { 8 | char *serialNumber = NULL; 9 | if(!PyArg_ParseTuple(args, "s", &serialNumber)) 10 | return NULL; 11 | 12 | // TODO Pipeline support 13 | Freenect2Device *device = getGlobalFreenect2().openDevice(serialNumber); 14 | return PyCapsule_New(device, "Freenect2Device", py_Freenect2Device_destroy); 15 | } 16 | 17 | void py_Freenect2Device_destroy(PyObject *deviceCapsule) { 18 | ((Freenect2Device*) PyCapsule_GetPointer(deviceCapsule, "Freenect2Device"))->close(); 19 | } 20 | 21 | PyObject *py_Freenect2Device_start(PyObject *self, PyObject *args) { 22 | PyObject *deviceCapsule = NULL; 23 | if(!PyArg_ParseTuple(args, "O", &deviceCapsule)) 24 | return NULL; 25 | bool success = ((Freenect2Device*) PyCapsule_GetPointer(deviceCapsule, "Freenect2Device"))->start(); 26 | if (success){ 27 | Py_RETURN_TRUE; 28 | } 29 | Py_RETURN_FALSE; 30 | } 31 | 32 | PyObject *py_Freenect2Device_stop(PyObject *self, PyObject *args) { 33 | PyObject *deviceCapsule = NULL; 34 | if(!PyArg_ParseTuple(args, "O", &deviceCapsule)) 35 | return NULL; 36 | ((Freenect2Device*) PyCapsule_GetPointer(deviceCapsule, "Freenect2Device"))->stop(); 37 | Py_INCREF(Py_None); 38 | return Py_None; 39 | } 40 | 41 | PyObject *py_Freenect2Device_close(PyObject *self, PyObject *args) { 42 | PyObject *deviceCapsule = NULL; 43 | if(!PyArg_ParseTuple(args, "O", &deviceCapsule)) 44 | return NULL; 45 | ((Freenect2Device*) PyCapsule_GetPointer(deviceCapsule, "Freenect2Device"))->close(); 46 | Py_INCREF(Py_None); 47 | return Py_None; 48 | } 49 | 50 | PyObject *py_Freenect2Device_setColorFrameListener(PyObject *self, PyObject *args) { 51 | PyObject *deviceCapsule = NULL; 52 | PyObject *listenerCapsule = NULL; 53 | if(!PyArg_ParseTuple(args, "OO", &deviceCapsule, &listenerCapsule)) 54 | return NULL; 55 | Freenect2Device *device = (Freenect2Device*) PyCapsule_GetPointer(deviceCapsule, "Freenect2Device"); 56 | 57 | std::cout << "device in F2D.cpp: " << device << std::endl; 58 | std::cout << "listenercapsule in F2D.cpp: " << listenerCapsule << std::endl; 59 | Py_INCREF(listenerCapsule); 60 | FrameListener *listener = (FrameListener*) PyCapsule_GetPointer(listenerCapsule, "SyncMultiFrameListener"); 61 | 62 | ///// BOOO!!! 63 | std::cout << "listener in F2D.cpp: " << listener << std::endl; 64 | device->setColorFrameListener(listener); 65 | Py_INCREF(Py_None); 66 | return Py_None; 67 | } 68 | 69 | PyObject *py_Freenect2Device_setDeepConfiguration(PyObject *self, PyObject *args){ 70 | PyObject *deviceCapsule = NULL; 71 | struct libfreenect2::Freenect2Device::Config *conf = NULL; 72 | size_t size; 73 | if(!PyArg_ParseTuple(args, "Ow#", &deviceCapsule, &conf,&size)) 74 | return NULL; 75 | if (size < sizeof(struct libfreenect2::Freenect2Device::Config)) { 76 | PyErr_SetString(PyExc_TypeError, "wrong buffer size"); 77 | return NULL; 78 | } 79 | Freenect2Device *device = (Freenect2Device*) PyCapsule_GetPointer(deviceCapsule, "Freenect2Device"); 80 | 81 | Py_INCREF(conf); 82 | device->setConfiguration(*conf); 83 | Py_DECREF(conf); 84 | Py_INCREF(Py_None); 85 | return Py_None; 86 | } 87 | 88 | PyObject *py_Freenect2Device_setIrAndDepthFrameListener(PyObject *self, PyObject *args) { 89 | PyObject *deviceCapsule = NULL; 90 | PyObject *listenerCapsule = NULL; 91 | if(!PyArg_ParseTuple(args, "OO", &deviceCapsule, &listenerCapsule)) 92 | return NULL; 93 | Freenect2Device *device = (Freenect2Device*) PyCapsule_GetPointer(deviceCapsule, "Freenect2Device"); 94 | Py_INCREF(listenerCapsule); 95 | FrameListener *listener = (FrameListener*) PyCapsule_GetPointer(listenerCapsule, "SyncMultiFrameListener"); 96 | device->setIrAndDepthFrameListener(listener); 97 | Py_INCREF(Py_None); 98 | return Py_None; 99 | } 100 | 101 | PyObject *py_Freenect2Device_getSerialNumber(PyObject *self, PyObject *args) { 102 | PyObject *deviceCapsule = NULL; 103 | if(!PyArg_ParseTuple(args, "O", &deviceCapsule)) 104 | return NULL; 105 | Freenect2Device *device = (Freenect2Device*) PyCapsule_GetPointer(deviceCapsule, "Freenect2Device"); 106 | std::string serialNumber = device->getSerialNumber(); 107 | return PyString_FromString(serialNumber.c_str()); 108 | } 109 | PyObject *py_Freenect2Device_getFirmwareVersion(PyObject *self, PyObject *args) { 110 | PyObject *deviceCapsule = NULL; 111 | if(!PyArg_ParseTuple(args, "O", &deviceCapsule)) 112 | return NULL; 113 | Freenect2Device *device = (Freenect2Device*) PyCapsule_GetPointer(deviceCapsule, "Freenect2Device"); 114 | std::string firmwareVersion = device->getFirmwareVersion(); 115 | return PyString_FromString(firmwareVersion.c_str()); 116 | } 117 | 118 | PyObject *py_Freenect2Device_getColorCameraParams(PyObject *self, PyObject *args) { 119 | PyObject *deviceCapsule = NULL; 120 | if(!PyArg_ParseTuple(args, "O", &deviceCapsule)) 121 | return NULL; 122 | Freenect2Device *device = (Freenect2Device*) PyCapsule_GetPointer(deviceCapsule, "Freenect2Device"); 123 | Freenect2Device::ColorCameraParams *colorCameraParams = new Freenect2Device::ColorCameraParams; 124 | return PyCapsule_New(colorCameraParams, "ColorCameraParams", py_Freenect2Device_ColorCameraParams_destroy); 125 | } 126 | PyObject *py_Freenect2Device_getIRCameraParams(PyObject *self, PyObject *args) { 127 | PyObject *deviceCapsule = NULL; 128 | if(!PyArg_ParseTuple(args, "O", &deviceCapsule)) 129 | return NULL; 130 | Freenect2Device *device = (Freenect2Device*) PyCapsule_GetPointer(deviceCapsule, "Freenect2Device"); 131 | Freenect2Device::IrCameraParams *irCameraParams = new Freenect2Device::IrCameraParams; 132 | return PyCapsule_New(irCameraParams, "IRCameraParams", py_Freenect2Device_IRCameraParams_destroy); 133 | } 134 | 135 | void py_Freenect2Device_ColorCameraParams_destroy(PyObject *colorCameraParamsCapsule) { 136 | delete ((Freenect2Device::ColorCameraParams*) PyCapsule_GetPointer(colorCameraParamsCapsule, "ColorCameraParams")); 137 | } 138 | void py_Freenect2Device_IRCameraParams_destroy(PyObject *irCameraParamsCapsule) { 139 | delete ((Freenect2Device::IrCameraParams*) PyCapsule_GetPointer(irCameraParamsCapsule, "IRCameraParams")); 140 | } 141 | -------------------------------------------------------------------------------- /src/Registration.cpp: -------------------------------------------------------------------------------- 1 | #include "../pyfreenect2.hpp" 2 | 3 | using libfreenect2::Freenect2Device; 4 | using libfreenect2::Registration; 5 | 6 | PyObject *py_Registration_new(PyObject *self, PyObject *args) { 7 | PyObject *irCameraParamsCapsule = NULL; 8 | PyObject *colorCameraParamsCapsule = NULL; 9 | if(!PyArg_ParseTuple(args, "OO", &irCameraParamsCapsule, &colorCameraParamsCapsule)) 10 | return NULL; 11 | Freenect2Device::IrCameraParams *irCameraParams = (Freenect2Device::IrCameraParams*) PyCapsule_GetPointer(irCameraParamsCapsule, "IRCameraParams"); 12 | Freenect2Device::ColorCameraParams *colorCameraParams = (Freenect2Device::ColorCameraParams*) PyCapsule_GetPointer(colorCameraParamsCapsule, "ColorCameraParams"); 13 | Registration *registration = new Registration(*irCameraParams, *colorCameraParams); 14 | return PyCapsule_New(registration, "Registration", py_Registration_destroy); 15 | } 16 | void py_Registration_destroy(PyObject *registrationCapsule) { 17 | delete (Registration*) PyCapsule_GetPointer(registrationCapsule, "Registration"); 18 | } 19 | 20 | PyObject *py_Registration_apply(PyObject *self, PyObject *args) { 21 | PyObject *registrationCapsule = NULL; 22 | if(!PyArg_ParseTuple(args, "O", ®istrationCapsule)) 23 | return NULL; 24 | // TODO 25 | Py_INCREF(Py_NotImplemented); 26 | return Py_NotImplemented; 27 | } 28 | -------------------------------------------------------------------------------- /src/SmartFrame.cpp: -------------------------------------------------------------------------------- 1 | #include "SmartFrame.h" 2 | 3 | SPFrameMap* getSPFrameMapFromFrameMap(FrameMap* frames){ 4 | SPFrameMap * spFrames = new SPFrameMap; 5 | for(FrameMap::iterator it = frames->begin() ; it!= frames->end() ; ++it){ 6 | spFrames->insert(std::make_pair(it->first,SPFrame(it->second))); 7 | } 8 | return spFrames; 9 | } 10 | -------------------------------------------------------------------------------- /src/SmartFrame.h: -------------------------------------------------------------------------------- 1 | #ifndef _SMARTFRAM_H_ 2 | #define _SMARTFRAM_H_ 3 | 4 | #include "../pyfreenect2.hpp" 5 | #include "SmartPtr.hpp" 6 | 7 | using libfreenect2::Frame; 8 | using libfreenect2::FrameMap; 9 | 10 | typedef SmartPtr SPFrame; 11 | typedef std::map SPFrameMap; 12 | 13 | SPFrameMap* getSPFrameMapFromFrameMap(FrameMap* frames); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /src/SmartPtr.hpp: -------------------------------------------------------------------------------- 1 | /*********************************************************************************************** 2 | *C++11 or boost shared_ptr is a better choice 3 | **************************************************************************************************/ 4 | #ifndef _SMARTPTR_HPP_ 5 | #define _SMARTPTR_HPP_ 6 | 7 | #include 8 | 9 | template 10 | class SmartPtr{ 11 | public: 12 | SmartPtr(T *p); 13 | ~SmartPtr(); 14 | T* acquire(); 15 | void release(); 16 | SmartPtr(const SmartPtr &orig); 17 | SmartPtr& operator=(const SmartPtr &rhs); 18 | private: 19 | void decAndFree(void); 20 | private: 21 | pthread_spinlock_t* spin; 22 | T *ptr; 23 | volatile int* use_count; 24 | }; 25 | 26 | template 27 | SmartPtr::SmartPtr(T *p) : ptr(p){ 28 | use_count = new int(1); 29 | spin = new pthread_spinlock_t(); 30 | pthread_spin_init(spin, PTHREAD_PROCESS_PRIVATE); 31 | } 32 | 33 | template 34 | SmartPtr::~SmartPtr(){ 35 | decAndFree(); 36 | } 37 | 38 | template 39 | void SmartPtr::decAndFree(void){ 40 | T * freePtr = NULL; 41 | bool destroy = false; 42 | pthread_spin_lock(spin); 43 | (*use_count) --; 44 | if (0 == (*use_count)){ 45 | freePtr = ptr; 46 | ptr = NULL; 47 | destroy = true; 48 | } 49 | pthread_spin_unlock(spin); 50 | if (NULL != freePtr){ 51 | delete freePtr; 52 | } 53 | if (destroy){ 54 | delete use_count; 55 | pthread_spin_destroy(spin); 56 | delete spin; 57 | } 58 | } 59 | 60 | template 61 | T* SmartPtr::acquire(){ 62 | pthread_spin_lock(spin); 63 | if((*use_count) > 0){ 64 | (*use_count)++; 65 | } 66 | pthread_spin_unlock(spin); 67 | return ptr; 68 | } 69 | 70 | template 71 | void SmartPtr::release(){ 72 | decAndFree(); 73 | } 74 | 75 | template 76 | SmartPtr::SmartPtr(const SmartPtr &orig){ 77 | pthread_spin_lock(orig.spin); 78 | spin = orig.spin; 79 | ptr = orig.ptr; 80 | use_count = orig.use_count; 81 | (*use_count)++; 82 | pthread_spin_unlock(orig.spin); 83 | } 84 | 85 | template 86 | SmartPtr& SmartPtr::operator=(const SmartPtr &rhs){ 87 | SmartPtr tmpPtr(*this); 88 | 89 | pthread_spin_lock(rhs.spin); 90 | (*rhs.use_count) ++; 91 | ptr = rhs.ptr; 92 | use_count = rhs.use_count; 93 | spin = rhs.spin; 94 | pthread_spin_unlock(rhs.spin); 95 | 96 | tmpPtr.decAndFree(); 97 | return *this; 98 | } 99 | 100 | #endif 101 | -------------------------------------------------------------------------------- /src/SyncMultiFrameListener.cpp: -------------------------------------------------------------------------------- 1 | #include "../pyfreenect2.hpp" 2 | #include 3 | #include "SmartFrame.h" 4 | 5 | using libfreenect2::FrameMap; 6 | using libfreenect2::SyncMultiFrameListener; 7 | 8 | void py_SyncMultiFrameListener_destroy(PyObject *listenerCapsule) { 9 | delete ((SyncMultiFrameListener*) PyCapsule_GetPointer(listenerCapsule, 10 | "SyncMultiFrameListener")); 11 | } 12 | 13 | PyObject *py_SyncMultiFrameListener_new(PyObject *self, PyObject *args) { 14 | unsigned int frame_types = 0; 15 | if(!PyArg_ParseTuple(args, "I", &frame_types)) 16 | return NULL; 17 | SyncMultiFrameListener *listener = new SyncMultiFrameListener(frame_types); 18 | std::cout << "listener in ext: " << listener << std::endl; 19 | return PyCapsule_New(listener, 20 | "SyncMultiFrameListener", 21 | py_SyncMultiFrameListener_destroy); 22 | } 23 | 24 | PyObject *py_SyncMultiFrameListener_waitForNewFrame(PyObject *self, PyObject *args) { 25 | PyObject *listenerCapsule = NULL; 26 | if(!PyArg_ParseTuple(args, "O", &listenerCapsule)) 27 | return NULL; 28 | SyncMultiFrameListener *listener = (SyncMultiFrameListener*) PyCapsule_GetPointer(listenerCapsule, "SyncMultiFrameListener"); 29 | FrameMap* frames = new FrameMap(); 30 | listener->waitForNewFrame(*frames); 31 | SPFrameMap * spFrames = getSPFrameMapFromFrameMap(frames); 32 | delete frames; 33 | PyObject * pyObj = PyCapsule_New(spFrames, "FrameMap", py_FrameMap_destroy); 34 | //std::cout << "waitForNewFrame: " << (void*)pyObj << "::" << (void*)listenerCapsule << std::endl; 35 | return pyObj; 36 | } 37 | 38 | /* 39 | void SyncMultiFrameListener::release(FrameMap &frame) 40 | { 41 | for(FrameMap::iterator it = frame.begin(); it != frame.end(); ++it) 42 | { 43 | delete it->second; 44 | it->second = 0; 45 | } 46 | 47 | frame.clear(); 48 | 49 | { 50 | libfreenect2::lock_guard l(impl_->mutex_); 51 | impl_->current_frame_released_ = true; 52 | } 53 | } 54 | */ 55 | /** Shortcut to delete all frames 56 | * There is a lock ,if not call release we will only get one frame 57 | */ 58 | PyObject * py_SyncMultiFrameListener_release(PyObject *self, PyObject *args) { 59 | PyObject *listenerCapsule = NULL; 60 | PyObject *framesCapsule = NULL; 61 | if(PyArg_ParseTuple(args, "OO", &listenerCapsule,&framesCapsule)){ 62 | SyncMultiFrameListener *listener = (SyncMultiFrameListener*) PyCapsule_GetPointer(listenerCapsule, "SyncMultiFrameListener"); 63 | //std::cout << "release: " << (void*)framesCapsule << "::" << (void*)listenerCapsule << std::endl; 64 | SPFrameMap *spFrames = (SPFrameMap *) PyCapsule_GetPointer(framesCapsule,"FrameMap"); 65 | spFrames->clear(); 66 | if((NULL != listener)&&(NULL != spFrames)){ 67 | FrameMap* frames = new FrameMap(); 68 | listener->release(*frames); 69 | delete frames; 70 | } 71 | } 72 | Py_INCREF(Py_None); 73 | return Py_None; 74 | } 75 | -------------------------------------------------------------------------------- /test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import cv2 4 | import scipy.misc 5 | import signal 6 | import pyfreenect2 7 | 8 | # This is pretty much a straight port of the Protonect program bundled with 9 | # libfreenect2. 10 | 11 | # Initialize device 12 | serialNumber = pyfreenect2.getDefaultDeviceSerialNumber() 13 | kinect = pyfreenect2.Freenect2Device(serialNumber) 14 | 15 | # Set up signal handler 16 | shutdown = False 17 | def sigint_handler(signum, frame): 18 | print "Got SIGINT, shutting down..." 19 | global shutdown 20 | shutdown = True 21 | signal.signal(signal.SIGINT, sigint_handler) 22 | 23 | # Set up frame listener 24 | frameListener = pyfreenect2.SyncMultiFrameListener(pyfreenect2.Frame.COLOR, 25 | pyfreenect2.Frame.IR, 26 | pyfreenect2.Frame.DEPTH) 27 | 28 | print frameListener 29 | kinect.setColorFrameListener(frameListener) 30 | kinect.setIrAndDepthFrameListener(frameListener) 31 | kinect.setDeepConfiguration(pyfreenect2.DeepConfig(MinDepth=.5,MaxDepth=10,EnableBilateralFilter=True,EnableEdgeAwareFilter=True)) 32 | 33 | # Start recording 34 | kinect.start() 35 | 36 | # Print useful info 37 | print "Kinect serial: %s" % kinect.serial_number 38 | print "Kinect firmware: %s" % kinect.firmware_version 39 | 40 | # What's a registration? 41 | print kinect.ir_camera_params 42 | 43 | registration = pyfreenect2.Registration(kinect.ir_camera_params, kinect.color_camera_params) 44 | #registration = pyfreenect2.Registration(kinect.color_camera_params, kinect.ir_camera_params) 45 | #registration = pyfreenect2.Registration() 46 | 47 | # Initialize OpenCV stuff 48 | cv2.namedWindow("RGB") 49 | # cv2.namedWindow("IR") 50 | cv2.namedWindow("Depth") 51 | 52 | # Main loop 53 | while not shutdown: 54 | frames = frameListener.waitForNewFrame() 55 | rgbFrame = frames.getFrame(pyfreenect2.Frame.COLOR) 56 | # irFrame = frames.getFrame(pyfreenect2.Frame.IR) 57 | depthFrame = frames.getFrame(pyfreenect2.Frame.DEPTH) 58 | rgb_frame = rgbFrame.getRGBData() 59 | bgr_frame = rgb_frame.copy() 60 | bgr_frame[:,:,0] = rgb_frame[:,:,2] 61 | bgr_frame[:,:,2] = rgb_frame[:,:,0] 62 | 63 | depth_frame = depthFrame.getDepthData() 64 | # depth_frame = frames.getFrame(pyfreenect2.Frame.DEPTH).getData() 65 | 66 | bgr_frame_resize = scipy.misc.imresize(bgr_frame, size = .5) 67 | depth_frame_resize = scipy.misc.imresize(depth_frame, size = .5) 68 | 69 | # TODO Display the frames w/ OpenCV 70 | cv2.imshow("RGB", bgr_frame_resize) 71 | cv2.imshow("Depth", depth_frame_resize) 72 | cv2.waitKey(20) 73 | frameListener.release(frames) 74 | 75 | kinect.stop() 76 | kinect.close() 77 | --------------------------------------------------------------------------------