使用Pykinect访问Kinect深度数据

3
我目前正在处理一个项目,需要使用PyKinect库来访问和处理深度数据。
我的目标是定义一个深度阈值,进行图像分割。但由于我对PyKinect不太熟悉,也不知道在哪里寻找资源,因此我不知道如何访问数据并获取值。
我尝试过使用freenect库,但无法使其正常工作。
请问有人能告诉我如何做到这一点,或者将我重定向到某种文档资料吗?
1个回答

5

我刚在我的BitBucket账户上创建了一个片段,用PyKinect和Pygame来可视化深度图像。以下是代码:

import thread
import pygame
from pykinect import nui

DEPTH_WINSIZE = 320,240

screen_lock = thread.allocate()
screen = None

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


def depth_frame_ready(frame):
    with screen_lock:
        frame.image.copy_bits(tmp_s._pixels_address)
        arr2d = (pygame.surfarray.pixels2d(tmp_s) >> 7) & 255
        pygame.surfarray.blit_array(screen, arr2d)

        pygame.display.update()


def main():
    """Initialize and run the game."""
    pygame.init()

    # Initialize PyGame
    global screen
    screen = pygame.display.set_mode(DEPTH_WINSIZE, 0, 8)
    screen.set_palette(tuple([(i, i, i) for i in range(256)]))
    pygame.display.set_caption('PyKinect Depth Map Example')

    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)

        # Main game loop
        while True:
            event = pygame.event.wait()

            if event.type == pygame.QUIT:
                break

if __name__ == '__main__':
    main()

编辑: 上面的代码展示了如何将深度数据转换为8位表示(这样它们可以轻松地绘制成灰度图像)。但是如果您想使用实际的深度数据,您需要知道它们的结构。

使用Microsoft Kinect SDK(PyKinect基于此),单个深度像素由16位组成。其中3个最不显著的位表示玩家索引,而我没有很好地理解最显著的位的含义...但是我们需要删除最后3位和第一位。例如,这是每个像素需要做的事情的示例(取自this question):

0 1 1 0 0 0 1 0 0 0 1 1 1 0 0 0 - 16 bits number
0 1 1 0 0 0 1 0 0 0 1 1 1       - 13 bits number
  1 1 0 0 0 1 0 0 0 1 1 1       - 12 bits number

上述操作(删除最后3位和第一个)可以通过对arr2d数组进行两个位运算来实现。由于它是一个NumPy数组,因此您可以按以下方式进行操作:
def depth_frame_ready(frame):
    frame.image.copy_bits(tmp_s._pixels_address)

    arr2d = (pygame.surfarray.pixels2d(tmp_s) >> 3) & 4095
    # arr2d[x,y] is the actual depth measured in mm at (x,y)

然后,您可能需要显示此数据,因此您可能需要8位表示。要获取它:

arr2d >>= 4

我想做的是设置一个层来捕捉我的伸出手臂,然后对它进行一些图像处理,而不是获取深度图。我想知道和了解如何从深度图中获取实际值。 - Big Puncho
我刚刚编辑了我的答案。在第一个解决方案中,我处理了位以将它们显示为灰度图像。如果您需要获取实际深度数据,则只需使用我刚刚添加的第二个代码片段。如果您需要在某些处理后显示深度数据,则在显示之前执行最后一个移位(arr2d >>= 4):这个最后的操作将把您处理过的深度图转换为8位灰度图像。 - Vito Gentile
谢谢,这对我想做的事情足够了。我不知道如何使用和解释深度图,并猜测 PyKinect 中是否有一个函数,可以过滤掉任何不需要的深度数据并给出一个阈值或类似的东西来使用。 - Big Puncho

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接