2016-12-19 7 views
2

MS Kinect V2에서 실제 좌표를 생성하려고합니다.pylibfreenect2에서 getPointXYZ()를 사용하면 Kinect V2 깊이 이미지에서 이상한 포인트 클라우드 좌표가 생성됩니까?

필자는 pyqt + opengl scatter plot을 함께 처리하고 pylibfreenect2를 사용하여 Kinect의 깊이 데이터를 보여주었습니다.

깊이 데이터가 점군 데이터와 같지 않다는 사실을 즉각 알아 챘습니다. 내 방의 천장이 매우 왜곡 된 예고 약간의 독서 후 깊이 프레임 enter image description here

음모를 꾸미고 내가 관리 소스 파일을 통해 파고의

결과 (평평한 천장해야 어떤 것은 하키 스틱 그래프를 닮은 시작) 매우 유망 해 보였던 기능을 찾는다.

getPointXYZ - 점 구름에서 3-D 포인트를 구축합니다.

한 번에 한 픽셀에서만 작동하기 때문에 간단한 중첩 for 루프를 작성했습니다. 코드에서 당신은 라인을 볼 수 아래 : getPointXYZ에서 좌표의

out = np.zeros((d.shape[0]*d.shape[1], 3)) #shape = (217088, 3) 
for row in range(d.shape[0]): 
    for col in range(d.shape[1]): 
     world = registration.getPointXYZ(undistorted, row, col) #convert depth pixel to real-world coordinate 
     out[row + col] = world 

결과를() enter image description here

거기에 무슨 일이 일어나고 있는지 확실하지. 그것은 직선과 비슷해 보이며 때로는 직사각형과 닮았으며 매우 평면적입니다 (그러나 그것은 3 차원의 임의의 천사에 있습니다). 센서 앞에서 손을 움직이면 어떤 점들이 움직일 수 있지만 선언 할 수있는 모양은 보이지 않습니다. 모든 포인트가한데 어우러져있는 것 같습니다.

다음은 OpenGL 분산 형 플롯을 포함하는 pyQt 응용 프로그램 창을 보여주는 Python 스크립트입니다. 프레임은 pylibfreenect2를 통해 Kinect 센서로부터 수신되며, 분산 데이터의 각 행과 열을 반복하고 getPointXYZ를 통해 전송하여 산점도의 점을 생성합니다 (이 속도는 실제로 느리며 작동하지 않습니다 ...).

# coding: utf-8 

# An example using startStreams 
from pyqtgraph.Qt import QtCore, QtGui 
import pyqtgraph.opengl as gl 

import numpy as np 
import cv2 
import sys 
from pylibfreenect2 import Freenect2, SyncMultiFrameListener 
from pylibfreenect2 import FrameType, Registration, Frame, libfreenect2 

fn = Freenect2() 
num_devices = fn.enumerateDevices() 
if num_devices == 0: 
    print("No device connected!") 
    sys.exit(1) 

serial = fn.getDeviceSerialNumber(0) 
device = fn.openDevice(serial) 

types = 0 
types |= FrameType.Color 
types |= (FrameType.Ir | FrameType.Depth) 
listener = SyncMultiFrameListener(types) 

# Register listeners 
device.setColorFrameListener(listener) 
device.setIrAndDepthFrameListener(listener) 

device.start() 

# NOTE: must be called after device.start() 
registration = Registration(device.getIrCameraParams(), 
          device.getColorCameraParams()) 

undistorted = Frame(512, 424, 4) 
registered = Frame(512, 424, 4) 


#QT app 
app = QtGui.QApplication([]) 
w = gl.GLViewWidget() 
w.show() 
g = gl.GLGridItem() 
w.addItem(g) 

#initialize some points data 
pos = np.zeros((1,3)) 

sp2 = gl.GLScatterPlotItem(pos=pos) 
w.addItem(sp2) 


def update(): 
    frames = listener.waitForNewFrame() 

    ir = frames["ir"] 
    color = frames["color"] 
    depth = frames["depth"] 

    d = depth.asarray() 

    registration.apply(color, depth, undistorted, registered) 

    #There are 3 optionally commented methods for generating points data (the last one is not commented here). 
    #First will generate points using depth data only. 
    #Second will generate colored points and pointcloud xyz coordinates. 
    #Third is simply the pointcloud xyz coordinates without the color mapping. 

    """ 
    #Format depth data to be displayed 
    m, n = d.shape 
    R, C = np.mgrid[:m, :n] 
    out = np.column_stack((d.ravel()/4500, C.ravel()/m, (-R.ravel()/n)+1)) 
    """ 

    """ 
    #Format undistorted and regisered data to real-world coordinates with mapped colors (dont forget color=out_col in setData) 
    out = np.zeros((d.shape[0]*d.shape[1], 3)) #shape = (217088, 3) 
    out_col = np.zeros((d.shape[0]*d.shape[1], 3)) #shape = (217088, 3) 
    for row in range(d.shape[0]): 
     for col in range(d.shape[1]): 
      world = registration.getPointXYZRGB(undistorted, registered, row, col) 
      out[row + col] = world[0:3] 
      out_col[row + col] = np.array(world[3:6])/255 

    """ 

    # Format undistorted data to real-world coordinates 
    out = np.zeros((d.shape[0]*d.shape[1], 3)) #shape = (217088, 3) 
    for row in range(d.shape[0]): 
     for col in range(d.shape[1]): 
      world = registration.getPointXYZ(undistorted, row, col) 
      out[row + col] = world 


    sp2.setData(pos=out, size=2) 

    listener.release(frames) 

t = QtCore.QTimer() 
t.timeout.connect(update) 
t.start(50) 


## Start Qt event loop unless running in interactive mode. 
if __name__ == '__main__': 
    import sys 
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'): 
     QtGui.QApplication.instance().exec_() 

device.stop() 
device.close() 

sys.exit(0) 

실제 점군 데이터를 얻으려면 다음에해야 할 일이 확실하지 않습니다.

누구에게 내가 뭘 잘못하고 있는지에 대한 제안이 있습니까?

내 운영 체제는 파이썬 3.5

감사와 우분투 16.0.4입니다.

답변

1

대답은 실제로 중첩 루프에서 실수를 해결하는 것이 었습니다. 배열을 올바르게 인덱싱하지 않는 것으로 나타났습니다.

#From: 
out[row + col] 
#To: 
out[row * n_columns + col] 

정점은 이제 3D 공간에 정확하게 배치되며 모두 잘 보입니다!

enter image description here

다음은 수정 및 완전한 기능을 코드입니다 :

# coding: utf-8 

# An example using startStreams 
from pyqtgraph.Qt import QtCore, QtGui 
import pyqtgraph.opengl as gl 

import numpy as np 
import cv2 
import sys 
from pylibfreenect2 import Freenect2, SyncMultiFrameListener 
from pylibfreenect2 import FrameType, Registration, Frame, libfreenect2 

fn = Freenect2() 
num_devices = fn.enumerateDevices() 
if num_devices == 0: 
    print("No device connected!") 
    sys.exit(1) 

serial = fn.getDeviceSerialNumber(0) 
device = fn.openDevice(serial) 

types = 0 
types |= FrameType.Color 
types |= (FrameType.Ir | FrameType.Depth) 
listener = SyncMultiFrameListener(types) 

# Register listeners 
device.setColorFrameListener(listener) 
device.setIrAndDepthFrameListener(listener) 

device.start() 

# NOTE: must be called after device.start() 
registration = Registration(device.getIrCameraParams(), 
          device.getColorCameraParams()) 

undistorted = Frame(512, 424, 4) 
registered = Frame(512, 424, 4) 


#QT app 
app = QtGui.QApplication([]) 
w = gl.GLViewWidget() 
w.show() 
g = gl.GLGridItem() 
w.addItem(g) 

#initialize some points data 
pos = np.zeros((1,3)) 

sp2 = gl.GLScatterPlotItem(pos=pos) 
w.addItem(sp2) 

def update(): 
    colors = ((1.0, 1.0, 1.0, 1.0)) 

    frames = listener.waitForNewFrame() 

    ir = frames["ir"] 
    color = frames["color"] 
    depth = frames["depth"] 

    d = depth.asarray() 

    registration.apply(color, depth, undistorted, registered) 

    listener.release(frames) 

    """ 
    #Format raw depth data to be displayed 
    m, n = d.shape 
    R, C = np.mgrid[:m, :n] 
    out = np.column_stack((d.ravel()/4500, C.ravel()/m, (-R.ravel()/n)+1)) 
    """ 


    #Format undistorted and regisered data to real-world coordinates with mapped colors (dont forget color=out_col in setData) 
    n_rows = d.shape[0] 
    n_columns = d.shape[1] 
    out = np.zeros((d.shape[0] * d.shape[1], 3), dtype=np.float64) 
    colors = np.zeros((d.shape[0] * d.shape[1], 3), dtype=np.float64) 
    for row in range(n_rows): 
     for col in range(n_columns): 
      X, Y, Z, B, G, R = registration.getPointXYZRGB(undistorted, registered, row, col) 
      out[row * n_columns + col] = np.array([X, Y, Z]) # np.array(pt, dtype=np.float64) 
      colors[row * n_columns + col] = np.divide([R, G, B], 255) # np.array(pt, dtype=np.float64) 


    """ 
    #Format undistorted depth data to real-world coordinates 
    n_rows = d.shape[0] 
    n_columns = d.shape[1] 
    out = np.zeros((d.shape[0] * d.shape[1], 3), dtype=np.float64) 
    for row in range(n_rows): 
     for col in range(n_columns): 
      X, Y, Z = registration.getPointXYZ(undistorted, row, col) 
      out[row * n_columns + col] = np.array([X, Y, Z]) # np.array(pt, dtype=np.float64) 
    """ 

    sp2.setData(pos=np.array(out, dtype=np.float64), color=colors, size=2) 



t = QtCore.QTimer() 
t.timeout.connect(update) 
t.start(50) 


## Start Qt event loop unless running in interactive mode. 
if __name__ == '__main__': 
    import sys 
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'): 
     QtGui.QApplication.instance().exec_() 

device.stop() 
device.close() 

sys.exit(0) 

[편집]

추가 정보

에 대한 This Post를 참조하십시오