Python调用Kinect 2
前言
发现github已经有很多Pykinect2的完善版本了,比我这边的完善了很多,一下的文章不用看了,大家直接去github上找就可以。CSDN有点恶心了,直接点击链接会转到一个VIP才能看到博文上(开源项目拿来收费是不是有点恶心?),大家可以右键选择在新窗口打开。推荐一个github项目(2020/12/31 更新)
Kinect 2 是微软的一款深度相机,微软本身提供了很好的SDK支持,SDK中包括了多个基础的API,例如RGB和Depth图像对齐,相机标定,图像像素空间转换,人体骨架识别函数等。但是其原生接口是C++的,并没有直接提供python的接口。
在Python中开发Kinect 目前有3种方法:
1、一种可行的方法是配置第三方驱动,即Libfreenect2以及OpenNi,但是这种方法有几个问题。
- 配置过程十分麻烦,不同的电脑环境总会遇到不同的问题,需要一路踩坑过去。
- 不能直接使用其SDK提供的函数支持,如骨架识别等。
2、第二种是利用Python和MATLAB联合编程(MATLAB提供了接口,可自行查找),因为MATLAB中有Kin2工具可以直接调用Kinect的SDK。也就是
Python——>MATLAB——>Kin2——>SDK——>Kinect2.
这种方式是我在第一种方法实在配不通的情况不得已自己摸索出来的。但是这种方式有很大的问题
- 程序运行的时候会自动启动MATLAB的后台,占用内存大。
- Matlab与python 通讯采用的是matlab提供的接口,对尺寸大的图像传输实时性受限,深度图还行,但是彩色图就明显有很大的延时了。
- Python调用Matlab时初始化很慢,调试很麻烦。
3、第三种方法是安装Pykinect2库,这是Python中的一个第三方库,可以直接调用Kinect 2 的SDK,但是他同样存在几个问题。
- 数据方面仅提供了获取RGB和Depth图像的接口。
- 算法方面仅提供了人体检测和人体骨架检测的接口。
在第二种方法实在让我难以接受其延时性的情况下,我考虑了能否对pykinect 进行完善。在其github的issues中也不少了提问了如何扩展的问题,但仍然没有得到解决。而我将问题中几个存在bug的代码尝试修改后,竟然实现了。这已经是一年前的工作了,下面会详细介绍一下。
工作环境
系统:win10 家庭版
Python:3.6版本
IDE:Pycharm
驱动:Microsolft SDK
Python 库: Pykinect
资料准备
Kinect SDK(暂无)
Pykinect2 Github网站
Pykinect2 下载
建议直接在github中下载Pykinect 而不采用pip安装,因为github的版本会比pip稍微新一点。
Pykinect安装
将下载下来的zip文件解压缩,
运行的时候会出来一个类似下面的错误。解决方法在后面的问题记录里面。
关键的代码
发现这部分关心的人比较多,先把自己之前的代码发出来,其他细节以后再慢慢补充。我不是科班的程序员,不要吐槽。。。。
# -*- coding:utf-8 -*-
"""
time:2019/5/1 19:34
author:Lance
organization: HIT
contact: QQ:261983626 , wechat:yuan261983626
——————————————————————————————
description:
$ 自己基于Pykinect2 写的一个Kinect的类。
主要包括:
彩色图像、深度图像、红外图像的获取
彩色图像和深度图像的坐标空间互换
——————————————————————————————
note:
$
"""
from pykinect2 import PyKinectV2
from pykinect2.PyKinectV2 import *
from pykinect2 import PyKinectRuntime
import numpy as np
import ctypes
import math
import cv2 as cv
import time
import copy
class Kinect(object):
def __init__(self):
self._kinect = PyKinectRuntime.PyKinectRuntime(PyKinectV2.FrameSourceTypes_Color | PyKinectV2.FrameSourceTypes_Depth | PyKinectV2.FrameSourceTypes_Infrared)
self.depth_ori = None
self.infrared_frame = None
self.color_frame = None
self.w_color = 1920
self.h_color = 1080
self.w_depth = 512
self.h_depth = 424
"""————————————————(2019/5/10)——————————————————"""
self.csp_type = _ColorSpacePoint * np.int(1920 * 1080)
self.csp = ctypes.cast(self.csp_type(), ctypes.POINTER(_DepthSpacePoint))
"""————————————————(2019/9/4)——————————————————"""
self.color = None
self.depth = None
self.depth_draw = None
self.color_draw = None
self.infrared = None
self.first_time = True
"""————————————————(2019/5/1)——————————————————"""
"""获取最新的图像数据"""
def get_the_last_color(self):
"""
Time :2019/5/1
FunC:获取最新的图像数据
Input:无
Return:无
"""
if self._kinect.has_new_color_frame():
# 获得的图像数据是二维的,需要转换为需要的格式
frame = self._kinect.get_last_color_frame()
# 返回的是4通道,还有一通道是没有注册的
gbra = frame.reshape([self._kinect.color_frame_desc.Height, self._kinect.color_frame_desc.Width, 4])
# 取出彩色图像数据
self.color_frame = gbra[:, :, 0:3]
return self.color_frame
"""————————————————(2019/5/1)——————————————————"""
"""获取最新的深度数据"""
def get_the_last_depth(self):
"""
Time :2019/5/1
FunC:获取最新的图像数据
Input:无
Return:无
"""
if self._kinect.has_new_depth_frame():
# 获得深度图数据
frame = self._kinect.get_last_depth_frame()
# 转换为图像排列
image_depth_all = frame.reshape([self._kinect.depth_frame_desc.Height,
self._kinect.depth_frame_desc.Width])
self.depth_ori = image_depth_all
return self.depth_ori
"""————————————————(2019/5/1)——————————————————"""
"""获取最新的红外数据"""
def get_the_last_infrared(self):