├── .idea ├── .name ├── encodings.xml ├── vcs.xml ├── modules.xml ├── py3freenect2.iml ├── misc.xml └── workspace.xml ├── .gitignore ├── rebuild.sh ├── examples ├── run.py └── run.py.bak ├── src ├── FrameMap.cpp ├── Freenect2.cpp ├── SyncMultiFrameListener.cpp ├── Registration.cpp ├── Frame.cpp └── Freenect2Device.cpp ├── setup.py ├── README.md ├── test.py ├── pyfreenect2.cpp ├── pyfreenect2.hpp └── pyfreenect2.py /.idea/.name: -------------------------------------------------------------------------------- 1 | py3freenect2 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | dist/ 3 | pyfreenect2.egg-info/ 4 | *.pyc 5 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /examples/run.py.bak: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /.idea/py3freenect2.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | -------------------------------------------------------------------------------- /src/FrameMap.cpp: -------------------------------------------------------------------------------- 1 | #include "../pyfreenect2.hpp" 2 | 3 | using libfreenect2::Frame; 4 | using libfreenect2::FrameMap; 5 | 6 | void py_FrameMap_destroy(PyObject *frameMapCapsule) { 7 | delete ((FrameMap*) PyCapsule_GetPointer(frameMapCapsule, "FrameMap")); 8 | } 9 | 10 | PyObject *py_FrameMap_getFrame(PyObject *self, PyObject *args) { 11 | Frame::Type type = (Frame::Type) 0; 12 | PyObject *frameMapCapsule = NULL; 13 | if(!PyArg_ParseTuple(args, "OI", &frameMapCapsule, &type)) 14 | return NULL; 15 | FrameMap *frameMap = (FrameMap*) PyCapsule_GetPointer(frameMapCapsule, "FrameMap"); 16 | return PyCapsule_New((*frameMap)[type], "Frame", py_Frame_destroy); 17 | } 18 | -------------------------------------------------------------------------------- /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 | extra_compile_args = ["-fpermissive"], 15 | include_dirs=[numpy.get_include()], 16 | define_macros=[("NPY_NO_DEPRECATED_API", "NPY_1_7_API_VERSION")]) 17 | 18 | setup(name="pyfreenect2", 19 | ext_modules=[libfreenect2_module], 20 | py_modules=["pyfreenect2"], 21 | install_requires=["numpy"]) 22 | -------------------------------------------------------------------------------- /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 PyLong_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 | /* python 3 adaptation is PyUnicode instead of PyString*/ 19 | return PyUnicode_FromString(serialNumber.c_str()); 20 | } 21 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | py3freenect2 2 | =========== 3 | 4 | Python bindings for [libfreenect2](https://github.com/OpenKinect/libfreenect2). 5 | 6 | Requirements 7 | --------- 8 | 9 | - Python3 (python2 support : https://github.com/remexre/pyfreenect2; backwards compatibility to come) 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 | -------------------------------------------------------------------------------- /src/SyncMultiFrameListener.cpp: -------------------------------------------------------------------------------- 1 | #include "../pyfreenect2.hpp" 2 | #include 3 | 4 | using libfreenect2::FrameMap; 5 | using libfreenect2::SyncMultiFrameListener; 6 | 7 | void py_SyncMultiFrameListener_destroy(PyObject *listenerCapsule) { 8 | delete ((SyncMultiFrameListener*) PyCapsule_GetPointer(listenerCapsule, 9 | "SyncMultiFrameListener")); 10 | } 11 | 12 | PyObject *py_SyncMultiFrameListener_new(PyObject *self, PyObject *args) { 13 | unsigned int frame_types = 0; 14 | if(!PyArg_ParseTuple(args, "I", &frame_types)) 15 | return NULL; 16 | SyncMultiFrameListener *listener = new SyncMultiFrameListener(frame_types); 17 | std::cout << "listener in ext: " << listener << std::endl; 18 | return PyCapsule_New(listener, 19 | "SyncMultiFrameListener", 20 | py_SyncMultiFrameListener_destroy); 21 | } 22 | 23 | PyObject *py_SyncMultiFrameListener_waitForNewFrame(PyObject *self, PyObject *args) { 24 | PyObject *listenerCapsule = NULL; 25 | if(!PyArg_ParseTuple(args, "O", &listenerCapsule)) 26 | return NULL; 27 | SyncMultiFrameListener *listener = (SyncMultiFrameListener*) PyCapsule_GetPointer(listenerCapsule, "SyncMultiFrameListener"); 28 | FrameMap *frames = new FrameMap; 29 | listener->waitForNewFrame(*frames); 30 | return PyCapsule_New(frames, "FrameMap", py_FrameMap_destroy); 31 | } 32 | -------------------------------------------------------------------------------- /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/Frame.cpp: -------------------------------------------------------------------------------- 1 | #include "../pyfreenect2.hpp" 2 | #include 3 | 4 | using libfreenect2::Frame; 5 | 6 | void py_Frame_destroy(PyObject *frameCapsule) { 7 | delete ((Frame*) PyCapsule_GetPointer(frameCapsule, "Frame")); 8 | } 9 | 10 | PyObject *py_Frame_getHeight(PyObject *self, PyObject *args) { 11 | PyObject *frameCapsule = NULL; 12 | if(!PyArg_ParseTuple(args, "O", &frameCapsule)) 13 | return NULL; 14 | Frame *frame = (Frame*) PyCapsule_GetPointer(frameCapsule, "Frame"); 15 | return PyLong_FromSize_t(frame->height); 16 | } 17 | 18 | PyObject *py_Frame_getWidth(PyObject *self, PyObject *args) { 19 | PyObject *frameCapsule = NULL; 20 | if(!PyArg_ParseTuple(args, "O", &frameCapsule)) 21 | return NULL; 22 | Frame *frame = (Frame*) PyCapsule_GetPointer(frameCapsule, "Frame"); 23 | return PyLong_FromSize_t(frame->width); 24 | } 25 | 26 | PyObject *py_Frame_getData(PyObject *self, PyObject *args) { 27 | 28 | 29 | PyObject *frameCapsule = NULL; 30 | if(!PyArg_ParseTuple(args, "O", &frameCapsule)) 31 | return NULL; 32 | Frame *frame = (Frame*) PyCapsule_GetPointer(frameCapsule, "Frame"); 33 | 34 | // frames are apparently 4 channel (4 bytes per pixel) 35 | npy_intp dims[] = {frame->height, frame->width, 4 }; 36 | 37 | // this should be elsewhere, however, fails without it. 38 | import_array(); 39 | 40 | PyArrayObject *array = (PyArrayObject*) PyArray_SimpleNewFromData(3, 41 | dims, 42 | NPY_UINT8, 43 | frame->data); 44 | 45 | return (PyObject*) array; 46 | } 47 | 48 | PyObject *py_Frame_getDepthData(PyObject *self, PyObject *args) 49 | { 50 | 51 | PyObject *frameCapsule = NULL; 52 | if(!PyArg_ParseTuple(args, "O", &frameCapsule)) 53 | return NULL; 54 | Frame *frame = (Frame*) PyCapsule_GetPointer(frameCapsule, "Frame"); 55 | 56 | npy_intp dims[] = {frame->height, frame->width, 4}; 57 | 58 | import_array(); 59 | 60 | PyArrayObject *array = (PyArrayObject*) PyArray_SimpleNewFromData(3, 61 | dims, 62 | NPY_UINT8, 63 | frame->data); 64 | return (PyObject*) array; 65 | } 66 | -------------------------------------------------------------------------------- /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 | shutdown = True 20 | signal.signal(signal.SIGINT, sigint_handler) 21 | 22 | # Set up frame listener 23 | frameListener = pyfreenect2.SyncMultiFrameListener(pyfreenect2.Frame.COLOR, 24 | pyfreenect2.Frame.IR, 25 | pyfreenect2.Frame.DEPTH) 26 | 27 | print(frameListener) 28 | kinect.setColorFrameListener(frameListener) 29 | kinect.setIrAndDepthFrameListener(frameListener) 30 | 31 | # Start recording 32 | kinect.start() 33 | 34 | # Print useful info 35 | print("Kinect serial: %s" % kinect.serial_number) 36 | print("Kinect firmware: %s" % kinect.firmware_version) 37 | 38 | # What's a registration? 39 | print(kinect.ir_camera_params) 40 | 41 | registration = pyfreenect2.Registration(kinect.ir_camera_params, kinect.color_camera_params) 42 | #registration = pyfreenect2.Registration(kinect.color_camera_params, kinect.ir_camera_params) 43 | #registration = pyfreenect2.Registration() 44 | 45 | # Initialize OpenCV stuff 46 | cv2.namedWindow("RGB") 47 | # cv2.namedWindow("IR") 48 | cv2.namedWindow("Depth") 49 | 50 | # Main loop 51 | while not shutdown: 52 | frames = frameListener.waitForNewFrame() 53 | rgbFrame = frames.getFrame(pyfreenect2.Frame.COLOR) 54 | # irFrame = frames.getFrame(pyfreenect2.Frame.IR) 55 | depthFrame = frames.getFrame(pyfreenect2.Frame.DEPTH) 56 | 57 | rgb_frame = rgbFrame.getRGBData() 58 | bgr_frame = rgb_frame.copy() 59 | bgr_frame[:,:,0] = rgb_frame[:,:,2] 60 | bgr_frame[:,:,2] = rgb_frame[:,:,0] 61 | 62 | depth_frame = depthFrame.getDepthData() 63 | # depth_frame = frames.getFrame(pyfreenect2.Frame.DEPTH).getData() 64 | 65 | bgr_frame_resize = scipy.misc.imresize(bgr_frame, size = .5) 66 | depth_frame_resize = scipy.misc.imresize(depth_frame, size = .5) 67 | 68 | # TODO Display the frames w/ OpenCV 69 | cv2.imshow("RGB", bgr_frame_resize) 70 | cv2.imshow("Depth", depth_frame_resize) 71 | cv2.waitKey(20) 72 | 73 | kinect.stop() 74 | kinect.close() 75 | -------------------------------------------------------------------------------- /pyfreenect2.cpp: -------------------------------------------------------------------------------- 1 | #include "Python.h" 2 | #include "pyfreenect2.hpp" 3 | #include 4 | 5 | struct module_state { 6 | PyObject *error; 7 | }; 8 | 9 | #if PY_MAJOR_VERSION >= 3 10 | #define GETSTATE(m) ((struct module_state*)PyModule_GetState(m)) 11 | #else 12 | #define GETSTATE(m) (&_state) 13 | static struct module_state _state; 14 | #endif 15 | 16 | static PyObject * 17 | error_out(PyObject *m) { 18 | struct module_state *st = GETSTATE(m); 19 | PyErr_SetString(st->error, "something bad happened"); 20 | return NULL; 21 | } 22 | 23 | static int pyfreenect2_traverse(PyObject *m, visitproc visit, void *arg) { 24 | Py_VISIT(GETSTATE(m)->error); 25 | return 0; 26 | } 27 | 28 | static int pyfreenect2_clear(PyObject *m) { 29 | Py_CLEAR(GETSTATE(m)->error); 30 | return 0; 31 | } 32 | 33 | static PyMethodDef pyfreenect2_methods[] = { 34 | // Freenect2 35 | { "numberOfDevices", py_numberOfDevices, METH_VARARGS, NULL }, 36 | { "getDefaultDeviceSerialNumber", py_getDefaultDeviceSerialNumber, METH_VARARGS, NULL }, 37 | // Freenect2Device 38 | { "Freenect2Device_new", py_Freenect2Device_new, METH_VARARGS, NULL }, 39 | { "Freenect2Device_start", py_Freenect2Device_start, METH_VARARGS, NULL }, 40 | { "Freenect2Device_stop", py_Freenect2Device_stop, METH_VARARGS, NULL }, 41 | { "Freenect2Device_setColorFrameListener", py_Freenect2Device_setColorFrameListener, METH_VARARGS, NULL }, 42 | { "Freenect2Device_setIrAndDepthFrameListener", py_Freenect2Device_setIrAndDepthFrameListener, METH_VARARGS, NULL }, 43 | { "Freenect2Device_getSerialNumber", py_Freenect2Device_getSerialNumber, METH_VARARGS, NULL }, 44 | { "Freenect2Device_getFirmwareVersion", py_Freenect2Device_getFirmwareVersion, METH_VARARGS, NULL }, 45 | { "Freenect2Device_getColorCameraParams", py_Freenect2Device_getColorCameraParams, METH_VARARGS, NULL }, 46 | { "Freenect2Device_getIRCameraParams", py_Freenect2Device_getIRCameraParams, METH_VARARGS, NULL }, 47 | // SyncMultiFrameListener 48 | { "SyncMultiFrameListener_new", py_SyncMultiFrameListener_new, METH_VARARGS, NULL }, 49 | { "SyncMultiFrameListener_waitForNewFrame", py_SyncMultiFrameListener_waitForNewFrame, METH_VARARGS, NULL }, 50 | // Registration 51 | { "Registration_new", py_Registration_new, METH_VARARGS, NULL }, 52 | { "Registration_apply", py_Registration_apply, METH_VARARGS, NULL }, 53 | // FrameMap 54 | { "FrameMap_getFrame", py_FrameMap_getFrame, METH_VARARGS, NULL }, 55 | // Frame 56 | { "Frame_getHeight", py_Frame_getHeight, METH_VARARGS, NULL }, 57 | { "Frame_getWidth", py_Frame_getWidth, METH_VARARGS, NULL }, 58 | { "Frame_getData", py_Frame_getData, METH_VARARGS, NULL }, 59 | { "Frame_getDepthData", py_Frame_getDepthData, METH_VARARGS, NULL }, 60 | // Sentinel 61 | { NULL, NULL, 0, NULL} 62 | }; 63 | 64 | static struct PyModuleDef pyfreenect2_module = { 65 | PyModuleDef_HEAD_INIT, 66 | "_pyfreenect2", 67 | NULL, 68 | sizeof(struct module_state), 69 | pyfreenect2_methods, 70 | NULL, 71 | pyfreenect2_traverse, 72 | pyfreenect2_clear, 73 | NULL 74 | }; 75 | 76 | PyMODINIT_FUNC 77 | PyInit__pyfreenect2() { 78 | 79 | /// enables debug of libfreenect2 80 | /// libfreenect2::setGlobalLogger(libfreenect2::createConsoleLogger(libfreenect2::Logger::Debug)); 81 | 82 | import_array(); 83 | return PyModule_Create(&pyfreenect2_module); 84 | import_array(); 85 | } 86 | -------------------------------------------------------------------------------- /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 | 30 | PyObject *py_Freenect2Device_setColorFrameListener(PyObject *self, PyObject *args); 31 | PyObject *py_Freenect2Device_setIrAndDepthFrameListener(PyObject *self, PyObject *args); 32 | 33 | PyObject *py_Freenect2Device_getSerialNumber(PyObject *self, PyObject *args); 34 | PyObject *py_Freenect2Device_getFirmwareVersion(PyObject *self, PyObject *args); 35 | PyObject *py_Freenect2Device_getColorCameraParams(PyObject *self, PyObject *args); 36 | PyObject *py_Freenect2Device_getIRCameraParams(PyObject *self, PyObject *args); 37 | 38 | void py_Freenect2Device_ColorCameraParams_destroy(PyObject *colorCameraParamsCapsule); 39 | void py_Freenect2Device_IRCameraParams_destroy(PyObject *irCameraParamsCapsule); 40 | 41 | //////////////////////////////////////////////////////////////////////////////// 42 | // SyncMultiFrameListener // 43 | //////////////////////////////////////////////////////////////////////////////// 44 | 45 | PyObject *py_SyncMultiFrameListener_new(PyObject *self, PyObject *args); 46 | void py_SyncMultiFrameListener_destroy(PyObject *object); 47 | 48 | PyObject *py_SyncMultiFrameListener_waitForNewFrame(PyObject *self, PyObject *args); 49 | 50 | //////////////////////////////////////////////////////////////////////////////// 51 | // FrameMap // 52 | //////////////////////////////////////////////////////////////////////////////// 53 | 54 | void py_FrameMap_destroy(PyObject *object); 55 | 56 | PyObject *py_FrameMap_getFrame(PyObject *self, PyObject *args); 57 | 58 | //////////////////////////////////////////////////////////////////////////////// 59 | // Frame // 60 | //////////////////////////////////////////////////////////////////////////////// 61 | 62 | void py_Frame_destroy(PyObject *object); 63 | 64 | PyObject *py_Frame_getHeight(PyObject *self, PyObject *args); 65 | PyObject *py_Frame_getWidth(PyObject *self, PyObject *args); 66 | PyObject *py_Frame_getData(PyObject *self, PyObject *args); 67 | PyObject *py_Frame_getDepthData(PyObject *self, PyObject *args); 68 | 69 | //////////////////////////////////////////////////////////////////////////////// 70 | // Registration // 71 | //////////////////////////////////////////////////////////////////////////////// 72 | 73 | PyObject *py_Registration_new(PyObject *self, PyObject *args); 74 | void py_Registration_destroy(PyObject *object); 75 | 76 | PyObject *py_Registration_apply(PyObject *self, PyObject *args); 77 | -------------------------------------------------------------------------------- /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 | void py_Freenect2Device_destroy(PyObject *deviceCapsule) { 17 | ((Freenect2Device*) PyCapsule_GetPointer(deviceCapsule, "Freenect2Device"))->close(); 18 | } 19 | 20 | PyObject *py_Freenect2Device_start(PyObject *self, PyObject *args) { 21 | PyObject *deviceCapsule = NULL; 22 | if(!PyArg_ParseTuple(args, "O", &deviceCapsule)) 23 | return NULL; 24 | ((Freenect2Device*) PyCapsule_GetPointer(deviceCapsule, "Freenect2Device"))->start(); 25 | Py_INCREF(Py_None); 26 | return Py_None; 27 | } 28 | PyObject *py_Freenect2Device_stop(PyObject *self, PyObject *args) { 29 | PyObject *deviceCapsule = NULL; 30 | if(!PyArg_ParseTuple(args, "O", &deviceCapsule)) 31 | return NULL; 32 | ((Freenect2Device*) PyCapsule_GetPointer(deviceCapsule, "Freenect2Device"))->stop(); 33 | Py_INCREF(Py_None); 34 | return Py_None; 35 | } 36 | 37 | PyObject *py_Freenect2Device_setColorFrameListener(PyObject *self, PyObject *args) { 38 | PyObject *deviceCapsule = NULL; 39 | PyObject *listenerCapsule = NULL; 40 | if(!PyArg_ParseTuple(args, "OO", &deviceCapsule, &listenerCapsule)) 41 | return NULL; 42 | Freenect2Device *device = (Freenect2Device*) PyCapsule_GetPointer(deviceCapsule, "Freenect2Device"); 43 | 44 | std::cout << "device in F2D.cpp: " << device << std::endl; 45 | std::cout << "listenercapsule in F2D.cpp: " << listenerCapsule << std::endl; 46 | Py_INCREF(listenerCapsule); 47 | FrameListener *listener = (FrameListener*) PyCapsule_GetPointer(listenerCapsule, "SyncMultiFrameListener"); 48 | 49 | ///// BOOO!!! 50 | std::cout << "listener in F2D.cpp: " << listener << std::endl; 51 | device->setColorFrameListener(listener); 52 | Py_INCREF(Py_None); 53 | return Py_None; 54 | } 55 | PyObject *py_Freenect2Device_setIrAndDepthFrameListener(PyObject *self, PyObject *args) { 56 | PyObject *deviceCapsule = NULL; 57 | PyObject *listenerCapsule = NULL; 58 | if(!PyArg_ParseTuple(args, "OO", &deviceCapsule, &listenerCapsule)) 59 | return NULL; 60 | Freenect2Device *device = (Freenect2Device*) PyCapsule_GetPointer(deviceCapsule, "Freenect2Device"); 61 | Py_INCREF(listenerCapsule); 62 | FrameListener *listener = (FrameListener*) PyCapsule_GetPointer(listenerCapsule, "SyncMultiFrameListener"); 63 | device->setIrAndDepthFrameListener(listener); 64 | Py_INCREF(Py_None); 65 | return Py_None; 66 | } 67 | 68 | PyObject *py_Freenect2Device_getSerialNumber(PyObject *self, PyObject *args) { 69 | PyObject *deviceCapsule = NULL; 70 | if(!PyArg_ParseTuple(args, "O", &deviceCapsule)) 71 | return NULL; 72 | Freenect2Device *device = (Freenect2Device*) PyCapsule_GetPointer(deviceCapsule, "Freenect2Device"); 73 | std::string serialNumber = device->getSerialNumber(); 74 | return PyUnicode_FromString(serialNumber.c_str()); 75 | } 76 | PyObject *py_Freenect2Device_getFirmwareVersion(PyObject *self, PyObject *args) { 77 | PyObject *deviceCapsule = NULL; 78 | if(!PyArg_ParseTuple(args, "O", &deviceCapsule)) 79 | return NULL; 80 | Freenect2Device *device = (Freenect2Device*) PyCapsule_GetPointer(deviceCapsule, "Freenect2Device"); 81 | std::string firmwareVersion = device->getFirmwareVersion(); 82 | return PyUnicode_FromString(firmwareVersion.c_str()); 83 | } 84 | 85 | PyObject *py_Freenect2Device_getColorCameraParams(PyObject *self, PyObject *args) { 86 | PyObject *deviceCapsule = NULL; 87 | if(!PyArg_ParseTuple(args, "O", &deviceCapsule)) 88 | return NULL; 89 | Freenect2Device *device = (Freenect2Device*) PyCapsule_GetPointer(deviceCapsule, "Freenect2Device"); 90 | Freenect2Device::ColorCameraParams *colorCameraParams = new Freenect2Device::ColorCameraParams; 91 | return PyCapsule_New(colorCameraParams, "ColorCameraParams", py_Freenect2Device_ColorCameraParams_destroy); 92 | } 93 | PyObject *py_Freenect2Device_getIRCameraParams(PyObject *self, PyObject *args) { 94 | PyObject *deviceCapsule = NULL; 95 | if(!PyArg_ParseTuple(args, "O", &deviceCapsule)) 96 | return NULL; 97 | Freenect2Device *device = (Freenect2Device*) PyCapsule_GetPointer(deviceCapsule, "Freenect2Device"); 98 | Freenect2Device::IrCameraParams *irCameraParams = new Freenect2Device::IrCameraParams; 99 | return PyCapsule_New(irCameraParams, "IRCameraParams", py_Freenect2Device_IRCameraParams_destroy); 100 | } 101 | 102 | void py_Freenect2Device_ColorCameraParams_destroy(PyObject *colorCameraParamsCapsule) { 103 | delete ((Freenect2Device::ColorCameraParams*) PyCapsule_GetPointer(colorCameraParamsCapsule, "ColorCameraParams")); 104 | } 105 | void py_Freenect2Device_IRCameraParams_destroy(PyObject *irCameraParamsCapsule) { 106 | delete ((Freenect2Device::IrCameraParams*) PyCapsule_GetPointer(irCameraParamsCapsule, "IRCameraParams")); 107 | } 108 | -------------------------------------------------------------------------------- /pyfreenect2.py: -------------------------------------------------------------------------------- 1 | import _pyfreenect2 2 | import numpy as np 3 | from collections import namedtuple 4 | 5 | ExtractedKinectFrame = namedtuple("ExtractedKinectFrame", 6 | ['RGB', 'BGR', 'IR', 'DEPTH']) 7 | 8 | def swap_c0c2(a): 9 | a2 = a.copy() 10 | a2[:,:,0] = a[:,:,2] 11 | a2[:,:,2] = a[:,:,0] 12 | return a2 13 | 14 | class PyFreeNect2(object): 15 | def __init__(self): 16 | 17 | 18 | self.serialNumber = getDefaultDeviceSerialNumber() 19 | self.kinect = Freenect2Device(self.serialNumber) 20 | 21 | self.frameListener = SyncMultiFrameListener(Frame.COLOR, 22 | Frame.IR, 23 | Frame.DEPTH) 24 | self.kinect.setColorFrameListener(self.frameListener) 25 | self.kinect.setIrAndDepthFrameListener(self.frameListener) 26 | self.kinect.start() 27 | self.registration = Registration(self.kinect.ir_camera_params, 28 | self.kinect.color_camera_params) 29 | print("%s setup done" % (self.__class__.__name__)) 30 | 31 | def get_new_frame(self, get_BGR = False): 32 | frames = self.frameListener.waitForNewFrame() 33 | rgbFrame = frames.getFrame(Frame.COLOR) 34 | depthFrame = frames.getFrame(Frame.DEPTH) 35 | 36 | rgb_frame = rgbFrame.getRGBData() 37 | #rgb_to_bgr(rgb_frame) 38 | #bgr_to_rgb(rgb_frame) 39 | 40 | depth_frame = depthFrame.getDepthData() 41 | 42 | bgr_frame = swap_c0c2(rgb_frame) if get_BGR else None 43 | 44 | ## TODO :: IR 45 | ext_k =ExtractedKinectFrame(RGB = rgb_frame, 46 | BGR = bgr_frame, 47 | DEPTH = depth_frame, 48 | IR = None) 49 | return ext_k 50 | 51 | def __del__(self): 52 | self.kinect.stop() 53 | 54 | ## todo :: call close method? was in original pyfreect test.py 55 | #self.kinect.close() 56 | 57 | class PyFreenect2Error(Exception): 58 | def __init__(self, message): 59 | super(PyFreenect2Error, self).__init__(message) 60 | class DeveloperIsALazyBastardError(Exception): 61 | def __init__(self, message): 62 | super(DeveloperIsALazyBastardError, self).__init__(message) 63 | 64 | ################################################################################ 65 | # GLOBAL FUNCTIONS # 66 | ################################################################################ 67 | 68 | def numberOfDevices(): 69 | return _pyfreenect2.numberOfDevices() 70 | 71 | def getDefaultDeviceSerialNumber(): 72 | if numberOfDevices() == 0: 73 | raise PyFreenect2Error("Could not find a Kinect v2") 74 | else: 75 | return _pyfreenect2.getDefaultDeviceSerialNumber() 76 | 77 | ################################################################################ 78 | # Freenect2Device # 79 | ################################################################################ 80 | 81 | class Freenect2Device: 82 | def __init__(self, serialNumber, pipeline=None): 83 | if pipeline is not None: 84 | raise DeveloperIsALazyBastardError("pyfreenect2.PacketPipeline is not yet implemented") 85 | self._capsule = _pyfreenect2.Freenect2Device_new(serialNumber) 86 | def start(self): 87 | _pyfreenect2.Freenect2Device_start(self._capsule) 88 | def stop(self): 89 | _pyfreenect2.Freenect2Device_stop(self._capsule) 90 | def setColorFrameListener(self, listener): 91 | if not isinstance(listener, SyncMultiFrameListener): 92 | raise TypeError("Argument to Freenect2Device.setColorFrameListener must be of type Freenect2Device.SyncMultiFrameListener") 93 | else: 94 | print("listener capsule : " , listener._capsule) 95 | _pyfreenect2.Freenect2Device_setColorFrameListener(self._capsule, listener._capsule) 96 | def setIrAndDepthFrameListener(self, listener): 97 | if not isinstance(listener, SyncMultiFrameListener): 98 | raise TypeError("Argument to Freenect2Device.setIrAndDepthFrameListener must be of type Freenect2Device.SyncMultiFrameListener") 99 | else: 100 | _pyfreenect2.Freenect2Device_setIrAndDepthFrameListener(self._capsule, listener._capsule) 101 | @property 102 | def serial_number(self): 103 | return _pyfreenect2.Freenect2Device_getSerialNumber(self._capsule) 104 | @property 105 | def firmware_version(self): 106 | return _pyfreenect2.Freenect2Device_getFirmwareVersion(self._capsule) 107 | @property 108 | def color_camera_params(self): 109 | return _pyfreenect2.Freenect2Device_getColorCameraParams(self._capsule) 110 | @property 111 | def ir_camera_params(self): 112 | return _pyfreenect2.Freenect2Device_getIRCameraParams(self._capsule) 113 | 114 | ################################################################################ 115 | # SyncMultiFrameListener # 116 | ################################################################################ 117 | 118 | class SyncMultiFrameListener: 119 | def __init__(self, *args): 120 | types = 0 121 | for arg in args: 122 | types |= int(arg) 123 | self._capsule = _pyfreenect2.SyncMultiFrameListener_new(types) 124 | def waitForNewFrame(self): 125 | return FrameMap(_pyfreenect2.SyncMultiFrameListener_waitForNewFrame(self._capsule)) 126 | 127 | ################################################################################ 128 | # FrameMap # 129 | ################################################################################ 130 | 131 | class FrameMap: 132 | def __init__(self, capsule): 133 | self._capsule = capsule 134 | def getFrame(self, frame_type): 135 | if not frame_type in (1, 2, 4): 136 | raise ValueError("frame_type must be one of Frame.COLOR, Frame.IR, or Frame.DEPTH") 137 | else: 138 | return Frame(_pyfreenect2.FrameMap_getFrame(self._capsule, frame_type)) 139 | 140 | ################################################################################ 141 | # Frame # 142 | ################################################################################ 143 | 144 | class Frame: 145 | COLOR = 1 146 | IR = 2 147 | DEPTH = 4 148 | def __init__(self, capsule): 149 | self._capsule = capsule 150 | def getHeight(self): 151 | return _pyfreenect2.Frame_getHeight(self._capsule) 152 | def getWidth(self): 153 | return _pyfreenect2.Frame_getWidth(self._capsule) 154 | def getRGBData(self): 155 | ## todo fix copy necessity (reference counting to frame) 156 | ## todo fix fliplr necessity 157 | ## todo fix BGR :/ 158 | BGR = np.fliplr(_pyfreenect2.Frame_getData(self._capsule).copy()) 159 | RGB = swap_c0c2(BGR) 160 | return RGB 161 | 162 | def getDepthData(self): 163 | ## todo fix copy necessity (reference counting to frame) 164 | ## todo fix fliplr necessity 165 | return np.fliplr(_pyfreenect2.Frame_getDepthData(self._capsule).copy()) 166 | 167 | ################################################################################ 168 | # Registration # 169 | ################################################################################ 170 | 171 | class Registration: 172 | def __init__(self, ir_camera_params, color_camera_params): 173 | self._capsule = _pyfreenect2.Registration_new(ir_camera_params, color_camera_params) 174 | def apply(self, rgbFrame, depthFrame): 175 | return _pyfreenect2.Registration_apply(self._capsule, rgbFrame, depthFrame) 176 | -------------------------------------------------------------------------------- /.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 22 | 23 | 24 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 81 | 82 | 92 | 93 | 94 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 148 | 149 | 165 | 166 | 184 | 185 | 203 | 204 | 224 | 225 | 246 | 247 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 1455942370091 287 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 337 | 338 | 339 | 340 | 341 | file://$PROJECT_DIR$/pyfreenect2.py 342 | 73 343 | 345 | 346 | file://$PROJECT_DIR$/test.py 347 | 11 348 | 350 | 351 | 352 | 353 | 354 | 356 | 357 | 358 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | --------------------------------------------------------------------------------