Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

python3 compatibility #2

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
95 changes: 64 additions & 31 deletions cyni.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ import sys
from struct import pack, unpack, calcsize

pixelFormats = {
"rgb": c_openni2.PIXEL_FORMAT_RGB888,
"yuv422": c_openni2.PIXEL_FORMAT_YUV422,
"gray16": c_openni2.PIXEL_FORMAT_GRAY16,
"depth1mm": c_openni2.PIXEL_FORMAT_DEPTH_1_MM,
"depth100um": c_openni2.PIXEL_FORMAT_DEPTH_100_UM,
b"rgb": c_openni2.PIXEL_FORMAT_RGB888,
b"yuv422": c_openni2.PIXEL_FORMAT_YUV422,
b"gray16": c_openni2.PIXEL_FORMAT_GRAY16,
b"depth1mm": c_openni2.PIXEL_FORMAT_DEPTH_1_MM,
b"depth100um": c_openni2.PIXEL_FORMAT_DEPTH_100_UM,
}

pixelFormatsReverse = dict([[v, k] for k, v in pixelFormats.items()])
Expand All @@ -36,7 +36,10 @@ def error(*args):


def initialize():
return c_openni2.initialize()
ret = c_openni2.initialize()
if ret != c_openni2.STATUS_OK:
raise RuntimeError("Failed to initialize OpenNi2, return code was {}".format(ret))
return ret


def enumerateDevices():
Expand Down Expand Up @@ -67,7 +70,7 @@ cdef class Device(object):
_stream.stop()
_stream.destroy()
self._streams.clear()

self._device.close()

def __init__(self, uri):
Expand Down Expand Up @@ -166,8 +169,8 @@ class Frame(object):

cdef class VideoStream(object):
cdef c_openni2.VideoStream _stream
cdef string _streamType
cdef string _pixelFormat
cdef bytes _streamType
cdef bytes _pixelFormat
cdef int frameSize

cdef readonly int width
Expand Down Expand Up @@ -200,17 +203,17 @@ cdef class VideoStream(object):
status = self._stream.create(_device, c_openni2.SENSOR_IR)

if status != c_openni2.STATUS_OK:
error("Error opening %s stream." % self.streamType)
error("Error opening %s stream." % self._streamType)

cdef const c_openni2.SensorInfo* _info = &self._stream.getSensorInfo()

cdef const c_openni2.Array[c_openni2.VideoMode]* _modes
_modes = &(_info.getSupportedVideoModes())

foundMode = False
if self._streamType == b"color" and pixelFormat != "rgb":
if self._streamType == b"color" and pixelFormat != b"rgb":
if pixelFormat is None:
pixelFormat = "rgb"
pixelFormat = b"rgb"
else:
error("Only RGB currently supported for color streams.")
self.destroy()
Expand All @@ -233,15 +236,15 @@ cdef class VideoStream(object):
# Set the pixel format in case it was None
pixelFormat = pixelFormatsReverse[mode.getPixelFormat()]

if pixelFormat == "rgb":
if pixelFormat == b"rgb":
pixelSize = sizeof(c_openni2.RGB888Pixel)
elif pixelFormat == "yuv422":
elif pixelFormat == b"yuv422":
pixelSize = sizeof(c_openni2.YUV422DoublePixel)
elif pixelFormat == "depth1mm":
elif pixelFormat == b"depth1mm":
pixelSize = sizeof(c_openni2.DepthPixel)
elif pixelFormat == "depth100um":
elif pixelFormat == b"depth100um":
pixelSize = sizeof(c_openni2.DepthPixel)
elif pixelFormat == "gray16":
elif pixelFormat == b"gray16":
pixelSize = sizeof(c_openni2.Grayscale16Pixel)

self._pixelFormat = pixelFormat
Expand Down Expand Up @@ -422,7 +425,7 @@ cdef _depthMapToPointCloudXYZ(np.ndarray[np.float_t, ndim=3] pointCloud,
c_openni2.convertDepthToWorld(depthStream._stream, x, y, depthMap[y,x],
&worldX, &worldY, &worldZ)
pointCloud[y,x,0] = worldX
pointCloud[y,x,1] = -worldY
pointCloud[y,x,1] = worldY
pointCloud[y,x,2] = worldZ

cdef _depthMapToPointCloudXYZRGB(np.ndarray[np.float_t, ndim=3] pointCloud,
Expand All @@ -442,7 +445,7 @@ cdef _depthMapToPointCloudXYZRGB(np.ndarray[np.float_t, ndim=3] pointCloud,
c_openni2.convertDepthToWorld(depthStream._stream, x, y, depthMap[y,x],
&worldX, &worldY, &worldZ)
pointCloud[y,x,0] = worldX
pointCloud[y,x,1] = -worldY
pointCloud[y,x,1] = worldY
pointCloud[y,x,2] = worldZ
pointCloud[y,x,3] = colorImage[y,x,0]
pointCloud[y,x,4] = colorImage[y,x,1]
Expand All @@ -465,7 +468,7 @@ cdef _depthMapToPointCloudXYZRGB_IR(np.ndarray[np.float_t, ndim=3] pointCloud,
c_openni2.convertDepthToWorld(depthStream._stream, x, y, depthMap[y,x],
&worldX, &worldY, &worldZ)
pointCloud[y,x,0] = worldX
pointCloud[y,x,1] = -worldY
pointCloud[y,x,1] = worldY
pointCloud[y,x,2] = worldZ
pointCloud[y,x,3] = irImage[y,x]
pointCloud[y,x,4] = irImage[y,x]
Expand Down Expand Up @@ -496,6 +499,8 @@ def registerDepthMap(np.ndarray[np.uint16_t, ndim=2] depthMapIn, np.ndarray[np.u

def getAnyDevice():
deviceList = enumerateDevices()
if not deviceList:
raise RuntimeError("No device found")
return Device(deviceList[0]['uri'])

def depthMapToImage(image):
Expand All @@ -519,9 +524,16 @@ def depthMapToPointCloud(depthMap, depthStream, colorImage=None):
raise Exception("Depth and color images must have save dimensions.")

def writePCD(pointCloud, filename, ascii=False):
"""
Stores pointcloud in .pcd format (PCD v0.7)

Format description: http://www.pointclouds.org/documentation/tutorials/pcd_file_format.php
"""

height = pointCloud.shape[0]
width = pointCloud.shape[1]

with open(filename, 'w') as f:
height = pointCloud.shape[0]
width = pointCloud.shape[1]
f.write("# .PCD v.7 - Point Cloud Data file format\n")
f.write("VERSION .7\n")
if pointCloud.shape[2] == 3:
Expand Down Expand Up @@ -576,17 +588,37 @@ def writePCD(pointCloud, filename, ascii=False):
for i, k in enumerate(['x', 'y', 'z']):
pointCloud_tmp[k] = pointCloud[:, :, i].reshape((height*width, 1))
pointCloud_tmp.tofile(f)


def writeOBJ(pointCloud, filename):
"""
Stores pointcloud as geometric vertices in .obj (Wavefront) format

Format description: https://en.wikipedia.org/wiki/Wavefront_.obj_file
This method only represents pointclouds as vertices without w coords
"""

height = pointCloud.shape[0]
width = pointCloud.shape[1]

with open(filename, 'w') as f:
f.write("# Wavefront .obj file format\n")
for row in range(height):
for col in range(width):
if pointCloud.shape[2]== 3:
f.write("v %f %f %f\n" % tuple(pointCloud[row, col, :]))
else:
print("Color not supported")

def readPCD(filename):
with open(filename, 'r') as f:
with open(filename, 'rb') as f:
#"# .PCD v.7 - Point Cloud Data file format\n"
f.readline()

#"VERSION .7\n"
f.readline()

# "FIELDS x y z\n"
fields = f.readline().strip().split()[1:]
fields = [i.decode() for i in f.readline().strip().split()[1:]]

if len(fields) == 3:
rgb = False
Expand All @@ -600,7 +632,7 @@ def readPCD(filename):
pointSize = np.sum(sizes)

#"TYPE F F F\n"
types = f.readline().strip().split()[1:]
types = [i.decode() for i in f.readline().strip().split()[1:]]

#"COUNT 1 1 1\n"
counts = [int(x) for x in f.readline().strip().split()[1:]]
Expand All @@ -612,14 +644,15 @@ def readPCD(filename):
height = int(f.readline().strip().split()[1])

#"VIEWPOINT 0 0 0 1 0 0 0\n"
viewpoint = np.array(f.readline().strip().split()[1:])
bytelist = f.readline().strip().split()[1:]
viewpoint = np.array([int(i) for i in bytelist])

#"POINTS %d\n" % height * width
points = int(f.readline().strip().split()[1])

#"DATA ascii\n"
format = f.readline().strip().split()[1]
ascii = format == 'ascii'
fmt = f.readline().strip().split()[1].decode()
ascii = fmt == 'ascii'

if rgb:
pointCloud = np.empty((height, width, 6))
Expand All @@ -631,13 +664,13 @@ def readPCD(filename):
if ascii:
data = [float(x) for x in f.readline().strip().split()]
else:
data = unpack('ffff', f.read(pointSize))
data = unpack('fff', f.read(pointSize))

pointCloud[row, col, 0] = data[0]
pointCloud[row, col, 1] = data[1]
pointCloud[row, col, 2] = data[2]
if rgb:
rgb_float = data[3]
rgb_float = unpack('f', f.read(1))
packed = pack('f', rgb_float)
rgb_int = unpack('i', packed)[0]
r = rgb_int >> 16 & 0x0000ff
Expand Down
19 changes: 10 additions & 9 deletions examples/cloud.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import cyni
import numpy as np
import Image
from PIL import Image

cyni.initialize()
device = cyni.getAnyDevice()
device.open()
depthStream = device.createStream("depth", fps=30)
colorStream = device.createStream("color", fps=30)
depthStream = device.createStream(b"depth", fps=30)
#colorStream = device.createStream(b"color", fps=30)
depthStream.start()
colorStream.start()
colorFrame = colorStream.readFrame()
#colorStream.start()
#colorFrame = colorStream.readFrame()
depthFrame = depthStream.readFrame()
cloud = cyni.depthMapToPointCloud(depthFrame.data, depthStream, colorFrame.data)
cyni.writePCD(cloud, "cloud.pcd")
readCloud = cyni.readPCD("cloud.pcd")
cyni.writePCD(readCloud, "cloud2.pcd", ascii=True)
cloud = cyni.depthMapToPointCloud(depthFrame.data, depthStream)
#cloud = cyni.depthMapToPointCloud(depthFrame.data, depthStream, colorFrame.data)
cyni.writePCD(cloud, "cloud_bin.pcd")
readCloud = cyni.readPCD("cloud_bin.pcd")
cyni.writePCD(readCloud, "cloud_ascii.pcd", ascii=True)
2 changes: 1 addition & 1 deletion examples/simple.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import cyni
import numpy as np
import Image
from PIL import Image

cyni.initialize()
device = cyni.getAnyDevice()
Expand Down
10 changes: 5 additions & 5 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,25 @@
openni2_lib = os.getenv('OPENNI2_REDIST')

if openni2_include is None or openni2_lib is None:
print """
print("""
Please make sure OPENNI2_INCLUDE and OPENNI2_REDIST are set. You can
source the OpenNIDevEnvironment that the OpenNI2 installer generates to set
these, or you can set them manually. To keep these environment variables
when running with sudo, you can use sudo -E python setup.py install.
"""
""")
sys.exit(1)

has_emitter_control = os.getenv('OPENNI2_HAS_EMITTER_CONTROL', 0)
has_emitter_control = bool(has_emitter_control)
if has_emitter_control:
print "Using emitter control API"
print("Using emitter control API")

class build_ext_with_config(build_ext):
def build_extensions(self):
print 'Generate config.pxi'
print('Generate config.pxi')
filename = os.path.join(os.path.dirname(__file__), 'config.pxi')
with open(filename, 'w') as fd:
for k, v in c_options.iteritems():
for k, v in c_options.items():
fd.write('DEF %s = %d\n' % (k.upper(), int(v)))
build_ext.build_extensions(self)
os.remove(filename)
Expand Down