PyKinect 2.1b1 中 get_next_frame() 的 TODO 问题

1 投票
1 回答
917 浏览
提问于 2025-04-18 09:43

我正在使用Kynect和Python(不使用微软的Visual Studio),在Windows 7系统上工作。

有没有人知道如何在不使用事件循环的情况下从Kinect获取帧数据?

我指的是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)

上面的这个函数是我需要的,但它还没有实现。我需要它来按需获取帧数据(不使用事件循环)。

我该怎么做呢?

我使用的环境和版本如下:

  • Python 2.7.2
  • PyKinect 2.1b1
  • Kinect传感器(来自XBOX v1)
  • Kinect SDK 1.8
  • Windows 7

1 个回答

0

你不能随时获取RGB、深度或骨骼数据。Kinect的数据是通过事件提供的,所以你必须依赖这些事件来获取数据。

为了绕过这种基于事件的系统,你可以把数据保存在一个全局变量里,然后在需要的时候读取这个变量。

比如说,你可以把一个叫做 depth_frame_ready 的函数和深度数据的事件关联起来:

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)

你可以在 depth_frame_ready 函数里把数据保存到一个全局变量(比如叫 depth_data)。你还需要一个同步机制来读取和写入这个变量(一个简单的 Lock 可以避免同时读写):

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)

现在,如果你需要使用深度数据,就可以在任何时候引用这个全局变量。

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

记得在访问时使用 depth_lock 来同步,就像在 update_depth_data() 函数里那样。

撰写回答