Python OpenNI2 - eiichiromomma/CVMLAB GitHub Wiki
Python) OpenNI2
(PythonでOpenNI 2とNiTE 2を使う
※Xtion Proでテスト
OpenNI2およびNiTe2の導入
各サイトに説明されているので省略
Mac OS Xの場合
どちらもinstall.shを実行後に生成されるOpenNIDevEnvironmentおよびNiTEDevEnvironmentを実行し、環境変数が指定されていることを意味する。 一々打つのが面倒な場合には .profile 等に以下のように記述しておく。
source /InstalledDir/OpenNI-MacOSX-x64-2.x/OpenNIDevEnvironment
source /InstalledDir/NiTE-MacOSX-x64-2.x/NiTEDevEnvironment
primesense package の導入
conda等のパッケージマネージャでインストールできる。
自力でインストールする場合はhttps://pypi.python.org/pypi/primesense/からzipなりtar.gzを入手し、適当な場所へ展開する。 コマンドラインから python setup.py install で導入完了。
テスト
サンプルで載っているソース
下記ファイルを実行すると一瞬投光部が光る
from primesense import openni2
openni2.initialize() # can also accept the path of the OpenNI redistribution
dev = openni2.Device.open_any()
print dev.get_sensor_info(openni2.SENSOR_DEPTH)
depth_stream = dev.create_depth_stream()
depth_stream.start()
frame = depth_stream.read_frame()
frame_data = frame.get_buffer_as_uint16()
depth_stream.stop()
openni2.unload()
frameデータからの変換
frame_dataはuint16のバッファになっていて、numpyのndarrayへdtypeの指定無しで入れるとおかしな事になるので
import numpy as np
import matplotlib.pyplot as plt
depth_array = np.ndarray((frame.height,frame.width),dtype=np.uint16,buffer=frame_data)
とする。 あとは
plt.imshow(depth_array)
plt.show()
で表示できる。
通しだと下記の通り。
import numpy as np
import matplotlib.pyplot as plt
from primesense import openni2
openni2.initialize() # can also accept the path of the OpenNI redistribution
dev = openni2.Device.open_any()
print dev.get_sensor_info(openni2.SENSOR_DEPTH)
depth_stream = dev.create_depth_stream()
depth_stream.start()
frame = depth_stream.read_frame()
frame_data = frame.get_buffer_as_uint16()
depth_stream.stop()
openni2.unload()
depth_array = np.ndarray((frame.height,frame.width),dtype=np.uint16,buffer=frame_data)
plt.imshow(depth_array)
plt.show()
OpenCV との連携
特に大した事はしていないが、それなりの速さで取り込み可能
# encoding: utf-8
# oni_ocv_sample.py
# 2013-9-13
# Eiichiro Momma
__author__ = 'momma'
import numpy as np
import matplotlib.pyplot as plt
from primesense import openni2
import cv2
openni2.initialize() # can also accept the path of the OpenNI redistribution
dev = openni2.Device.open_any()
print dev.get_sensor_info(openni2.SENSOR_DEPTH)
depth_stream = dev.create_depth_stream()
depth_stream.start()
shot_idx = 0
while True:
frame = depth_stream.read_frame()
frame_data = frame.get_buffer_as_uint16()
depth_array = np.ndarray((frame.height, frame.width),dtype=np.uint16,buffer=frame_data)/10000. #0-10000mm to 0.-1.
cv2.imshow('Depth',depth_array)
ch = 0xFF & cv2.waitKey(1)
if ch == 27:
break
if ch == ord(' '):
fn = 'shot_%03d.png)' % shot_idx
cv2.imwrite(fn, (depth_array*255).astype(np.uint8))
print fn, ' saved'
shot_idx += 1
depth_stream.stop()
openni2.unload()
cv2.destroyAllWindows()
IRセンサも追加
C I/F同様にストリームを指定するだけでIR画像が得られる。但し16bitで1000程度の値にしかならないので,ここでは最大値で正規化している。
# encoding: utf-8
# oni_ocv_sample.py
# 2013-9-13
# Eiichiro Momma
__author__ = 'momma'
import numpy as np
import matplotlib.pyplot as plt
from primesense import openni2
import cv2
openni2.initialize() # can also accept the path of the OpenNI redistribution
dev = openni2.Device.open_any()
print dev.get_sensor_info(openni2.SENSOR_DEPTH)
depth_stream = dev.create_depth_stream()
depth_stream.start()
ir_stream = dev.create_ir_stream()
ir_stream.start()
shot_idx = 0
while True:
frame = depth_stream.read_frame()
frame_data = frame.get_buffer_as_uint16()
depth_array = np.ndarray((frame.height, frame.width),dtype=np.uint16,buffer=frame_data)/10000. #0-10000mm to 0.-1.
cv2.imshow('Depth',depth_array)
ir_frame = ir_stream.read_frame()
ir_frame_data = ir_frame.get_buffer_as_uint16()
ir_array = np.ndarray((ir_frame.height, ir_frame.width),dtype=np.uint16, buffer = ir_frame_data).astype(np.float32)
cv2.imshow('IR',ir_array/ir_array.max())
ch = 0xFF & cv2.waitKey(1)
if ch == 27:
break
if ch == ord(' '):
fn = 'depth_shot_%03d.png)' % shot_idx
cv2.imwrite(fn, (depth_array*255).astype(np.uint8))
print fn, ' saved'
fn = 'ir_shot_%03d.png)' % shot_idx
cv2.imwrite(fn, (ir_array/ir_array.max()*255).astype(np.uint8))
print fn, ' saved'
shot_idx += 1
depth_stream.stop()
openni2.unload()
cv2.destroyAllWindows()
depthをCSVに書き出し+フレームサイズを640x480に
要望があったので追加
# encoding: utf-8
# oni_ocv_sample2.py
# 2014-10-29
# Eiichiro Momma
__author__ = 'momma'
import numpy as np
import matplotlib.pyplot as plt
from primesense import openni2
import cv2
openni2.initialize() # can also accept the path of the OpenNI redistribution
dev = openni2.Device.open_any()
print dev.get_sensor_info(openni2.SENSOR_DEPTH)
depth_stream = dev.create_depth_stream()
depth_stream.set_video_mode(openni2.c_api.OniVideoMode(pixelFormat = openni2.c_api.OniPixelFormat.ONI_PIXEL_FORMAT_DEPTH_1_MM, resolutionX = 640, resolutionY = 480, fps = 30))
depth_stream.start()
ir_stream = dev.create_ir_stream()
ir_stream.set_video_mode(openni2.c_api.OniVideoMode(pixelFormat = openni2.c_api.OniPixelFormat.ONI_PIXEL_FORMAT_GRAY16, resolutionX = 640, resolutionY = 480, fps = 30))
ir_stream.set_video_mode(vmode)
ir_stream.start()
shot_idx = 0
while True:
frame = depth_stream.read_frame()
frame_data = frame.get_buffer_as_uint16()
depth_array = np.ndarray((frame.height,frame.width),dtype=np.uint16,buffer=frame_data)/10000. #0-10000mm to 0.-1.
depth_array_mm = np.ndarray((frame.height,frame.width),dtype=np.uint16,buffer=frame_data) #0-10000mm
cv2.imshow('Depth',depth_array)
ir_frame = ir_stream.read_frame()
#Kinect
# ir_frame_data = ir_frame.get_buffer_as_uint8()
# ir_array = np.ndarray((ir_frame.height,ir_frame.width),dtype=np.uint8, buffer = ir_frame_data).astype(np.float32)
#Xtion Pro
ir_frame_data = ir_frame.get_buffer_as_uint16()
ir_array = np.ndarray((ir_frame.height,ir_frame.width),dtype=np.uint16, buffer = ir_frame_data).astype(np.float32)
cv2.imshow('IR',ir_array/ir_array.max())
ch = 0xFF & cv2.waitKey(500)
if ch == 27:
break
if ch == ord(' '):
# if True:
fn = 'depth_shot_%03d.png' % shot_idx
cv2.imwrite(fn, (depth_array*255).astype(np.uint8))
print fn, 'depth saved'
fn = 'ir_shot_%03d.png' % shot_idx
cv2.imwrite(fn, (ir_array/ir_array.max()*255).astype(np.uint8))
print fn, 'ir saved'
fn = 'depth_mm_%03d.csv' % shot_idx
np.savetxt(fn,depth_array_mm,'%d',delimiter=',')
shot_idx += 1
depth_stream.stop()
ir_stream.stop()
openni2.unload()
cv2.destroyAllWindows()
NiTE2の利用
普通にinitializeするとエラーが発生する。site-packages内にインストールされた_nite2.pyからniteDumpUserTrackerCalibrationDataToFile関連をコメントアウトするとinitializeに成功するが、使い方が不明。