@@ -98,7 +98,7 @@ void Utilities::pointTypeTransfer(PointCloudRGBN::Ptr cloud_in,
98
98
}
99
99
}
100
100
101
- void Utilities::cutCloud (pcl::ModelCoefficients::Ptr coeff_in, double th_distance,
101
+ void Utilities::cutCloud (pcl::ModelCoefficients::Ptr coeff_in, float th_distance,
102
102
PointCloudRGBN::Ptr cloud_in,
103
103
PointCloudMono::Ptr &cloud_out)
104
104
{
@@ -263,27 +263,27 @@ void Utilities::shrinkHull(PointCloudMono::Ptr cloud,
263
263
float theta = atan (d_y/d_x);
264
264
if (d_x > 0 && d_y >= 0 ) {
265
265
cloud_sk->points [i].x = (pit->x - fabs (dis*sin (theta)))>center_x?
266
- (pit->x - fabs (dis*sin (theta))):pit->x ;
266
+ (pit->x - fabs (dis*sin (theta))):pit->x ;
267
267
cloud_sk->points [i].y = (pit->y - fabs (dis*cos (theta)))>center_y?
268
- (pit->y - fabs (dis*cos (theta))):pit->y ;
268
+ (pit->y - fabs (dis*cos (theta))):pit->y ;
269
269
}
270
270
else if (d_x < 0 && d_y >= 0 ) {
271
271
cloud_sk->points [i].x = (pit->x + fabs (dis*sin (theta)))<center_x?
272
- (pit->x + fabs (dis*sin (theta))):pit->x ;
272
+ (pit->x + fabs (dis*sin (theta))):pit->x ;
273
273
cloud_sk->points [i].y = (pit->y - fabs (dis*cos (theta)))>center_y?
274
- (pit->y - fabs (dis*cos (theta))):pit->y ;
274
+ (pit->y - fabs (dis*cos (theta))):pit->y ;
275
275
}
276
276
else if (d_x < 0 && d_y < 0 ) {
277
277
cloud_sk->points [i].x = (pit->x + fabs (dis*sin (theta)))<center_x?
278
- (pit->x + fabs (dis*sin (theta))):pit->x ;
278
+ (pit->x + fabs (dis*sin (theta))):pit->x ;
279
279
cloud_sk->points [i].y = (pit->y + fabs (dis*cos (theta)))<center_y?
280
- (pit->y + fabs (dis*cos (theta))):pit->y ;
280
+ (pit->y + fabs (dis*cos (theta))):pit->y ;
281
281
}
282
282
else {
283
283
cloud_sk->points [i].x = (pit->x - fabs (dis*sin (theta)))>center_x?
284
- (pit->x - fabs (dis*sin (theta))):pit->x ;
284
+ (pit->x - fabs (dis*sin (theta))):pit->x ;
285
285
cloud_sk->points [i].y = (pit->y + fabs (dis*cos (theta)))<center_y?
286
- (pit->y + fabs (dis*cos (theta))):pit->y ;
286
+ (pit->y + fabs (dis*cos (theta))):pit->y ;
287
287
}
288
288
}
289
289
}
@@ -292,38 +292,53 @@ void Utilities::shrinkHull(PointCloudMono::Ptr cloud,
292
292
bool Utilities::isInHull (PointCloudMono::Ptr hull, pcl::PointXY p_in,
293
293
pcl::PointXY &offset, pcl::PointXY &p_closest)
294
294
{
295
- float x_temp = 1.0 ;
296
- float y_temp = 1.0 ;
297
295
float dis_temp = 30.0 ;
298
296
297
+ // Step 1: get the nearest 2 points of p_in on hull
299
298
size_t i = 0 ;
299
+ pcl::PointXY p_n1;
300
+ pcl::PointXY p_n2;
300
301
for (PointCloudMono::const_iterator pit = hull->begin ();
301
302
pit != hull->end (); ++pit) {
302
303
float delta_x = pit->x - p_in.x ;
303
- x_temp *= delta_x;
304
304
float delta_y = pit->y - p_in.y ;
305
- y_temp *= delta_y;
305
+ float distance = sqrt ( pow (delta_x, 2 ) + pow ( delta_y, 2 )) ;
306
306
307
- // Use Manhattan distance
308
- float dis = fabs (delta_x) + fabs (delta_y);
309
- if (dis < dis_temp) {
310
- offset.x = delta_x;
311
- offset.y = delta_y;
312
- p_closest.x = pit->x ;
313
- p_closest.y = pit->y ;
314
- dis_temp = dis;
307
+ if (distance < dis_temp) {
308
+ p_n2.x = p_n1.x ;
309
+ p_n2.y = p_n1.y ;
310
+ p_n1.x = pit->x ;
311
+ p_n1.y = pit->y ;
312
+ dis_temp = distance;
315
313
}
316
314
++i;
317
315
}
318
- if (x_temp <= 0 && y_temp <= 0 ) {
319
- // The p_in is surrounded by hull
316
+
317
+ // Step 2: form the line segment (pn1, pn2) and (p_in, p_c)
318
+ // p_c is the center of the hull, judge if the 2 line segment
319
+ // cross each other, if true, the p_in is not in hull
320
+ pcl::PointXYZ minPt, maxPt;
321
+ pcl::getMinMax3D (*hull, minPt, maxPt);
322
+ pcl::PointXY p_c;
323
+ p_c.x = (minPt.x + maxPt.x )/2 ;
324
+ p_c.y = (minPt.y + maxPt.y )/2 ;
325
+ bool cross = isIntersect (p_n1, p_n2, p_in, p_c);
326
+
327
+ if (cross) {
328
+ // The p_in is not in hull
329
+ // Here we use a less accurate but simple way
330
+ // to calculate the closest point on hull of p_in
331
+ getClosestPoint (p_n1, p_n2, p_in, p_closest);
332
+
333
+ offset.x = p_closest.x - p_in.x ;
334
+ offset.y = p_closest.y - p_in.y ;
335
+ return false ;
336
+ }
337
+ else {
320
338
offset.x = 0 ;
321
339
offset.y = 0 ;
322
340
return true ;
323
341
}
324
- else {
325
- return false ;
326
- }
327
342
}
328
343
329
344
bool Utilities::tryExpandROI (int &minx, int &miny, int &maxx, int &maxy,
@@ -341,3 +356,63 @@ bool Utilities::tryExpandROI(int &minx, int &miny, int &maxx, int &maxy,
341
356
if (miny < 0 ) miny = 0 ;
342
357
if (maxy > height) maxy = height - 1 ;
343
358
}
359
+
360
+ float Utilities::determinant (float v1, float v2, float v3, float v4)
361
+ {
362
+ return (v1 * v3 - v2 * v4);
363
+ }
364
+
365
+ bool Utilities::isIntersect (pcl::PointXY p1, pcl::PointXY p2,
366
+ pcl::PointXY p3, pcl::PointXY p4)
367
+ {
368
+ float delta = determinant (p2.x -p1.x , p3.x -p4.x , p2.y -p1.y , p3.y -p4.y );
369
+ if ( delta<=(1e-6 ) && delta>=-(1e-6 ) ) {
370
+ return false ;
371
+ }
372
+ float lameda = determinant (p3.x -p1.x , p3.x -p4.x , p3.y -p1.y , p3.y -p4.y ) / delta;
373
+ if ( lameda > 1 || lameda < 0 ) {
374
+ return false ;
375
+ }
376
+ float miu = determinant (p2.x -p1.x , p3.x -p1.x , p2.y -p1.y , p3.y -p1.y ) / delta;
377
+ if ( miu > 1 || miu < 0 ) {
378
+ return false ;
379
+ }
380
+ return true ;
381
+ }
382
+
383
+ void Utilities::getClosestPoint (pcl::PointXY p1, pcl::PointXY p2,
384
+ pcl::PointXY p, pcl::PointXY &pc)
385
+ {
386
+ float A = p1.x - p2.x ;
387
+ float B = p1.y - p2.y ;
388
+
389
+ if (A == 0 ) {
390
+ pc.x = p1.x ;
391
+ pc.y = p.y ;
392
+ return ;
393
+ }
394
+ if (B == 0 ) {
395
+ pc.x = p.x ;
396
+ pc.y = p1.y ;
397
+ return ;
398
+ }
399
+
400
+ pc.x = (A*(A*p.x + B*p.y )/B - A*p1.y + B*p1.x )/(B + A*A/B);
401
+ pc.y = B*(pc.x - p1.x )/A + p1.y ;
402
+ }
403
+
404
+ float Utilities::pointToSegDist (float x, float y, float x1, float y1, float x2, float y2)
405
+ {
406
+ float cross = (x2 - x1) * (x - x1) + (y2 - y1) * (y - y1);
407
+ if (cross <= 0 )
408
+ return sqrt ((x - x1) * (x - x1) + (y - y1) * (y - y1));
409
+
410
+ float d2 = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
411
+ if (cross >= d2)
412
+ return sqrt ((x - x2) * (x - x2) + (y - y2) * (y - y2));
413
+
414
+ float r = cross / d2;
415
+ float px = x1 + (x2 - x1) * r;
416
+ float py = y1 + (y2 - y1) * r;
417
+ return sqrt ((x - px) * (x - px) + (py - y) * (py - y));
418
+ }
0 commit comments