使用 Pykinect 和 Open CV 保存 Kinect RGB 和深度图像

Posted

技术标签:

【中文标题】使用 Pykinect 和 Open CV 保存 Kinect RGB 和深度图像【英文标题】:Save Kinect RGB and Depth Images using Pykinect and Open CV 【发布时间】:2018-11-15 09:52:24 【问题描述】:

我在 Windows 中使用 PyKinect 和 OpenCV 来保存 RGB 和 kinect 深度图像。 可以很好地显示 RGB 和深度图像。 RGB 和深度图像的帧速率均为 30FPS。

我想以 .jpg 格式保存 RGB 图像,以 .xml 格式保存深度图像。这也可以正常工作。

但我的问题是当我开始保存 RGB 和深度图像时,我没有获得相同的帧速率。就像如果我将图像保存 10 秒,我会得到 300 个 XML 文件,但同时我会得到 100 个 JPG 图像。

但如果我执行相同的程序仅保存 RGB 图像(注释掉深度图像部分)10 秒,我会得到 300 个 JPG 文件。所以我相信这是一个可以改进的性能问题。任何提高性能的建议表示赞赏。

这是我的方法:

from pykinect import nui
from pykinect.nui import JointId
import numpy
from numpy import * 
import cv2
import datetime


import os
import os.path
from os.path import join as pjoin
from pykinect.nui import SkeletonTrackingState

current_directory = os.getcwd()

kinect = nui.Runtime()
save_image = False


def getColorImage(frame):
    height,width = frame.image.height,frame.image.width #get width and height of the images 
    rgb = numpy.empty((height,width,4),numpy.uint8) 
    frame.image.copy_bits(rgb.ctypes.data) #copy the bit of the image to the aray   
    cv2.imshow('KINECT Video Stream', rgb) # display the image
    # save to Folder
    folder = 'RGB_images'+'\\s'+ subject_id +'_a' +activity_id
    if not os.path.exists(folder):
        os.makedirs(folder)
    path = current_directory+str('\\')+folder
    image_name = 'color_image_'+str(frame.frame_number)+'.jpg'
    if save_image:
        cv2.imwrite(os.path.join(path,image_name), rgb)


def getDepthImage(frame):
    height,width = frame.image.height,frame.image.width #get frame height and width
    depth_frame = saveDepthImageData(frame.frame_number)
    depth = numpy.empty((height,width,1),numpy.uint8)   
    arr2d = (depth >> 3) & 4095 
    arr2d >>= 4

    frame.image.copy_bits(arr2d.ctypes.data)

    cv2.imshow('KINECT depth Stream', arr2d)

    folder = 'Depth_data'+'\\s'+ subject_id +'_a' +activity_id
    if not os.path.exists(folder):
        os.makedirs(folder)     
    path = current_directory+str('\\')+folder
    file_name = 'depth_image_'+str(frame.frame_number)+'.xml'
    file_to_save = os.path.join(path,file_name)
    if save_image:      
        f = cv2.FileStorage(file_to_save,flags=1)
        f.write("depthImg",arr2d)
        f.release() #close the file


def main():
    global save_image
    global subject_id
    global activity_id


    subject_id = raw_input("Subject id : ")
    activity_id = raw_input("Activity id : ")
    print "Press t to start saving"
    print "Press Esc to quit"

    kinect.video_frame_ready += getColorImage
    kinect.video_stream.open(nui.ImageStreamType.Video, 2,nui.ImageResolution.Resolution640x480,nui.ImageType.Color)
    cv2.namedWindow('KINECT Video Stream', cv2.WINDOW_AUTOSIZE)

    kinect.depth_frame_ready += getDepthImage
    kinect.depth_stream.open(nui.ImageStreamType.Depth, 2, nui.ImageResolution.Resolution320x240, nui.ImageType.Depth)
    cv2.namedWindow('KINECT depth Stream', cv2.WINDOW_AUTOSIZE)

    while True:
        key = cv2.waitKey(0)        
        if key == 116:
            save_image = not save_image
        if key == 27:           
            cv2.destroyAllWindows()
            kinect.close()
            break   


if __name__ == '__main__':
    main()

【问题讨论】:

写入磁盘花费时间...您从 pykinect 获得的深度图像的像素是什么类型?如果它是 16 位,您可以将其保存为不压缩的 png 对于 RGB 图像分辨率 640x480 和深度图像分辨率 320x240 我将深度图像保存在 xml 中,因为我可能会重复使用它们,如果我将它们保存为 PNG,它不会有用,因为深度数据会丢失。 您可以将深度图高效地保存为一个简单的灰度 NetPBM 文件en.wikipedia.org/wiki/Netpbm_format,扩展名为.PGM @amranhossen 这不是真的。许多深度图像以 16 位无符号整数形式出现,无需压缩即可保存为 png……这意味着没有数据丢失并且权重更小。我出于同样的目的使用了这种方法。马克的建议也将起作用。 【参考方案1】:

将深度图像转换为 XML 将大大增加其大小。 Kinect 深度图像是 640x480 IIRC,而不是每个像素的单个 11 位值,XML 将平均使用每个像素 10 个字节,这意味着每帧约 3.5 MB,然后您的代码将不得不编写仅就磁盘 I/O 而言接近 100 MB/s(不包括整个 XML 转换)。

我建议使用另一种格式来保存深度图像,可能像 PGM 这样简单的东西会是一个想法。

【讨论】:

以上是关于使用 Pykinect 和 Open CV 保存 Kinect RGB 和深度图像的主要内容,如果未能解决你的问题,请参考以下文章

计算机视觉实战基础Open-CV的使用

mini6410 上的 Open Cv 和 GPIO 出现问题

OpenCV图像处理基本操作 Open_CV系列

小啾带你开天眼 之 开启py-OpenCV摄像头及视频处理Python-Open_CV系列

Numpy和open cv不导入[重复]

PIL Image.open 和 cv2.imdecode 的区别