Skip to content

Commit

Permalink
Merge pull request #193 from agri-gaia/feat/fb-point-cloud-cleaned-up
Browse files Browse the repository at this point in the history
add support for point clouds over flatbuffers
  • Loading branch information
Mark-Niemeyer authored Oct 24, 2022
2 parents 79ea0c7 + c44fd92 commit e9c0642
Show file tree
Hide file tree
Showing 39 changed files with 2,333 additions and 99 deletions.
90 changes: 90 additions & 0 deletions examples/python/gRPC/pointcloud/gRPC_fb_queryPointCloud.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import os
import struct
import sys

import flatbuffers
import numpy as np

np.set_printoptions(precision=7)
from fb import point_cloud_service_grpc_fb as pointCloudService
from fb.PointCloud2 import PointCloud2

script_dir = os.path.dirname(__file__)
util_dir = os.path.join(script_dir, '..')
sys.path.append(util_dir)
import util
import util_fb

channel = util.get_gRPC_channel()

stubPointCloud = pointCloudService.PointCloudServiceStub(channel)
builder = flatbuffers.Builder(1024)

PROJECTNAME = "testproject"
projectUuid = util_fb.getProject(builder, channel, PROJECTNAME)

if projectUuid is None:
print(f"Project: {PROJECTNAME} does not exist")
sys.exit()


builder = flatbuffers.Builder(1024)

timeMin = util_fb.createTimeStamp(builder, 1610549273, 0)
timeMax = util_fb.createTimeStamp(builder, 1938549273, 0)
timeInterval = util_fb.createTimeInterval(builder, timeMin, timeMax)

queryMsg = util_fb.createQuery(
builder,
projectUuids=[builder.CreateString(projectUuid)],
timeInterval=timeInterval,
labels=[builder.CreateString("BoundingBoxLabel0")],
)
builder.Finish(queryMsg)
buf = builder.Output()

for responseBuf in stubPointCloud.GetPointCloud2(bytes(buf)):
response = PointCloud2.GetRootAs(responseBuf)

print("---Header---")
print(f"Message UUID: {response.Header().UuidMsgs().decode('utf-8')}")
print(f"Project UUID: {response.Header().UuidProject().decode('utf-8')}")
print(f"Frame ID: {response.Header().FrameId().decode('utf-8')}")

print("---Point Fields---")
for i in range(response.FieldsLength()):
print(f"Field Name: {response.Fields(i).Name().decode('utf-8')}")
print(f"Datatype: {response.Fields(i).Datatype()}")
print(f"Offset: {response.Fields(i).Offset()}")
print(f"Count: {response.Fields(i).Count()}")

print("---Bounding Box Labels---")
for i in range(response.LabelsBbLength()):
print(f"Label {i}: {response.LabelsBb(i).LabelWithInstance().Label().decode('utf-8')}")
print(f"Instance {i}: {response.LabelsBb(i).LabelWithInstance().InstanceUuid().decode('utf-8')}")
print(
f"Bounding Box Min {i}: "
f"{response.LabelsBb(i).BoundingBox().PointMin().X()},"
f"{response.LabelsBb(i).BoundingBox().PointMin().Y()},"
f"{response.LabelsBb(i).BoundingBox().PointMin().Z()} "
f"(x,y,z)"
)
print(
f"Bounding Box Max {i}: "
f"{response.LabelsBb(i).BoundingBox().PointMax().X()},"
f"{response.LabelsBb(i).BoundingBox().PointMax().Y()},"
f"{response.LabelsBb(i).BoundingBox().PointMax().Z()} "
f"(x,y,z)"
)

print("---General Labels----")
for i in range(response.LabelsGeneralLength()):
print(f"Label {i}: {response.LabelsGeneral(i).Label().decode('utf-8')}")
print(f"Instance {i}: {response.LabelsGeneral(i).InstanceUuid().decode('utf-8')}")

print("---Data--")
if not response.DataIsNone():
rawData = response.DataAsNumpy()
data = [struct.unpack('f', rawData[i : i + 4]) for i in range(0, rawData.shape[0], 4)]
reshapedData = np.array(data).reshape(960, 1280, 4)
print(f"Data: {reshapedData}")
109 changes: 109 additions & 0 deletions examples/python/gRPC/pointcloud/gRPC_fb_sendPointCloud.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
#!/user/bin/env python3

import os
import sys
import time
import uuid

import flatbuffers
import numpy as np

np.set_printoptions(precision=7)
from fb import PointCloud2
from fb import point_cloud_service_grpc_fb as pointCloudService

script_dir = os.path.dirname(__file__)
util_dir = os.path.join(script_dir, '..')
sys.path.append(util_dir)

import util
from util_fb import (
addToBoundingBoxLabeledVector,
addToGeneralLabelsVector,
addToPointFieldVector,
createBoundingBoxes,
createBoundingBoxesLabeled,
createHeader,
createLabelsWithInstance,
createPoint,
createPointFields,
createTimeStamp,
getOrCreateProject,
)

NUM_GENERAL_LABELS = 1
NUM_BB_LABELS = 1
NUM_POINT_CLOUDS = 1


def createPointCloud(builder, header, height=960, width=1280):
'''Creates a flatbuffers point cloud message'''
pointFields = createPointFields(builder, ['x', 'y', 'z', 'rgba'], 7, 4, 1)
pointFieldsVector = addToPointFieldVector(builder, pointFields)

# create general labels
labelsGeneral = createLabelsWithInstance(
builder,
["GeneralLabel" + str(i) for i in range(NUM_GENERAL_LABELS)],
[str(uuid.uuid4()) for _ in range(NUM_GENERAL_LABELS)],
)
labelsGeneralVector = addToGeneralLabelsVector(builder, labelsGeneral)

# create bounding box labels
boundingBoxes = createBoundingBoxes(
builder,
header,
[createPoint(builder, np.random.rand(), np.random.rand(), np.random.rand()) for _ in range(NUM_BB_LABELS)],
[createPoint(builder, np.random.rand(), np.random.rand(), np.random.rand()) for _ in range(NUM_BB_LABELS)],
)
labelWithInstances = createLabelsWithInstance(
builder,
["BoundingBoxLabel" + str(i) for i in range(NUM_BB_LABELS)],
[str(uuid.uuid4()) for _ in range(NUM_BB_LABELS)],
)
labelsBb = createBoundingBoxesLabeled(builder, labelWithInstances, boundingBoxes)
labelsBbVector = addToBoundingBoxLabeledVector(builder, labelsBb)

# Note: rgb field is float, for simplification
points = np.random.randn(height, width, 4).astype(np.float32)
print(f"Data: {points}")

pointsVector = builder.CreateByteVector(points.tobytes())

# add all data into the flatbuffers point cloud message
PointCloud2.Start(builder)
PointCloud2.AddHeader(builder, header)
PointCloud2.AddHeight(builder, points.shape[0])
PointCloud2.AddWidth(builder, points.shape[1])
PointCloud2.AddIsBigendian(builder, True)
PointCloud2.AddPointStep(builder, 16)
PointCloud2.AddRowStep(builder, points.shape[1] * 16)
PointCloud2.AddFields(builder, pointFieldsVector)
PointCloud2.AddData(builder, pointsVector)
PointCloud2.AddLabelsGeneral(builder, labelsGeneralVector)
PointCloud2.AddLabelsBb(builder, labelsBbVector)
return PointCloud2.End(builder)


def createPointClouds(projectUuid, numOf):
'''Creates numOf pointcloud2 messages as a generator function'''
theTime = int(time.time())
for i in range(numOf):
print(f"Send point cloud: {str(i+1)}")
builder = flatbuffers.Builder(1024)

timeStamp = createTimeStamp(builder, theTime + i)
header = createHeader(builder, timeStamp, "map", projectUuid)

pointCloudMsg = createPointCloud(builder, header)
builder.Finish(pointCloudMsg)
yield bytes(builder.Output())


channel = util.get_gRPC_channel()
stub = pointCloudService.PointCloudServiceStub(channel)
builder = flatbuffers.Builder(1024)

projectUuid = getOrCreateProject(builder, channel, "testproject")

responseBuf = stub.TransferPointCloud2(createPointClouds(projectUuid, NUM_POINT_CLOUDS))
7 changes: 6 additions & 1 deletion examples/python/gRPC/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ def get_gRPC_channel(target="local"):
elif target == "local":
# server without certs
server = "localhost:9090"
channel = grpc.insecure_channel(server)
# set the max message size to 1GB (half the size of the server)
options = [
('grpc.max_send_message_length', 1 * 1024 * 1024 * 1024),
('grpc.max_receive_message_length', 1 * 1024 * 1024 * 1024),
]
channel = grpc.insecure_channel(server, options=options)

return channel
Loading

0 comments on commit e9c0642

Please sign in to comment.