diff --git a/include/sdf/Camera.hh b/include/sdf/Camera.hh index 5beed486b..054822323 100644 --- a/include/sdf/Camera.hh +++ b/include/sdf/Camera.hh @@ -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; diff --git a/include/sdf/Sensor.hh b/include/sdf/Sensor.hh index 1fa136872..205fa619c 100644 --- a/include/sdf/Sensor.hh +++ b/include/sdf/Sensor.hh @@ -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. diff --git a/sdf/1.9/camera.sdf b/sdf/1.9/camera.sdf index 1e46ff484..67633cca2 100644 --- a/sdf/1.9/camera.sdf +++ b/sdf/1.9/camera.sdf @@ -62,6 +62,33 @@ + + + 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. + + + + + + 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 + + + The properties of the noise model that should be applied to generated images diff --git a/sdf/1.9/sensor.sdf b/sdf/1.9/sensor.sdf index 080aeb430..f16b8c13c 100644 --- a/sdf/1.9/sensor.sdf +++ b/sdf/1.9/sensor.sdf @@ -12,6 +12,7 @@ altimeter, camera, contact, + boundingbox_camera, boundingbox, custom, depth_camera, depth, force_torque, @@ -27,6 +28,7 @@ rfid, rfidtag, rgbd_camera, rgbd, + segmentation_camera, segmentation, sonar, thermal_camera, thermal, wireless_receiver, and diff --git a/src/Camera.cc b/src/Camera.cc index a70af2f7e..027575e35 100644 --- a/src/Camera.cc +++ b/src/Camera.cc @@ -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}; @@ -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}; @@ -277,6 +289,16 @@ Errors Camera::Load(ElementPtr _sdf) "Camera sensor is missing a element."}); } + if (_sdf->HasElement("segmentation_type")) + { + this->SetSegmentationType(_sdf->Get("segmentation_type")); + } + + if (_sdf->HasElement("box_type")) + { + this->SetBoundingBoxType(_sdf->Get("box_type")); + } + if (_sdf->HasElement("save")) { sdf::ElementPtr elem = _sdf->GetElement("save"); @@ -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) { diff --git a/src/Camera_TEST.cc b/src/Camera_TEST.cc index 765f4d0b2..f624315b2 100644 --- a/src/Camera_TEST.cc +++ b/src/Camera_TEST.cc @@ -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"); + 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()); diff --git a/src/Sensor.cc b/src/Sensor.cc index bc6651351..4f2898e2e 100644 --- a/src/Sensor.cc +++ b/src/Sensor.cc @@ -60,6 +60,8 @@ const std::vector sensorTypeStrs = "air_pressure", "rgbd_camera", "thermal_camera", + "segmentation_camera", + "boundingbox_camera", "custom" }; @@ -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); @@ -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; diff --git a/src/Sensor_TEST.cc b/src/Sensor_TEST.cc index f7bf9313b..51acf6e99 100644 --- a/src/Sensor_TEST.cc +++ b/src/Sensor_TEST.cc @@ -243,6 +243,7 @@ TEST(DOMSensor, Type) std::vector types = { sdf::SensorType::NONE, sdf::SensorType::ALTIMETER, + sdf::SensorType::BOUNDINGBOX_CAMERA, sdf::SensorType::CAMERA, sdf::SensorType::CONTACT, sdf::SensorType::DEPTH_CAMERA, @@ -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, @@ -266,6 +268,7 @@ TEST(DOMSensor, Type) { "none", "altimeter", + "boundingbox_camera", "camera", "contact", "depth_camera", @@ -279,6 +282,7 @@ TEST(DOMSensor, Type) "lidar", "rfid", "rfidtag", + "segmentation_camera", "sonar", "wireless_receiver", "wireless_transmitter", diff --git a/test/integration/link_dom.cc b/test/integration/link_dom.cc index 8aad28c8b..5815bfa5d 100644 --- a/test/integration/link_dom.cc +++ b/test/integration/link_dom.cc @@ -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); @@ -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()); + 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()); + EXPECT_TRUE(boundingboxCamSensor->HasBoundingBoxType()); + EXPECT_EQ("2d", boundingboxCamSensor->BoundingBoxType()); + // Get the force_torque sensor const sdf::Sensor *forceTorqueSensor = link->SensorByName("force_torque_sensor"); diff --git a/test/sdf/sensors.sdf b/test/sdf/sensors.sdf index c09bb9f50..ac7d7bbff 100644 --- a/test/sdf/sensors.sdf +++ b/test/sdf/sensors.sdf @@ -440,6 +440,122 @@ + + 37 38 39 0 0 0 + + semantic + 0.1 0.2 0.3 0 0 0 + .75 + + 640 + 480 + R8G8B8 + + + 0.2 + 12.3 + + + + /tmp/cam + + + + gaussian + 0.5 + 0.1 + + + + 0.1 + 0.2 + 0.3 + 0.4 + 0.5 +
0.2 0.4
+
+ + custom + false + + 1.1 + 2.2 + 3.3 + 1.2 + sin + + 0.7505 + 128 + + 280 + 281 + 162 + 124 + 1.2 + + +
+ +
+ + + 37 38 39 0 0 0 + + 2d + 0.1 0.2 0.3 0 0 0 + .75 + + 640 + 480 + R8G8B8 + + + 0.2 + 12.3 + + + + /tmp/cam + + + + gaussian + 0.5 + 0.1 + + + + 0.1 + 0.2 + 0.3 + 0.4 + 0.5 +
0.2 0.4
+
+ + custom + false + + 1.1 + 2.2 + 3.3 + 1.2 + sin + + 0.7505 + 128 + + 280 + 281 + 162 + 124 + 1.2 + + +
+ +
+ 13 14 15 0 0 0