PyKinect helps/ about TODO in version 2.1b1 get_next_frame()

925 Views Asked by At

I am working with Kynect + Python (without using Micosoft visual studio), on windows 7.

Does anybody know how to get frames from Kinect without using an event loop?

I am refering to this method of PyKinect/nui/init.py

def get_next_frame(self, milliseconds_to_wait = 0):
# TODO: Allow user to provide a NUI_IMAGE_FRAME ?
return self.runtime._nui.NuiImageStreamGetNextFrame(self._stream, milliseconds_to_wait)

The above function is what I need and it isn't implemented yet. I need it to get frames on demand (without using an event loop).

How can I do this?

I am using the following environment and versions:

  • Python 2.7.2
  • PyKinect 2.1b1
  • Kinect sensor (from XBOX v1)
  • Kinect SDK 1.8
  • Windows 7
1

There are 1 best solutions below

0
On

You cannot get RGB or depth or skeleton frame "on demand". Kinect data are provided by events, so you have to use them to got data.

The only thing that you can do to workaround this event-based system, is to save your data in a global variable, and then read that variable whenever you need it.

For instance, let's say that you associate a function named depth_frame_ready to the event related to depth data:

from pykinect import nui

with nui.Runtime() as kinect:
    kinect.depth_frame_ready += depth_frame_ready   
    kinect.depth_stream.open(nui.ImageStreamType.Depth, 2, nui.ImageResolution.Resolution320x240, nui.ImageType.Depth)

You can write the depth_frame_ready function to save data on a global variable (let's say depth_data). You will also need a synchronization mechanism to read and write that variable (a simple Lock to avoid simultaneously writing and reading):

import threading
import pygame

DEPTH_WINSIZE = 320,240
tmp_s = pygame.Surface(DEPTH_WINSIZE, 0, 16)

depth_data = None
depth_lock = threading.Lock()

def update_depth_data(new_depth_data):
    global depth_data
    depth_lock.acquire()
    depth_data = new_depth_data
    depth_lock.release()

#based on https://bitbucket.org/snippets/VitoGentile/Eoze
def depth_frame_ready(frame):
    # Copy raw data in a temp surface
    frame.image.copy_bits(tmp_s._pixels_address)

    update_depth_data((pygame.surfarray.pixels2d(tmp_s) >> 3) & 4095)

Now, if you need to use depth data, you can refer to the global variable whenever you want.

global depth_data
if depth_data is not None:
    #read your data

Remember to use depth_lock to synchronize the access, as done in the update_depth_data() function.