24 #include <pcl/filters/filter.h> 25 #include <pcl/filters/passthrough.h> 27 #include <asr_halcon_bridge/halcon_pointcloud.h> 29 #include <pcl/common/common.h> 38 PoseRecognition::PoseRecognition(HalconCpp::HImage &scene_image, HalconCpp::HImage &scene_image_mono, pcl::PointCloud<pcl::PointXYZ>::Ptr &point_cloud_with_guppy,
ObjectDescriptor *obj_desc,
int median_points_offset,
double samplingDistance,
double keypointFraction,
bool eval,
int max_instances)
39 : scene_image_(scene_image), scene_image_mono_(scene_image_mono),
40 point_cloud_with_guppy_(point_cloud_with_guppy), obj_desc_(obj_desc), max_instances_(max_instances), median_points_offset_(median_points_offset),
41 sampling_distance_(samplingDistance), keypoint_fraction_(keypointFraction), eval_(eval) { }
46 for (
unsigned int i = 0; i <
results_.size(); i++) {
52 std::ofstream object_ofstream;
55 object_ofstream.open (path.c_str(), std::ofstream::out | std::ofstream::app);
64 object_ofstream << textures_found - find_poses_start;
66 for (
unsigned int i = 0; i <
results_.size(); i++) {
68 object_ofstream <<
"#";
76 object_ofstream << cloud_reduced - loop_entry <<
";";
83 object_ofstream << model_found - cloud_reduced <<
";";
99 object_ofstream << std::endl;
100 object_ofstream.close();
108 HalconCpp::HTuple score;
114 if (score.Length() > 0) {
115 for (
int j = 0; j < score.Length(); j++) {
117 HalconCpp::HHomMat2D matrix;
118 matrix.SetFromTuple(matrix_tuple);
120 double trans_x, trans_y, trans_w;
123 int row = (int) (trans_x / trans_w);
124 int column = (int) (trans_y / trans_w);
146 int row =
results_.at(result_index)->getTexPoint()[0];
147 int column =
results_.at(result_index)->getTexPoint()[1];
149 std::vector<pcl::PointXYZ> points;
152 for (
int i = 0; i < 5; i++) {
153 if (row - median_points_offset_ < 0 || column - median_points_offset_ < 0 || row + median_points_offset_ >= image_height || column + median_points_offset_ >= image_width) {
157 if (pcl::isFinite(current_point)) {
158 points.push_back(current_point);
162 if (points.size() > 0) {
165 if (pcl::isFinite(median_point)) {
166 if (median_point.x - radius > min.x) { min.x = median_point.x - radius; }
167 if (median_point.x + radius < max.x) { max.x = median_point.x + radius; }
168 if (median_point.y - radius > min.y) { min.y = median_point.y - radius; }
169 if (median_point.y + radius < max.y) { max.y = median_point.y + radius; }
170 if (median_point.z - radius > min.z) { min.z = median_point.z - radius; }
171 if (median_point.z + radius < max.z) { max.z = median_point.z + radius; }
178 pcl::PointCloud<pcl::PointXYZ>::Ptr reduced_cloud(
new pcl::PointCloud<pcl::PointXYZ>);
180 pcl::PassThrough<pcl::PointXYZ> pass;
182 pass.setFilterFieldName (
"x");
183 pass.setFilterLimits (min.x, max.x);
184 pass.filter (*reduced_cloud);
186 pass.setInputCloud (reduced_cloud);
187 pass.setFilterFieldName (
"y");
188 pass.setFilterLimits (min.y, max.y);
189 pass.filter (*reduced_cloud);
191 results_.at(result_index)->setTexPoint3D(median_point);
192 results_.at(result_index)->setSearchCloud(reduced_cloud);
203 if ((
results_.at(result_index)->getSearchCloud()->width *
results_.at(result_index)->getSearchCloud()->height > 0)) {
205 std::vector< int > index;
206 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud =
results_.at(result_index)->getSearchCloud();
207 pcl::removeNaNFromPointCloud(*cloud, *cloud, index);
209 results_.at(result_index)->setSearchCloud(cloud);
210 sensor_msgs::PointCloud2 p_n_cloud;
212 halcon_bridge::HalconPointcloudPtr ptr = halcon_bridge::toHalconCopy(p_n_cloud);
213 HalconCpp::HObjectModel3D scene = *ptr->model;
215 HalconCpp::HSurfaceMatchingResultArray result;
216 HalconCpp::HTuple *score =
new HalconCpp::HTuple();
217 HalconCpp::HTuple genParamName(
"num_matches");
218 genParamName.Append(
"pose_ref_use_scene_normals");
219 HalconCpp::HTuple genParamValue(1);
220 genParamValue.Append(
"false");
224 bool pose_already_found =
false;
225 for (
int i = 0; i < result_index; i++) {
226 if ((
results_.at(i)->checkModelFound()) && (sqrt(pow(
results_.at(i)->getPose()[0] - poses.ConvertToTuple()[0], 2.0) + pow(
results_.at(i)->getPose()[1] - poses.ConvertToTuple()[1], 2.0) + pow(
results_.at(i)->getPose()[2] - poses.ConvertToTuple()[2], 2.0)) < (
obj_desc_->
getDiameter() * 0.5))) {
227 pose_already_found =
true;
231 if (!pose_already_found) {
233 results_.at(result_index)->setPose(poses.ConvertToTuple());
234 results_.at(result_index)->setScore3D((*score)[0]);
248 HalconCpp::HPose pose;
249 pose.SetFromTuple(
results_.at(result_index)->getPose());
251 HalconCpp::HQuaternion rotation;
252 rotation.PoseToQuat(pose);
253 rotation = rotation.QuatNormalize();
255 Eigen::Vector3d location(
results_.at(result_index)->getPose()[0],
results_.at(result_index)->getPose()[1],
results_.at(result_index)->getPose()[2]);
265 Eigen::Vector3d texFromObjOrigin;
266 texFromObjOrigin =
results_.at(result_index)->getTexPoint3D() - location;
267 texFromObjOrigin.normalize();
271 Eigen::Vector3d viewOrientationFromObjOrigin(x, y, z);
272 viewOrientationFromObjOrigin.normalize();
274 double dot = texFromObjOrigin.dot(viewOrientationFromObjOrigin);
276 double bestAngle = 0.0;
278 while (currentAngle < 360) {
279 double radians = (currentAngle) * (PI / 180);
282 double x_curr, y_curr, z_curr;
285 Eigen::Vector3d vec_curr_obj(x_curr, y_curr, z_curr);
286 vec_curr_obj.normalize();
287 x_curr = rotation.QuatRotatePoint3d(vec_curr_obj[0], vec_curr_obj[1], vec_curr_obj[2], &y_curr, &z_curr);
289 Eigen::Vector3d vec_curr(x_curr, y_curr, z_curr);
290 vec_curr.normalize();
292 if (texFromObjOrigin.dot(vec_curr) > maxDot) {
293 maxDot = texFromObjOrigin.dot(vec_curr);
294 bestAngle = currentAngle;
299 results_.at(result_index)->setAdjustedRotation(quat_result.QuatCompose(
results_.at(result_index)->getAdjustedRotation()));
306 double trans_x, trans_y, trans_w;
307 trans_x =
results_.at(result_index)->getTransMatrix2D().ProjectiveTransPoint2d(0, 1, 1, &trans_y, &trans_w);
308 Eigen::Vector2d upperPoint(trans_x / trans_w, trans_y / trans_w);
309 trans_x =
results_.at(result_index)->getTransMatrix2D().ProjectiveTransPoint2d(0, 0, 1, &trans_y, &trans_w);
310 Eigen::Vector2d centerPoint(trans_x / trans_w, trans_y / trans_w);
311 upperPoint = upperPoint - centerPoint;
312 upperPoint.normalize();
314 double x_upper, y_upper, z_upper;
315 x_upper = rotation.QuatRotatePoint3d(0, -1, 0, &y_upper, &z_upper);
316 Eigen::Vector2d upperPoint3D(x_upper, -1 * y_upper);
317 upperPoint3D.normalize();
319 if (upperPoint.dot(upperPoint3D) < 0) {
320 double axis_rot_x, axis_rot_y, axis_rot_z;
322 HalconCpp::HQuaternion quat_upside_down(axis_rot_x, axis_rot_y, axis_rot_z, PI);
323 results_.at(result_index)->setAdjustedRotation(quat_upside_down.QuatCompose(
results_.at(result_index)->getAdjustedRotation()));
std::vector< RecognitionResult * > getResults() const
double keypoint_fraction_
HalconCpp::HSurfaceModel getSurfaceModel() const
HalconCpp::HRegion getInputImageDomain() const
static const std::string OUTPUT_EVALUATION_DIR("eval")
int median_points_offset_
pcl::PointXYZ findPoint3D(pcl::PointCloud< pcl::PointXYZ >::Ptr cloud, pcl::PointXYZ current_point, int row, int column, int image_height, int image_width)
Finds the corresponding 3D point to the given 2D point.
PoseRecognition(HalconCpp::HImage &scene_image, HalconCpp::HImage &scene_image_mono, pcl::PointCloud< pcl::PointXYZ >::Ptr &point_cloud_with_guppy, ObjectDescriptor *obj_desc, int median_points_offset, double samplingDistance, double keypointFraction, bool eval, int max_instances=1)
The constructor of this class.
int getRotationModelType() const
ObjectDescriptor * obj_desc_
TFSIMD_FORCE_INLINE const tfScalar & y() const
pcl::PointCloud< pcl::PointXYZ >::Ptr point_cloud_with_guppy_
bool reducePointCloud(int result_index)
Prepares the 3D-recognition by reducing the point cloud depending on the 2D-recognition result...
std::vector< RecognitionResult * > results_
void findPoses()
Recognizes the present object instances in the scene.
HalconCpp::HImage scene_image_
static const int ROTATION_MODEL_SPHERE
bool findModelInCloud(int result_index)
Recognizes the object in the reduced 3D-scene.
ObjectDescriptor * getObjectDescriptor() const
TFSIMD_FORCE_INLINE const tfScalar & x() const
std::vector< ObjectViewDescriptor > getModelViewDescriptors() const
HalconCpp::HImage scene_image_mono_
static const int ROTATION_MODEL_CYLINDER
#define ROS_DEBUG_STREAM(args)
TFSIMD_FORCE_INLINE const tfScalar & z() const
Eigen::Vector3d computeMedian(std::vector< Eigen::Vector3d > points)
Computes the median of the given points.
double getScore3D() const
double getDiameter() const
void findTexture()
Recognizes the object in the 2D-scene.
std::string getName() const
void toROSMsg(const sensor_msgs::PointCloud2 &cloud, sensor_msgs::Image &image)
double sampling_distance_
virtual ~PoseRecognition()
The destructor of this class.
void adjustRotation(int result_index)
Adjusts the rotation of the found object instance depending on its rotation-type. ...