PointCloudLibrary / PointCloudLibrary/pcl
people detect perform not well with realsen D435
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 11.1k
- Forks
- 4.7k
- Avg merge
- 4d 10h
- Merged PRs (30d)
- 6
Description
Your Environment
- Operating System and version:Ubuntu16.04 ROS Kenetic
- Compiler:g++ 5.4
- PCL Version: 1.8.1
Context
Hi, I using the demo main_ground_based_people_detection.cpp and using it in ROS with a realsense D435, but the output is always no person detected~no matter how far I am from the sensor.Is there some configs but "rgb_intrinsics_matrix " .
Expected Behavior
Current Behavior
Code to Reproduce
#include <pcl/console/parse.h>
#include <pcl/point_types.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/io/openni_grabber.h>
#include <pcl/sample_consensus/sac_model_plane.h>
#include <pcl/people/ground_based_people_detection_app.h>
#include <pcl_conversions/pcl_conversions.h>
#include <pcl/common/time.h>
//ros
#include <ros/ros.h>
#include <sensor_msgs/PointCloud2.h>
typedef pcl::PointXYZRGBA PointT;
typedef pcl::PointCloud<PointT> PointCloudT;
// PCL viewer //
pcl::visualization::PCLVisualizer viewer("PCL Viewer");
// Mutex: //
boost::mutex cloud_mutex;
enum { COLS = 1280, ROWS = 720 };//realsense depth image size
PointCloudT::Ptr cloud (new PointCloudT);
bool new_cloud_available_flag = false;
int print_help()
{
cout << "*******************************************************" << std::endl;
cout << "Ground based people detection app options:" << std::endl;
cout << " --help <show_this_help>" << std::endl;
cout << " --svm <path_to_svm_file>" << std::endl;
cout << " --conf <minimum_HOG_confidence (default = -1.5)>" << std::endl;
cout << " --min_h <minimum_person_height (default = 1.3)>" << std::endl;
cout << " --max_h <maximum_person_height (default = 2.3)>" << std::endl;
cout << "*******************************************************" << std::endl;
return 0;
}
void getPclPointCloud(const sensor_msgs::PointCloud2::ConstPtr& points,
PointCloudT& pcl_cloud)
{
using pcl::fromROSMsg;
fromROSMsg<PointT>(*points, pcl_cloud);
}
void cloudCB(const sensor_msgs::PointCloud2::ConstPtr& msg)
{
cloud_mutex.unlock ();
PointCloudT::Ptr pointcloud(new PointCloudT);
getPclPointCloud(msg, *pointcloud);
*cloud = *pointcloud;
new_cloud_available_flag = true;
std::cout<<"copy point cloud"<<std::endl;
cloud_mutex.unlock ();
}
struct callback_args{
// structure used to pass arguments to the callback function
PointCloudT::Ptr clicked_points_3d;
pcl::visualization::PCLVisualizer::Ptr viewerPtr;
};
void
pp_callback (const pcl::visualization::PointPickingEvent& event, void* args)
{
struct callback_args* data = (struct callback_args *)args;
if (event.getPointIndex () == -1)
return;
PointT current_point;
event.getPoint(current_point.x, current_point.y, current_point.z);
data->clicked_points_3d->points.push_back(current_point);
// Draw clicked points in red:
pcl::visualization::PointCloudColorHandlerCustom<PointT> red (data->clicked_points_3d, 255, 0, 0);
data->viewerPtr->removePointCloud("clicked_points");
data->viewerPtr->addPointCloud(data->clicked_points_3d, red, "clicked_points");
data->viewerPtr->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 10, "clicked_points");
std::cout << current_point.x << " " << current_point.y << " " << current_point.z << std::endl;
}
int main (int argc, char** argv)
{
ros::init(argc, argv, "detect_person_pcl");
if(pcl::console::find_switch (argc, argv, "--help") || pcl::console::find_switch (argc, argv, "-h"))
return print_help();
ros::NodeHandle nh;
ros::Subscriber pc_sub = nh.subscribe<sensor_msgs::PointCloud2>("/realsense/depth_registered/points",1, &cloudCB);
// Algorithm parameters:
std::string svm_filename = "/models/trainedLinearSVMForPeopleDetectionWithHOG.yaml";
float min_confidence = -1.5;
float min_width = 0.1;
float max_width = 8.0;
float min_height = 1.3;
float max_height = 2.3;
float voxel_size = 0.06;
float sampling_factor = 1;
Eigen::Matrix3f rgb_intrinsics_matrix;
rgb_intrinsics_matrix << 641.0419311523438, 0.0, 646.490478515625,
0.0, 641.0419311523438, 366.8730163574219,
0.0, 0.0, 1.0; // realsense depth camera intrinsics
// Read if some parameters are passed from command line:
pcl::console::parse_argument (argc, argv, "--svm", svm_filename);
pcl::console::parse_argument (argc, argv, "--conf", min_confidence);
pcl::console::parse_argument (argc, argv, "--min_h", min_height);
pcl::console::parse_argument (argc, argv, "--max_h", max_height);
pcl::console::parse_argument (argc, argv, "--sample", sampling_factor);
// Wait for the first frame:
while(!new_cloud_available_flag && ros::ok())
{
std::cout<<"waiting for point clouds"<<std::endl;
boost::this_thread::sleep(boost::posix_time::milliseconds(1));
ros::spinOnce();
}
new_cloud_available_flag = false;
cloud_mutex.lock (); // for not overwriting the point cloud
// Display pointcloud:
pcl::visualization::PointCloudColorHandlerRGBField<PointT> rgb(cloud);
viewer.addPointCloud<PointT> (cloud, rgb, "input_cloud");
viewer.setCameraPosition(0,0,-2, 0,-1,0,0);
// Add point picking callback to viewer:
struct callback_args cb_args;
PointCloudT::Ptr clicked_points_3d (new PointCloudT);
cb_args.clicked_points_3d = clicked_points_3d;
cb_args.viewerPtr = pcl::visualization::PCLVisualizer::Ptr(&viewer);
viewer.registerPointPickingCallback (pp_callback, (void*)&cb_args);
std::cout << "Shift+click on three floor points, then press 'Q'..." << std::endl;
// Spin until 'Q' is pressed:
viewer.spin();
std::cout << "done." << std::endl;
cloud_mutex.unlock ();
// Ground plane estimation:
Eigen::VectorXf ground_coeffs;
ground_coeffs.resize(4);
std::vector<int> clicked_points_indices;
for (unsigned int i = 0; i < clicked_points_3d->points.size(); i++)
clicked_points_indices.push_back(i);
pcl::SampleConsensusModelPlane<PointT> model_plane(clicked_points_3d);
model_plane.computeModelCoefficients(clicked_points_indices,ground_coeffs);
std::cout << "Ground plane: " << ground_coeffs(0) << " " << ground_coeffs(1) << " " << ground_coeffs(2) << " " << ground_coeffs(3) << std::endl;
// Initialize new viewer:
pcl::visualization::PCLVisualizer viewer("PCL Viewer"); // viewer initialization
viewer.setCameraPosition(0,0,-2,0,-1,0,0);
// Create classifier for people detection:
pcl::people::PersonClassifier<pcl::RGB> person_classifier;
person_classifier.loadSVMFromFile(svm_filename); // load trained SVM
// People detection app initialization:
pcl::people::GroundBasedPeopleDetectionApp<PointT> people_detector; // people detection object
people_detector.setVoxelSize(voxel_size); // set the voxel size
people_detector.setIntrinsics(rgb_intrinsics_matrix); // set RGB camera intrinsic parameters
people_detector.setClassifier(person_classifier); // set person classifier
people_detector.setPersonClusterLimits(min_height, max_height, min_width, max_width);
people_detector.setSamplingFactor(sampling_factor); // set a downsampling factor to the point cloud (for increasing speed)
// people_detector.setSensorPortraitOrientation(true); // set sensor orientation to vertical
// For timing:
static unsigned count = 0;
static double last = pcl::getTime ();
// Main loop:
while (!viewer.wasStopped() && ros::ok())
{
if (new_cloud_available_flag && cloud_mutex.try_lock ()) // if a new cloud is available
{
new_cloud_available_flag = false;
// Perform people detection on the new cloud:
std::vector<pcl::people::PersonCluster<PointT> > clusters; // vector containing persons clusters
people_detector.setInputCloud(cloud);
people_detector.setGround(ground_coeffs); // set floor coefficients
people_detector.compute(clusters); // perform people detection
ground_coeffs = people_detector.getGround(); // get updated floor coefficients
// Draw cloud and people bounding boxes in the viewer:
viewer.removeAllPointClouds();
viewer.removeAllShapes();
pcl::visualization::PointCloudColorHandlerRGBField<PointT> rgb(cloud);
viewer.addPointCloud<PointT> (cloud, rgb, "input_cloud");
unsigned int k = 0;
for(std::vector<pcl::people::PersonCluster<PointT> >::iterator it = clusters.begin(); it != clusters.end(); ++it)
{
if(it->getPersonConfidence() > min_confidence) // draw only people with confidence above a threshold
{
// draw theoretical person bounding box in the PCL viewer:
it->drawTBoundingBox(viewer, k);
k++;
}
}
std::cout << k << " people found" << std::endl;
viewer.spinOnce();
// Display average framerate:
if (++count == 30)
{
double now = pcl::getTime ();
std::cout << "Average framerate: " << double(count)/double(now - last) << " Hz" << std::endl;
count = 0;
last = now;
}
cloud_mutex.unlock ();
}
ros::spinOnce();
}
return 0;
}
Possible Solution
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the main_ground_based_people_detection.cpp demo and the supplied ROS subscriber callback, using Ubuntu 16.04, ROS Kinetic, PCL 1.8.1, and the RealSense D435 setup described here. Check that the subscribed point cloud and camera intrinsics match the detector's inputs, then reproduce the no-detection result. Done means the cause is identified and people are detected reliably in the documented setup.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- computer-vision, robotics
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100