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 BoundingBox Sensor #136

Merged
merged 37 commits into from
Jun 17, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
9c0f77c
Add BoundingBox Sensor
AmrElsersy Jun 16, 2021
207f3bb
Add Integration Test
AmrElsersy Jun 16, 2021
6429fb9
Edit format 2D boxes
AmrElsersy Jul 15, 2021
8a4ea0d
Add 3D Boxes
AmrElsersy Jul 15, 2021
907302b
Testing 3D
AmrElsersy Jul 15, 2021
026a869
Fix 3D testing
AmrElsersy Jul 16, 2021
f7cecfb
Near/Far plane
AmrElsersy Jul 16, 2021
8a6b5e3
Merge branch 'main' into BoundingBox
adlarkin Jul 18, 2021
79355fb
style
AmrElsersy Jul 22, 2021
f7741e8
Merge branch 'BoundingBox' of https://github.com/AmrElsersy/ign-senso…
AmrElsersy Jul 22, 2021
a5732c4
Merge branch 'main' into BoundingBox
adlarkin Jul 30, 2021
ff5e94a
style
AmrElsersy Aug 5, 2021
cfdece7
Add Tutorial
AmrElsersy Aug 6, 2021
46b0a6e
style
AmrElsersy Aug 16, 2021
ea6dab5
Merge branch 'main' of https://github.com/ignitionrobotics/ign-sensor…
AmrElsersy Aug 16, 2021
d4608e3
Rename integration test files
AmrElsersy Aug 16, 2021
8ec4daf
style
AmrElsersy Aug 16, 2021
f7f43c6
Using RenderingSensor::Render() instead of Capture for rgb camera
AmrElsersy Aug 17, 2021
e48a9d3
style
AmrElsersy Aug 17, 2021
f022c26
Add Save boxes
AmrElsersy Aug 18, 2021
460391d
style
AmrElsersy Aug 18, 2021
182e755
remove lowercasing from type
AmrElsersy Aug 18, 2021
4b8ec6f
solve the unsaving issue when the sensor has no subscribers
AmrElsersy Aug 19, 2021
cb19034
add debug info for advertised topics
adlarkin Aug 26, 2021
21b5d57
Update BoundingBox tutorial
AmrElsersy Aug 26, 2021
6985194
Add dataset generation tutorial
AmrElsersy Aug 26, 2021
06d18ed
add dataset generation gif
AmrElsersy Aug 26, 2021
2dde81c
DirIter instead of filesystem
AmrElsersy Sep 3, 2021
91a5bab
Merge branch 'main' of https://github.com/ignitionrobotics/ign-sensor…
AmrElsersy Sep 22, 2021
ab95793
merged from ign-sensors6
chapulina Jun 2, 2022
80052d2
Update to new API
chapulina Jun 2, 2022
83e6084
clean up member variables, includes, messages...
chapulina Jun 2, 2022
d638a57
tweaks
chapulina Jun 2, 2022
c951ec7
Depend on rendering 6.5
chapulina Jun 15, 2022
6ce248d
codecheck
chapulina Jun 15, 2022
22d5272
Fix test
chapulina Jun 16, 2022
79dd5b3
Disable test on macOS
chapulina Jun 16, 2022
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
23 changes: 13 additions & 10 deletions include/ignition/sensors/BoundingBoxCameraSensor.hh
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
*
*/

#ifndef IGNITION_SENSORS_BOUNDINGBOXCAMERASENSOR2_HH_
#define IGNITION_SENSORS_BOUNDINGBOXCAMERASENSOR2_HH_
#ifndef IGNITION_SENSORS_BOUNDINGBOXCAMERASENSOR_HH_
#define IGNITION_SENSORS_BOUNDINGBOXCAMERASENSOR_HH_

#include <string>
#include <memory>
Expand All @@ -26,16 +26,17 @@
#include <ignition/common/PluginMacros.hh>
#include <ignition/common/SuppressWarning.hh>
#include <ignition/common/Time.hh>
#include <ignition/msgs.hh>
#include <ignition/transport/Node.hh>
#include <ignition/transport/Publisher.hh>
#include <ignition/rendering/BoundingBoxCamera.hh>
AmrElsersy marked this conversation as resolved.
Show resolved Hide resolved

#include "ignition/msgs.hh"
#include "ignition/transport/Node.hh"
#include "ignition/transport/Publisher.hh"

#include "ignition/rendering/BoundingBoxCamera.hh"
#include "ignition/sensors/CameraSensor.hh"
#include "ignition/sensors/Export.hh"
#include "ignition/sensors/Sensor.hh"

#include "ignition/sensors/boundingbox_camera/Export.hh"

namespace ignition
{
namespace sensors
Expand All @@ -52,7 +53,8 @@ namespace ignition
/// It offers both an ignition-transport interface and a direct C++ API
/// to access the image data. The API works by setting a callback to be
/// called with image data.
class BoundingBoxCameraSensor : public CameraSensor
class IGNITION_SENSORS_BOUNDINGBOX_CAMERA_VISIBLE
BoundingBoxCameraSensor : public CameraSensor
{
/// \brief constructor
public: BoundingBoxCameraSensor();
Expand Down Expand Up @@ -82,12 +84,13 @@ namespace ignition

/// \brief Get the rendering BoundingBox camera
/// \return BoundingBox camera pointer
public: virtual rendering::BoundingBoxCameraPtr BoundingBoxCamera();
public: virtual rendering::BoundingBoxCameraPtr
BoundingBoxCamera() const;

/// \brief Callback on new bounding boxes from bounding boxes camera
/// \param[in] _boxes Detected bounding boxes from the camera
public: void OnNewBoundingBoxes(
const std::vector<rendering::BoundingBox> &boxes);
const std::vector<rendering::BoundingBox> &_boxes);

/// \brief Set the rendering scene.
/// \param[in] _scene Pointer to the scene
Expand Down
111 changes: 52 additions & 59 deletions src/BoundingBoxCameraSensor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,20 @@
#include <mutex>
#include <memory>

#include "ignition/common/Console.hh"
#include "ignition/common/Profiler.hh"
#include "ignition/common/Image.hh"
#include <ignition/common/Console.hh>
#include <ignition/common/Profiler.hh>
#include <ignition/common/Image.hh>
#include "ignition/sensors/RenderingEvents.hh"
#include "ignition/sensors/SensorFactory.hh"

#include "ignition/sensors/BoundingBoxCameraSensor.hh"
#include "ignition/rendering/BoundingBoxCamera.hh"

#include "ignition/transport/Node.hh"
#include "ignition/transport/Publisher.hh"
#include "ignition/msgs.hh"
#include <ignition/rendering/BoundingBoxCamera.hh>
#include <ignition/transport/Node.hh>
#include <ignition/transport/Publisher.hh>
#include <ignition/msgs.hh>
AmrElsersy marked this conversation as resolved.
Show resolved Hide resolved


using namespace ignition;
AmrElsersy marked this conversation as resolved.
Show resolved Hide resolved
using namespace sensors;
using namespace rendering;

class ignition::sensors::BoundingBoxCameraSensorPrivate
{
Expand All @@ -49,7 +46,7 @@ class ignition::sensors::BoundingBoxCameraSensorPrivate

/// \brief Rendering RGB Camera to draw boxes on it and publish
/// its image (just for visualization)
public: rendering::CameraPtr camera {nullptr};
public: rendering::CameraPtr rgbCamera {nullptr};

/// \brief Node to create publisher
public: transport::Node node;
Expand All @@ -69,18 +66,14 @@ class ignition::sensors::BoundingBoxCameraSensorPrivate
/// \brief 3D oreinted bounding boxes msg
public: msgs::AnnotatedOriented3DBox_V boxes3DMsg;

/// \brief Topic to publish the BoundingBox image
/// \brief Topic to publish the bounding box msg
public: std::string topicBoundingBoxes = "";

/// \brief Topic to publish the BoundingBox image
/// \brief Topic to publish the image with drawn boxes
public: std::string topicImage = "";

/// \brief True when the sensor published image with drawn boxes
/// False when the sensor publish only the boxes
public: bool IsPublishedImage {false};

/// \brief Buffer contains the BoundingBox map data
public: std::vector<BoundingBox> boundingBoxes;
/// \brief Vector to receive boxes from the rendering camera
public: std::vector<rendering::BoundingBox> boundingBoxes;

/// \brief RGB Image to draw boxes on it
public: rendering::Image image;
Expand All @@ -98,7 +91,8 @@ class ignition::sensors::BoundingBoxCameraSensorPrivate
public: std::mutex mutex;

/// \brief BoundingBoxes type
public: BoundingBoxType type {BoundingBoxType::VisibleBox2D};
public: rendering::BoundingBoxType type
{rendering::BoundingBoxType::VisibleBox2D};
};

//////////////////////////////////////////////////
Expand Down Expand Up @@ -145,12 +139,12 @@ bool BoundingBoxCameraSensor::Load(const sdf::Sensor &_sdf)
});

if (type == "full_2d" || type == "full_box_2d")
this->dataPtr->type = BoundingBoxType::FullBox2D;
this->dataPtr->type = rendering::BoundingBoxType::FullBox2D;
else if (type == "2d" || type == "visible_2d"
|| type == "visible_box_2d")
this->dataPtr->type = BoundingBoxType::VisibleBox2D;
this->dataPtr->type = rendering::BoundingBoxType::VisibleBox2D;
else if (type == "3d")
this->dataPtr->type = BoundingBoxType::Box3D;
this->dataPtr->type = rendering::BoundingBoxType::Box3D;
else
{
ignerr << "Unknown bounding box type " << type << std::endl;
Expand Down Expand Up @@ -187,7 +181,7 @@ bool BoundingBoxCameraSensor::Load(const sdf::Sensor &_sdf)
this->dataPtr->node.Advertise<ignition::msgs::Image>(
this->dataPtr->topicImage);

if (this->dataPtr->type == BoundingBoxType::Box3D)
if (this->dataPtr->type == rendering::BoundingBoxType::Box3D)
{
this->dataPtr->boxesPublisher =
this->dataPtr->node.Advertise<
Expand All @@ -204,14 +198,14 @@ bool BoundingBoxCameraSensor::Load(const sdf::Sensor &_sdf)

if (!this->dataPtr->imagePublisher)
{
ignerr << "Unable to create publisher on topic["
ignerr << "Unable to create publisher on topic ["
<< this->dataPtr->topicImage << "].\n";
return false;
}

if (!this->dataPtr->boxesPublisher)
{
ignerr << "Unable to create publisher on topic["
ignerr << "Unable to create publisher on topic ["
<< this->dataPtr->topicBoundingBoxes << "].\n";
return false;
}
Expand Down Expand Up @@ -244,7 +238,7 @@ void BoundingBoxCameraSensor::SetScene(
if (this->Scene() != _scene)
{
this->dataPtr->boundingboxCamera = nullptr;
this->dataPtr->camera = nullptr;
this->dataPtr->rgbCamera = nullptr;
RenderingSensor::SetScene(_scene);

if (this->dataPtr->initialized)
Expand All @@ -265,51 +259,52 @@ bool BoundingBoxCameraSensor::CreateCamera()
// Camera Info Msg
this->PopulateInfo(sdfCamera);

if (!this->dataPtr->camera)
if (!this->dataPtr->rgbCamera)
{
// Create rendering camera
this->dataPtr->boundingboxCamera =
this->Scene()->CreateBoundingBoxCamera(this->Name());

this->dataPtr->camera = this->Scene()->CreateCamera(
this->dataPtr->rgbCamera = this->Scene()->CreateCamera(
this->Name() + "_rgbCamera");
}

auto width = sdfCamera->ImageWidth();
auto height = sdfCamera->ImageHeight();

// Set Camera Properties
this->dataPtr->camera->SetImageFormat(rendering::PF_R8G8B8);
this->dataPtr->camera->SetImageWidth(width);
this->dataPtr->camera->SetImageHeight(height);
this->dataPtr->camera->SetVisibilityMask(sdfCamera->VisibilityMask());
this->dataPtr->camera->SetNearClipPlane(sdfCamera->NearClip());
this->dataPtr->camera->SetFarClipPlane(sdfCamera->FarClip());
this->dataPtr->camera->SetNearClipPlane(0.01);
this->dataPtr->camera->SetFarClipPlane(1000);
this->dataPtr->rgbCamera->SetImageFormat(rendering::PF_R8G8B8);
this->dataPtr->rgbCamera->SetImageWidth(width);
this->dataPtr->rgbCamera->SetImageHeight(height);
this->dataPtr->rgbCamera->SetVisibilityMask(sdfCamera->VisibilityMask());
this->dataPtr->rgbCamera->SetNearClipPlane(sdfCamera->NearClip());
this->dataPtr->rgbCamera->SetFarClipPlane(sdfCamera->FarClip());
this->dataPtr->rgbCamera->SetNearClipPlane(0.01);
this->dataPtr->rgbCamera->SetFarClipPlane(1000);
AmrElsersy marked this conversation as resolved.
Show resolved Hide resolved
math::Angle angle = sdfCamera->HorizontalFov();
if (angle < 0.01 || angle > IGN_PI*2)
{
ignerr << "Invalid horizontal field of view [" << angle << "]\n";
return false;
}
double aspectRatio = static_cast<double>(width)/height;
this->dataPtr->camera->SetAspectRatio(aspectRatio);
this->dataPtr->camera->SetHFOV(angle);
this->dataPtr->rgbCamera->SetAspectRatio(aspectRatio);
this->dataPtr->rgbCamera->SetHFOV(angle);

this->dataPtr->boundingboxCamera->SetImageWidth(width);
this->dataPtr->boundingboxCamera->SetImageHeight(height);
this->dataPtr->boundingboxCamera->SetNearClipPlane(sdfCamera->NearClip());
this->dataPtr->boundingboxCamera->SetFarClipPlane(sdfCamera->FarClip());
this->dataPtr->boundingboxCamera->SetImageFormat(PixelFormat::PF_R8G8B8);
this->dataPtr->boundingboxCamera->SetImageFormat(
rendering::PixelFormat::PF_R8G8B8);
this->dataPtr->boundingboxCamera->SetAspectRatio(aspectRatio);
this->dataPtr->boundingboxCamera->SetHFOV(angle);
this->dataPtr->boundingboxCamera->SetVisibilityMask(
sdfCamera->VisibilityMask());
this->dataPtr->boundingboxCamera->SetBoundingBoxType(this->dataPtr->type);

// Add the camera to the scene
this->Scene()->RootVisual()->AddChild(this->dataPtr->camera);
this->Scene()->RootVisual()->AddChild(this->dataPtr->rgbCamera);
this->Scene()->RootVisual()->AddChild(this->dataPtr->boundingboxCamera);

// Add the rendering sensor to handle its render, no need to add the
Expand All @@ -322,13 +317,14 @@ bool BoundingBoxCameraSensor::CreateCamera()
std::bind(&BoundingBoxCameraSensor::OnNewBoundingBoxes, this,
std::placeholders::_1));

this->dataPtr->image = this->dataPtr->camera->CreateImage();
this->dataPtr->image = this->dataPtr->rgbCamera->CreateImage();

return true;
}

/////////////////////////////////////////////////
rendering::BoundingBoxCameraPtr BoundingBoxCameraSensor::BoundingBoxCamera()
rendering::BoundingBoxCameraPtr
BoundingBoxCameraSensor::BoundingBoxCamera() const
{
return this->dataPtr->boundingboxCamera;
}
Expand All @@ -339,7 +335,7 @@ void BoundingBoxCameraSensor::OnNewBoundingBoxes(
{
std::lock_guard<std::mutex> lock(this->dataPtr->mutex);
this->dataPtr->boundingBoxes.clear();
for (auto box : boxes)
for (const auto &box : boxes)
this->dataPtr->boundingBoxes.push_back(box);
}

Expand All @@ -354,7 +350,7 @@ bool BoundingBoxCameraSensor::Update(
return false;
}

if (!this->dataPtr->boundingboxCamera || !this->dataPtr->camera)
if (!this->dataPtr->boundingboxCamera || !this->dataPtr->rgbCamera)
{
ignerr << "Camera doesn't exist.\n";
return false;
Expand All @@ -371,18 +367,15 @@ bool BoundingBoxCameraSensor::Update(
this->Render();

// Publish image only if there is subscribers for it
this->dataPtr->IsPublishedImage =
this->dataPtr->imagePublisher.HasConnections();

if (this->dataPtr->IsPublishedImage)
if (this->dataPtr->imagePublisher.HasConnections())
{
// The sensor updates only the bounding box camera with its pose
// as it has the same name, so make rgb camera with the same pose
this->dataPtr->camera->SetWorldPose(
this->dataPtr->rgbCamera->SetWorldPose(
this->dataPtr->boundingboxCamera->WorldPose());

// Render the rgb camera
this->dataPtr->camera->Capture(this->dataPtr->image);
this->dataPtr->rgbCamera->Capture(this->dataPtr->image);

// Draw bounding boxes
for (auto box : this->dataPtr->boundingBoxes)
AmrElsersy marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -393,8 +386,8 @@ bool BoundingBoxCameraSensor::Update(
this->dataPtr->imageBuffer, box);
}

auto width = this->dataPtr->camera->ImageWidth();
auto height = this->dataPtr->camera->ImageHeight();
auto width = this->dataPtr->rgbCamera->ImageWidth();
auto height = this->dataPtr->rgbCamera->ImageHeight();

// Create Image message
this->dataPtr->imageMsg.set_width(width);
Expand All @@ -420,12 +413,12 @@ bool BoundingBoxCameraSensor::Update(
this->dataPtr->imagePublisher.Publish(this->dataPtr->imageMsg);
}

if (this->dataPtr->type == BoundingBoxType::Box3D)
if (this->dataPtr->type == rendering::BoundingBoxType::Box3D)
{
this->dataPtr->boxes3DMsg.Clear();

// Create 3D boxes message
for (auto box : this->dataPtr->boundingBoxes)
for (const auto &box : this->dataPtr->boundingBoxes)
{
// box data
auto annotated_box = this->dataPtr->boxes3DMsg.add_annotated_box();
Expand Down Expand Up @@ -468,7 +461,7 @@ bool BoundingBoxCameraSensor::Update(
this->dataPtr->boxes2DMsg.Clear();

// Create 2D boxes message
for (auto box : this->dataPtr->boundingBoxes)
for (const auto &box : this->dataPtr->boundingBoxes)
{
// box data
auto annotated_box = this->dataPtr->boxes2DMsg.add_annotated_box();
Expand Down Expand Up @@ -501,7 +494,7 @@ bool BoundingBoxCameraSensor::Update(

// Publish
this->PublishInfo(_now);
if (this->dataPtr->type == BoundingBoxType::Box3D)
if (this->dataPtr->type == rendering::BoundingBoxType::Box3D)
{
this->AddSequence(
this->dataPtr->boxes3DMsg.mutable_header(), "boundingboxes");
Expand All @@ -520,13 +513,13 @@ bool BoundingBoxCameraSensor::Update(
/////////////////////////////////////////////////
unsigned int BoundingBoxCameraSensor::ImageHeight() const
{
return this->dataPtr->camera->ImageHeight();
return this->dataPtr->rgbCamera->ImageHeight();
}

/////////////////////////////////////////////////
unsigned int BoundingBoxCameraSensor::ImageWidth() const
{
return this->dataPtr->camera->ImageWidth();
return this->dataPtr->rgbCamera->ImageWidth();
}

IGN_SENSORS_REGISTER_SENSOR(BoundingBoxCameraSensor)
2 changes: 1 addition & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ target_link_libraries(${boundingbox_camera_target}
${camera_target}
ignition-msgs${IGN_MSGS_VER}::ignition-msgs${IGN_MSGS_VER}
ignition-transport${IGN_TRANSPORT_VER}::ignition-transport${IGN_TRANSPORT_VER}
)
)

# Build the unit tests.
ign_build_tests(TYPE UNIT SOURCES ${gtest_sources} LIB_DEPS ${rendering_target})
Expand Down