41 #include <pcl/people/person_classifier.h>
43 #ifndef PCL_PEOPLE_PERSON_CLASSIFIER_HPP_
44 #define PCL_PEOPLE_PERSON_CLASSIFIER_HPP_
46 template <
typename Po
intT>
49 template <
typename Po
intT>
52 template <
typename Po
intT>
bool
56 std::ifstream SVM_file;
57 SVM_file.open(svm_filename.c_str());
59 getline (SVM_file,line);
60 std::size_t tok_pos = line.find_first_of(
':', 0);
61 window_height_ = std::atoi(line.substr(tok_pos+1, std::string::npos - tok_pos-1).c_str());
63 getline (SVM_file,line);
64 tok_pos = line.find_first_of(
':', 0);
65 window_width_ = std::atoi(line.substr(tok_pos+1, std::string::npos - tok_pos-1).c_str());
67 getline (SVM_file,line);
68 tok_pos = line.find_first_of(
':', 0);
69 SVM_offset_ = std::atof(line.substr(tok_pos+1, std::string::npos - tok_pos-1).c_str());
71 getline (SVM_file,line);
72 tok_pos = line.find_first_of(
'[', 0);
73 std::size_t tok_end_pos = line.find_first_of(
']', 0);
74 while (tok_pos < tok_end_pos)
76 std::size_t prev_tok_pos = tok_pos;
77 tok_pos = line.find_first_of(
',', prev_tok_pos+1);
78 SVM_weights_.push_back(std::atof(line.substr(prev_tok_pos+1, tok_pos-prev_tok_pos-1).c_str()));
82 if (SVM_weights_.empty ())
84 PCL_ERROR (
"[pcl::people::PersonClassifier::loadSVMFromFile] Invalid SVM file!\n");
90 template <
typename Po
intT>
void
93 window_height_ = window_height;
94 window_width_ = window_width;
95 SVM_weights_ = SVM_weights;
96 SVM_offset_ = SVM_offset;
99 template <
typename Po
intT>
void
102 window_height = window_height_;
103 window_width = window_width_;
104 SVM_weights = SVM_weights_;
105 SVM_offset = SVM_offset_;
108 template <
typename Po
intT>
void
120 output_image->points.resize(width*height, new_point);
121 output_image->height = height;
122 output_image->width = width;
125 float scale1 =
static_cast<float>(height) /
static_cast<float>(input_image->height);
126 float scale2 =
static_cast<float>(width) /
static_cast<float>(input_image->width);
128 Eigen::Matrix3f T_inv;
129 T_inv << 1/scale1, 0, 0,
137 for (
int i = 0; i < height; i++)
139 for (
int j = 0; j < width; j++)
141 A = T_inv * Eigen::Vector3f(i, j, 1);
142 c1 = std::ceil(A(0));
143 f1 = std::floor(A(0));
144 c2 = std::ceil(A(1));
145 f2 = std::floor(A(1));
149 (f1 >=
static_cast<int> (input_image->height)) ||
150 (c1 >=
static_cast<int> (input_image->height)) ||
153 (f2 >=
static_cast<int> (input_image->width)) ||
154 (c2 >=
static_cast<int> (input_image->width)))
159 g1 = (*input_image)(f2, c1);
160 g3 = (*input_image)(f2, f1);
161 g4 = (*input_image)(c2, f1);
162 g2 = (*input_image)(c2, c1);
166 new_point.r =
static_cast<int>((1 - w1) * ((1 - w2) * g1.r + w2 * g4.r) + w1 * ((1 - w2) * g3.r + w2 * g4.r));
167 new_point.g =
static_cast<int>((1 - w1) * ((1 - w2) * g1.g + w2 * g4.g) + w1 * ((1 - w2) * g3.g + w2 * g4.g));
168 new_point.b =
static_cast<int>((1 - w1) * ((1 - w2) * g1.b + w2 * g4.b) + w1 * ((1 - w2) * g3.b + w2 * g4.b));
171 (*output_image)(j,i) = new_point;
176 template <
typename Po
intT>
void
188 output_image->points.resize(height*width, black_point);
189 output_image->width = width;
190 output_image->height = height;
192 int x_start_in = std::max(0, xmin);
193 int x_end_in = std::min(
static_cast<int>(input_image->width-1), xmin+width-1);
194 int y_start_in = std::max(0, ymin);
195 int y_end_in = std::min(
static_cast<int>(input_image->height-1), ymin+height-1);
197 int x_start_out = std::max(0, -xmin);
199 int y_start_out = std::max(0, -ymin);
202 for (
int i = 0; i < (y_end_in - y_start_in + 1); i++)
204 for (
int j = 0; j < (x_end_in - x_start_in + 1); j++)
206 (*output_image)(x_start_out + j, y_start_out + i) = (*input_image)(x_start_in + j, y_start_in + i);
211 template <
typename Po
intT>
double
217 if (SVM_weights_.empty ())
219 PCL_ERROR (
"[pcl::people::PersonClassifier::evaluate] SVM has not been set!\n");
223 int height = std::floor((height_person * window_height_) / (0.75 * window_height_) + 0.5);
224 int width = std::floor((height_person * window_width_) / (0.75 * window_height_) + 0.5);
225 int xmin = std::floor(xc - width / 2 + 0.5);
226 int ymin = std::floor(yc - height / 2 + 0.5);
233 copyMakeBorder(image, box, xmin, ymin, width, height);
237 resize(box, sample, window_width_, window_height_);
240 float* sample_float =
new float[sample->width * sample->height * 3];
241 int delta = sample->height * sample->width;
242 for (std::uint32_t row = 0; row < sample->height; row++)
244 for (std::uint32_t col = 0; col < sample->width; col++)
246 sample_float[row + sample->height * col] = (
static_cast<float> ((*sample)(col, row).r))/255;
247 sample_float[row + sample->height * col + delta] = (
static_cast<float> ((*sample)(col, row).g))/255;
248 sample_float[row + sample->height * col + delta * 2] =
static_cast<float> (((*sample)(col, row).b))/255;
254 float *descriptor =
new float[SVM_weights_.size()];
255 std::fill_n(descriptor, SVM_weights_.size(), 0.0f);
256 hog.
compute(sample_float, descriptor);
260 for(std::size_t i = 0; i < SVM_weights_.size(); i++)
262 confidence += SVM_weights_[i] * descriptor[i];
265 confidence -= SVM_offset_;
268 delete[] sample_float;
272 confidence = std::numeric_limits<double>::quiet_NaN();
278 template <
typename Po
intT>
double
280 Eigen::Vector3f& bottom,
281 Eigen::Vector3f& top,
282 Eigen::Vector3f& centroid,
290 pixel_height = bottom(1) - top(1);
291 pixel_width = pixel_height / 2.0f;
295 pixel_width = top(0) - bottom(0);
296 pixel_height = pixel_width / 2.0f;
298 float pixel_xc = centroid(0);
299 float pixel_yc = centroid(1);
303 return (evaluate(pixel_height, pixel_xc, pixel_yc, image));
305 return (evaluate(pixel_width, pixel_yc, image->height-pixel_xc+1, image));
PointCloud represents the base class in PCL for storing collections of 3D points.
HOG represents a class for computing the HOG descriptor described in Dalal, N.
void compute(float *I, int h, int w, int n_channels, int bin_size, int n_orients, bool soft_bin, float *descriptor)
Compute HOG descriptor.
void copyMakeBorder(PointCloudPtr &input_image, PointCloudPtr &output_image, int xmin, int ymin, int width, int height)
Copies an image and makes a black border around it, where the source image is not present.
virtual ~PersonClassifier()
Destructor.
PersonClassifier()
Constructor.
double evaluate(float height, float xc, float yc, PointCloudPtr &image)
Classify the given portion of image.
typename PointCloud::Ptr PointCloudPtr
void setSVM(int window_height, int window_width, std::vector< float > SVM_weights, float SVM_offset)
Set trained SVM for person confidence estimation.
bool loadSVMFromFile(const std::string &svm_filename)
Load SVM parameters from a text file.
void getSVM(int &window_height, int &window_width, std::vector< float > &SVM_weights, float &SVM_offset)
Get trained SVM for person confidence estimation.
void resize(PointCloudPtr &input_image, PointCloudPtr &output_image, int width, int height)
Resize an image represented by a pointcloud containing RGB information.
A point structure representing Euclidean xyz coordinates, and the RGB color.