RobotsIO
Loading...
Searching...
No Matches
SegmentationCamera.cpp
1/*
2 * Copyright (C) 2020 Istituto Italiano di Tecnologia (IIT)
3 *
4 * This software may be modified and distributed under the terms of the
5 * BSD 3-Clause license. See the accompanying LICENSE file for details.
6 */
7
8#include <RobotsIO/Camera/SegmentationCamera.h>
9#include <RobotsIO/Camera/CameraParameters.h>
10
11#include <Eigen/Dense>
12
13using namespace RobotsIO::Camera;
14using namespace Eigen;
15
16
17SegmentationCamera::SegmentationCamera(const CameraParameters& camera_parameters, const std::string& object_mesh_path, const double& threshold) :
18 parameters_(camera_parameters),
19 threshold_(threshold)
20{
21 /* Configure renderer. */
22 SICAD::ModelPathContainer model;
23 model["object"] = object_mesh_path;
24 renderer_ = std::unique_ptr<SICAD>
25 (
26 new SICAD(model, parameters_.width(), parameters_.height(), parameters_.fx(), parameters_.fy(), parameters_.cx(), parameters_.cy(), 1)
27 );
28 renderer_->setOglToCam({1.0, 0.0, 0.0, static_cast<float>(M_PI)});
29}
30
31
32SegmentationCamera::~SegmentationCamera()
33{}
34
35
36std::pair<bool, cv::Mat> SegmentationCamera::mask(const MatrixXf& scene_depth, const Transform<double, 3, Affine> object_transform)
37{
38 return render_mask(scene_depth, object_transform);
39}
40
41
42std::pair<bool, cv::Mat> SegmentationCamera::mask(std::shared_ptr<Camera> camera, std::shared_ptr<RobotsIO::Utils::Transform> object_transform)
43{
44 /* Get object pose. */
45 if (!object_transform->freeze(true))
46 {
47 std::cout << log_name_ << "::mask. Error: cannot get object pose." << std::endl;
48 return std::make_pair(false, cv::Mat());
49 }
50 Transform<double, 3, Affine> transform = object_transform->transform();
51
52 /* Get camera depth. */
53 bool valid_depth = false;
54 Eigen::MatrixXf depth;
55 std::tie(valid_depth, depth) = camera->depth(true);
56 if (!valid_depth)
57 {
58 std::cout << log_name_ << "::mask. Error: cannot get depth." << std::endl;
59 return std::make_pair(false, cv::Mat());
60 }
61
62 return render_mask(depth, transform);
63}
64
65std::pair<bool, cv::Mat> SegmentationCamera::render_mask(const Eigen::MatrixXf& scene_depth, const Eigen::Transform<double, 3, Affine> object_transform)
66{
67 /* Compose pose for renderer. */
68 SICAD::ModelPose pose;
69 pose.push_back(object_transform.translation()(0));
70 pose.push_back(object_transform.translation()(1));
71 pose.push_back(object_transform.translation()(2));
72
73 AngleAxisd rotation(object_transform.rotation());
74 Vector3d axis = rotation.axis();
75 pose.push_back(axis(0));
76 pose.push_back(axis(1));
77 pose.push_back(axis(2));
78 pose.push_back(rotation.angle());
79
80 SICAD::ModelPoseContainer pose_container;
81 pose_container.emplace("object", pose);
82
83 /* Placeholders */
84 cv::Mat placeholder;
85 double cam_x [4] = {0.0, 0.0, 0.0};
86 double cam_o [4] = {1.0, 0.0, 0.0, 0.0};
87
88 /* Render depth. */
89 cv::Mat rendered_depth;
90 if (!(renderer_->superimpose(pose_container, cam_x, cam_o, placeholder, rendered_depth)))
91 {
92 std::cout << log_name_ << "::render_mask. Error: cannot render depth." << std::endl;
93 return std::make_pair(false, cv::Mat());
94 }
95
96 /* Use depth to produce a rendered segmentation mask. */
97 cv::Mat mask;
98#if CV_MAJOR_VERSION >= 4
99 cv::threshold(rendered_depth, mask, 0.001, 255, cv::THRESH_BINARY);
100#else
101 cv::threshold(rendered_depth, mask, 0.001, 255, CV_THRESH_BINARY);
102#endif
103 mask.convertTo(mask, CV_8UC1);
104
105 /* Remove pixels that are not coherent with the depth of the entire scene. */
106 cv::Mat non_zero_coordinates;
107 findNonZero(mask, non_zero_coordinates);
108 for (std::size_t i = 0; i < non_zero_coordinates.total(); i++)
109 {
110 const cv::Point& p = non_zero_coordinates.at<cv::Point>(i);
111
112 if (std::abs(scene_depth(p.y, p.x) - rendered_depth.at<float>(p)) > threshold_)
113 mask.at<uchar>(p) = 0.0;
114 }
115
116 return std::make_pair(true, mask);
117}
std::pair< bool, cv::Mat > mask(const Eigen::MatrixXf &scene_depth, const Eigen::Transform< double, 3, Eigen::Affine > object_transform)