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

Add segmentation and bounding box sensor types #592

Merged
merged 16 commits into from
Aug 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions include/sdf/Camera.hh
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,40 @@ namespace sdf
/// \param[in] _far The far clip distance.
public: void SetFarClip(double _far);

/// \brief Set whether the segmentation type has been specified.
/// \param[in] _type True if the segmentation type
/// has been set in the sdf.
public: void SetHasSegmentationType(bool _type);

/// \brief Get whether the segmentation type was set.
/// \return True if the segmentation type was set.
public: bool HasSegmentationType() const;

/// \brief Get the segmentation type.
/// \return The segmentation type.
public: const std::string &SegmentationType() const;

/// \brief Set the segmentation type.
/// \param[in] _type The segmentation type.
public: void SetSegmentationType(const std::string &_type);

/// \brief Set whether the boundingbox type has been specified.
/// \param[in] _type True if the boundingbox type
/// has been set in the sdf.
public: void SetHasBoundingBoxType(bool _type);

/// \brief Get whether the boundingbox type was set.
/// \return True if the boundingbox type was set.
public: bool HasBoundingBoxType() const;

/// \brief Get the boundingbox type.
/// \return The boundingbox type.
public: const std::string &BoundingBoxType() const;

/// \brief Set the boundingbox type.
/// \param[in] _type The boundingbox type.
public: void SetBoundingBoxType(const std::string &_type);

/// \brief Get whether frames should be saved.
/// \return True if image frames should be saved.
public: bool SaveFrames() const;
Expand Down
8 changes: 7 additions & 1 deletion include/sdf/Sensor.hh
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,14 @@ namespace sdf
/// \brief A thermal camera sensor
THERMAL_CAMERA = 20,

/// \brief A segmentation camera sensor
SEGMENTATION_CAMERA = 21,

/// \brief A boundingbox camera sensor
BOUNDINGBOX_CAMERA = 22,

/// \brief A custom sensor
CUSTOM = 21
CUSTOM = 23
};

/// \brief Information about an SDF sensor.
Expand Down
27 changes: 27 additions & 0 deletions sdf/1.9/camera.sdf
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,33 @@
</element>
</element> <!-- End depth_camera -->

<element name="segmentation_type" type="string" default="semantic" required="0">
<description>
The segmentation type of the segmentation camera. Valid options are:
- semantic: Semantic segmentation, which provides 2 images:
1. A grayscale image, with the pixel values representing the label of an object
2. A colored image, with the pixel values being a unique color for each label

- panoptic | instance: Panoptic segmentation, which provides an image where each pixel
has 1 channel for label value of the object and 2 channels for the
number of the instances of that label, and a colored image which its
pixels have a unique color for each instance.
</description>
</element> <!-- End segmentation_type -->

<element name="box_type" type="string" default="2d" required="0">
<description>
The boundingbox type of the boundingbox camera. Valid options are:
- 2d | visible_2d | visible_box_2d: a visible 2d box mode which provides axis aligned 2d boxes
on the visible parts of the objects

- full_2d | full_box_2d: a full 2d box mode which provides axis aligned 2d boxes that fills the
object dimentions, even if it has an occluded part

- 3d: a 3d mode which provides oriented 3d boxes
</description>
</element> <!-- End box_type -->

<element name="noise" required="0">
<description>The properties of the noise model that should be applied to generated images</description>
<element name="type" type="string" default="gaussian" required="1">
Expand Down
2 changes: 2 additions & 0 deletions sdf/1.9/sensor.sdf
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
altimeter,
camera,
contact,
boundingbox_camera, boundingbox,
custom,
depth_camera, depth,
force_torque,
Expand All @@ -27,6 +28,7 @@
rfid,
rfidtag,
rgbd_camera, rgbd,
segmentation_camera, segmentation,
sonar,
thermal_camera, thermal,
wireless_receiver, and
Expand Down
72 changes: 72 additions & 0 deletions src/Camera.cc
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@ class sdf::Camera::Implementation
/// \brief Far clip distance for depth camera.
public: double depthFarClip{10.0};

/// \brief Segmentation type for segmentation camera.
public: std::string segmentationType{"semantic"};

/// \brief Boundingbox type for boundingbox camera.
public: std::string boundingBoxType{"2d"};

/// \brief True indicates the depth camera was set.
public: bool hasDepthCamera{false};

Expand All @@ -87,6 +93,12 @@ class sdf::Camera::Implementation
/// \brief True indicates the depth camera near clip distance was set.
public: bool hasDepthNearClip{false};

/// \brief True indicates the segmentation type was set.
public: bool hasSegmentationType{false};

/// \brief True indicates the boundingobx type was set.
public: bool hasBoundingBoxType{false};

/// \brief True indicates frames should be saved.
public: bool save{false};

Expand Down Expand Up @@ -277,6 +289,16 @@ Errors Camera::Load(ElementPtr _sdf)
"Camera sensor is missing a <clip> element."});
}

if (_sdf->HasElement("segmentation_type"))
{
this->SetSegmentationType(_sdf->Get<std::string>("segmentation_type"));
}

if (_sdf->HasElement("box_type"))
{
this->SetBoundingBoxType(_sdf->Get<std::string>("box_type"));
}

if (_sdf->HasElement("save"))
{
sdf::ElementPtr elem = _sdf->GetElement("save");
Expand Down Expand Up @@ -485,6 +507,56 @@ void Camera::SetFarClip(double _far)
this->dataPtr->farClip = _far;
}

//////////////////////////////////////////////////
const std::string &Camera::SegmentationType() const
{
return this->dataPtr->segmentationType;
}

//////////////////////////////////////////////////
void Camera::SetSegmentationType(const std::string &_type)
{
this->dataPtr->hasSegmentationType = true;
this->dataPtr->segmentationType = _type;
}

//////////////////////////////////////////////////
void Camera::SetHasSegmentationType(bool _type)
{
this->dataPtr->hasSegmentationType = _type;
}

//////////////////////////////////////////////////
bool Camera::HasSegmentationType() const
{
return this->dataPtr->hasSegmentationType;
}

//////////////////////////////////////////////////
const std::string &Camera::BoundingBoxType() const
{
return this->dataPtr->boundingBoxType;
}

//////////////////////////////////////////////////
void Camera::SetBoundingBoxType(const std::string &_type)
{
this->dataPtr->hasBoundingBoxType = true;
this->dataPtr->boundingBoxType = _type;
}

//////////////////////////////////////////////////
void Camera::SetHasBoundingBoxType(bool _type)
{
this->dataPtr->hasBoundingBoxType = _type;
}

//////////////////////////////////////////////////
bool Camera::HasBoundingBoxType() const
{
return this->dataPtr->hasBoundingBoxType;
}

//////////////////////////////////////////////////
void Camera::SetHasDepthCamera(bool _camera)
{
Expand Down
16 changes: 16 additions & 0 deletions src/Camera_TEST.cc
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,22 @@ TEST(DOMCamera, Construction)
cam.SetFarClip(200.2);
EXPECT_DOUBLE_EQ(200.2, cam.FarClip());

EXPECT_EQ("semantic", cam.SegmentationType());
EXPECT_FALSE(cam.HasSegmentationType());
cam.SetSegmentationType("panoptic");
EXPECT_TRUE(cam.HasSegmentationType());
EXPECT_EQ("panoptic", cam.SegmentationType());
cam.SetHasSegmentationType(false);
EXPECT_FALSE(cam.HasSegmentationType());

EXPECT_EQ("2d", cam.BoundingBoxType());
EXPECT_FALSE(cam.HasBoundingBoxType());
cam.SetBoundingBoxType("3d");
AmrElsersy marked this conversation as resolved.
Show resolved Hide resolved
EXPECT_TRUE(cam.HasBoundingBoxType());
EXPECT_EQ("3d", cam.BoundingBoxType());
cam.SetHasBoundingBoxType(false);
EXPECT_FALSE(cam.HasBoundingBoxType());

EXPECT_FALSE(cam.SaveFrames());
cam.SetSaveFrames(true);
EXPECT_TRUE(cam.SaveFrames());
Expand Down
18 changes: 18 additions & 0 deletions src/Sensor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ const std::vector<std::string> sensorTypeStrs =
"air_pressure",
"rgbd_camera",
"thermal_camera",
"segmentation_camera",
"boundingbox_camera",
"custom"
};

Expand Down Expand Up @@ -156,6 +158,8 @@ bool Sensor::operator==(const Sensor &_sensor) const
case SensorType::DEPTH_CAMERA:
case SensorType::RGBD_CAMERA:
case SensorType::THERMAL_CAMERA:
case SensorType::SEGMENTATION_CAMERA:
case SensorType::BOUNDINGBOX_CAMERA:
return *(this->dataPtr->camera) == *(_sensor.dataPtr->camera);
case SensorType::LIDAR:
return *(this->dataPtr->lidar) == *(_sensor.dataPtr->lidar);
Expand Down Expand Up @@ -271,6 +275,20 @@ Errors Sensor::Load(ElementPtr _sdf)
Errors err = this->dataPtr->camera->Load(_sdf->GetElement("camera"));
errors.insert(errors.end(), err.begin(), err.end());
}
else if (type == "segmentation" || type == "segmentation_camera")
{
this->dataPtr->type = SensorType::SEGMENTATION_CAMERA;
this->dataPtr->camera.emplace();
Errors err = this->dataPtr->camera->Load(_sdf->GetElement("camera"));
errors.insert(errors.end(), err.begin(), err.end());
}
else if (type == "boundingbox" || type == "boundingbox_camera")
{
this->dataPtr->type = SensorType::BOUNDINGBOX_CAMERA;
this->dataPtr->camera.emplace();
Errors err = this->dataPtr->camera->Load(_sdf->GetElement("camera"));
errors.insert(errors.end(), err.begin(), err.end());
}
else if (type == "force_torque")
{
this->dataPtr->type = SensorType::FORCE_TORQUE;
Expand Down
4 changes: 4 additions & 0 deletions src/Sensor_TEST.cc
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ TEST(DOMSensor, Type)
std::vector<sdf::SensorType> types = {
sdf::SensorType::NONE,
sdf::SensorType::ALTIMETER,
sdf::SensorType::BOUNDINGBOX_CAMERA,
sdf::SensorType::CAMERA,
sdf::SensorType::CONTACT,
sdf::SensorType::DEPTH_CAMERA,
Expand All @@ -256,6 +257,7 @@ TEST(DOMSensor, Type)
sdf::SensorType::LIDAR,
sdf::SensorType::RFID,
sdf::SensorType::RFIDTAG,
sdf::SensorType::SEGMENTATION_CAMERA,
sdf::SensorType::SONAR,
sdf::SensorType::WIRELESS_RECEIVER,
sdf::SensorType::WIRELESS_TRANSMITTER,
Expand All @@ -266,6 +268,7 @@ TEST(DOMSensor, Type)
{
"none",
"altimeter",
"boundingbox_camera",
"camera",
"contact",
"depth_camera",
Expand All @@ -279,6 +282,7 @@ TEST(DOMSensor, Type)
"lidar",
"rfid",
"rfidtag",
"segmentation_camera",
"sonar",
"wireless_receiver",
"wireless_transmitter",
Expand Down
31 changes: 30 additions & 1 deletion test/integration/link_dom.cc
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ TEST(DOMLink, Sensors)
const sdf::Link *link = model->LinkByIndex(0);
ASSERT_NE(nullptr, link);
EXPECT_EQ("link", link->Name());
EXPECT_EQ(23u, link->SensorCount());
EXPECT_EQ(25u, link->SensorCount());

// Get the altimeter sensor
const sdf::Sensor *altimeterSensor = link->SensorByIndex(0);
Expand Down Expand Up @@ -358,6 +358,35 @@ TEST(DOMLink, Sensors)
ASSERT_NE(nullptr, thermalCamSensor);
EXPECT_EQ("my_thermal_camera", thermalCamSensor->Name());

// Get the segmentation sensor
const sdf::Sensor *segmentationSensor =
link->SensorByName("segmentation_sensor");
ASSERT_NE(nullptr, segmentationSensor);
EXPECT_EQ("segmentation_sensor", segmentationSensor->Name());
EXPECT_EQ(sdf::SensorType::SEGMENTATION_CAMERA, segmentationSensor->Type());
EXPECT_EQ(ignition::math::Pose3d(37, 38, 39, 0, 0, 0),
segmentationSensor->RawPose());
const sdf::Camera *segmentationCameraSensor =
segmentationSensor->CameraSensor();
ASSERT_NE(nullptr, segmentationCameraSensor);
EXPECT_EQ("my_segmentation_camera", segmentationCameraSensor->Name());
AmrElsersy marked this conversation as resolved.
Show resolved Hide resolved
AmrElsersy marked this conversation as resolved.
Show resolved Hide resolved
EXPECT_TRUE(segmentationCameraSensor->HasSegmentationType());
EXPECT_EQ("semantic", segmentationCameraSensor->SegmentationType());

// Get the boundingbox sensor
const sdf::Sensor *boundingboxSensor =
link->SensorByName("boundingbox_sensor");
ASSERT_NE(nullptr, boundingboxSensor);
EXPECT_EQ("boundingbox_sensor", boundingboxSensor->Name());
EXPECT_EQ(sdf::SensorType::BOUNDINGBOX_CAMERA, boundingboxSensor->Type());
EXPECT_EQ(ignition::math::Pose3d(37, 38, 39, 0, 0, 0),
boundingboxSensor->RawPose());
const sdf::Camera *boundingboxCamSensor = boundingboxSensor->CameraSensor();
ASSERT_NE(nullptr, boundingboxCamSensor);
EXPECT_EQ("my_boundingbox_camera", boundingboxCamSensor->Name());
AmrElsersy marked this conversation as resolved.
Show resolved Hide resolved
AmrElsersy marked this conversation as resolved.
Show resolved Hide resolved
EXPECT_TRUE(boundingboxCamSensor->HasBoundingBoxType());
EXPECT_EQ("2d", boundingboxCamSensor->BoundingBoxType());

// Get the force_torque sensor
const sdf::Sensor *forceTorqueSensor =
link->SensorByName("force_torque_sensor");
Expand Down
Loading