rating.cpp
Go to the documentation of this file.
1 
18 #include "rating.h"
19 #include <Eigen/Dense>
20 #include <ros/console.h>
21 
22 #include <pcl/point_cloud.h>
23 #include <pcl/filters/frustum_culling.h>
24 #include <pcl/impl/point_types.hpp>
25 
26 #include <pcl/filters/impl/frustum_culling.hpp>
27 
28 namespace fake_object_recognition {
29 
30 Rating::Rating(double fovx, double fovy, double ncp, double fcp) :
31  fovx_(fovx),
32  fovy_(fovy),
33  ncp_(ncp),
34  fcp_(fcp),
35  camera_orientation_(Eigen::Vector3d(0.0, 0.0, 1.0)) { }
36 
37 bool Rating::ratePose(const geometry_msgs::Pose &pose, double threshold_d, double threshold_x, double threshold_y) {
38  //Use distance and agle ratings to rate pose.
39  double rating_d = getDistanceRating(pose);
40  ROS_DEBUG_STREAM("Distance Rating: " << rating_d);
41  double rating_x = getAngleRating(pose, true);
42  ROS_DEBUG_STREAM("Angle rating in xz-plane: " << rating_x);
43  double rating_y = getAngleRating(pose, false);
44  ROS_DEBUG_STREAM("Angle rating in yz-plane: " << rating_y);
45 
46  return rating_d > threshold_d && rating_x > threshold_x && rating_y > threshold_y;
47 }
48 
49 double Rating::getDistanceRating(const geometry_msgs::Pose &object_pose) {
50  double rating = 0.0;
51  Eigen::Vector3d object_position(object_pose.position.x, object_pose.position.y, object_pose.position.z);
52  double dot_cam_obj = camera_orientation_.dot(object_position);
53 
54  double dist_to_mid = std::abs(dot_cam_obj - ((fcp_ + ncp_) / 2.0));
55  double dist_threshold = (fcp_ - ncp_) / 2.0;
56 
57  if (dist_to_mid < dist_threshold) {
58  rating = 0.5 + 0.5 * cos((dist_to_mid * M_PI) / dist_threshold);
59  }
60 
61  return rating;
62 }
63 
64  double Rating::getAngleRating(const geometry_msgs::Pose &object_pose, bool direction) {
65  double rating = 0.0;
66 
67  Eigen::Vector3d object_position(object_pose.position.x, object_pose.position.y, object_pose.position.z);
68 
69  double angle_max;
70 
71  //Azimut
72  if(direction){
73  //Project object position on xz-plane of camera frame.
74  object_position.y() = 0.0;
75  angle_max = (fovx_ * M_PI) / 180.0;
76  }
77  //Elevation
78  else {
79  //Project object position on xz-plane of camera frame.
80  object_position.x() = 0.0;
81  angle_max = (fovy_ * M_PI) / 180.0;
82  }
83 
84  object_position.normalize();
85 
86  double angle = std::acos(camera_orientation_.dot(object_position));
87 
88  if (angle < angle_max) {
89  rating = 0.5 + 0.5 * std::cos((angle * M_PI) / angle_max);
90  }
91 
92  return rating;
93 }
94 
95 bool Rating::getBBRating(const std::array<geometry_msgs::Point, 8> &bounding_box) {
96  pcl::PointCloud<pcl::PointXYZ>::Ptr point_cloud = boost::make_shared<pcl::PointCloud<pcl::PointXYZ>>();
97  unsigned int bb_size = bounding_box.size(); // always 8
98  for (unsigned int i = 0; i < bb_size; i++) {
99  pcl::PointXYZ pt = pcl::PointXYZ(bounding_box.at(i).x, bounding_box.at(i).y, bounding_box.at(i).z);
100  point_cloud->push_back(pt);
101  }
102 
103  pcl::FrustumCulling<pcl::PointXYZ> fc;
104  fc.setHorizontalFOV(fovx_);
105  fc.setVerticalFOV(fovy_);
106  fc.setNearPlaneDistance(ncp_);
107  fc.setFarPlaneDistance(fcp_);
108 
109  /* Camera pose: since visual axis is always set to (0,0,1) in ctor, a fixed matrix is used here; it is a homogenous matrix rotating around the y-axis by 90 degrees
110  * because of the assumption that the camera is pointing in the x direction in the beginning. */
111  Eigen::Matrix4f cam;
112  cam << 0.0, 0.0, -1.0, 0.0,
113  0.0, 1.0, 0.0, 0.0,
114  1.0, 0.0, 0.0, 0.0,
115  0.0, 0.0, 0.0, 1.0;
116  fc.setCameraPose(cam);
117 
118  fc.setInputCloud(pcl::PointCloud<pcl::PointXYZ>::Ptr(point_cloud));
119 
120  pcl::PointCloud<pcl::PointXYZ>::Ptr culled_cloud = boost::make_shared<pcl::PointCloud<pcl::PointXYZ>>();
121  fc.filter(*culled_cloud);
122 
123  return (culled_cloud->size() == bb_size);
124 }
125 
126 double Rating::getNormalRating(const geometry_msgs::Pose &object_pose, const std::vector<geometry_msgs::Point> &normals) {
127  //similar to NBV - DefaulRatingModule
128  // (never called with empty normals because of check in rateBBandNormal)
129  Eigen::Vector3d v1, v2;
130  double angleThreshold = M_PI * 0.5;
131  v1 << object_pose.position.x, object_pose.position.y, object_pose.position.z; // Vector describing the position of the object.
132  v1 = (-1) * v1;
133  v1.normalize(); // Vector from camera to object
134 
135  float xNorm = v1.lpNorm<2>();
136  if (xNorm == 0) {
137  ROS_DEBUG_STREAM("Object appears to be inside camera.");
138  return 0.0;
139  }
140  // find maximum rating:
141  float best_rated = 0.0;
142  for (unsigned int i = 0; i < normals.size(); i++) {
143  v2 << normals.at(i).x, normals.at(i).y, normals.at(i).z;
144  v2.normalize();
145  float yNorm = v2.lpNorm<2>();
146  if (yNorm != 0) { // Otherwise normal does not actually exist
147  float cosine = v1.dot(v2) / xNorm / yNorm;
148  float angle = std::acos(cosine);
149  if (angle < angleThreshold) {
150  float rating = 0.5 + 0.5 * std::cos(angle * M_PI / angleThreshold);
151  if (rating > best_rated) { best_rated = rating; }
152  }
153  }
154  }
155  ROS_DEBUG_STREAM("getNormalRating: best_rated = " << best_rated);
156  return best_rated;
157 }
158 
159 bool Rating::rateBBandNormal(const geometry_msgs::Pose &object_pose, const std::array<geometry_msgs::Point, 8> &bounding_box, const std::vector<geometry_msgs::Point> &normals, double threshold) {
160  if (!getBBRating(bounding_box)) { // if not all 8 corner points of bounding box are inside the frustum:
161  return false; // Return immediately.
162  }
163  else if (normals.empty()) { // if there are no normals, e.g. because an object has no clear ones:
164  return true; // since all bounding box corner points are inside frustum: return true.
165  }
166  else {
167  return (getNormalRating(object_pose, normals) > threshold); // Otherwise rate normals.
168  }
169 }
170 
171 
172 
173 
174 }
bool getBBRating(const std::array< geometry_msgs::Point, 8 > &bounding_box)
Returns the amount of points of the bounding box inside the frustum divided by the amount of all poin...
Definition: rating.cpp:95
double getAngleRating(const geometry_msgs::Pose &object_pose, bool direction)
Returns a rating of an object&#39;s pose based on the (azimut or elevation) angle between the camera&#39;s vi...
Definition: rating.cpp:64
bool rateBBandNormal(const geometry_msgs::Pose &object_pose, const std::array< geometry_msgs::Point, 8 > &bounding_box, const std::vector< geometry_msgs::Point > &normals, double threshold)
Rates an objects visibility based on its bounding box and its normals.
Definition: rating.cpp:159
TFSIMD_FORCE_INLINE tfScalar angle(const Quaternion &q1, const Quaternion &q2)
#define ROS_DEBUG_STREAM(args)
double getNormalRating(const geometry_msgs::Pose &object_pose, const std::vector< geometry_msgs::Point > &normals)
Returns a rating for the angle between sight vector to object and object&#39;s normal. 1.0 is best, 0.0 worst.
Definition: rating.cpp:126
bool ratePose(const geometry_msgs::Pose &pose, double threshold_d, double threshold_x, double threshold_y)
Return whether a pose is visible in the camera frustum based on the distance and angle rating...
Definition: rating.cpp:37
const Eigen::Vector3d camera_orientation_
Definition: rating.h:45
double getDistanceRating(const geometry_msgs::Pose &object_pose)
Returns a rating of an object&#39;s pose based on the distance to the camera.
Definition: rating.cpp:49
Rating(double fovx, double fovy, double ncp, double fcp)
The constructor of the class.
Definition: rating.cpp:30


asr_fake_object_recognition
Author(s): Allgeyer Tobias, Aumann Florian, Borella Jocelyn, Meißner Pascal, Qattan Mohamad
autogenerated on Wed Feb 19 2020 03:58:59