36 #include <visp3/core/vpCPUFeatures.h>
37 #include <visp3/mbt/vpMbtFaceDepthNormal.h>
38 #include <visp3/mbt/vpMbtTukeyEstimator.h>
40 #if defined(VISP_HAVE_PCL) && defined(VISP_HAVE_PCL_SEGMENTATION) && defined(VISP_HAVE_PCL_FILTERS) && defined(VISP_HAVE_PCL_COMMON)
41 #include <pcl/common/centroid.h>
42 #include <pcl/filters/extract_indices.h>
43 #include <pcl/segmentation/sac_segmentation.h>
46 #if defined __SSE2__ || defined _M_X64 || (defined _M_IX86_FP && _M_IX86_FP >= 2)
47 #include <emmintrin.h>
48 #define VISP_HAVE_SSE2 1
51 #define USE_SSE_CODE 1
52 #if VISP_HAVE_SSE2 && USE_SSE_CODE
60 : m_cam(), m_clippingFlag(
vpPolygon3D::NO_CLIPPING), m_distFarClip(100), m_distNearClip(0.001), m_hiddenFace(nullptr),
61 m_planeObject(), m_polygon(nullptr), m_useScanLine(false), m_faceActivated(false),
62 m_faceCentroidMethod(GEOMETRIC_CENTROID), m_faceDesiredCentroid(), m_faceDesiredNormal(),
63 m_featureEstimationMethod(ROBUST_FEATURE_ESTIMATION), m_isTrackedDepthNormalFace(true), m_isVisible(false),
64 m_listOfFaceLines(), m_planeCamera(),
65 m_pclPlaneEstimationMethod(2),
66 m_pclPlaneEstimationRansacMaxIter(200), m_pclPlaneEstimationRansacThreshold(0.001), m_polygonLines()
91 vpUniRand &rand_gen,
int polygon, std::string name)
94 PolygonLine polygon_line;
97 polygon_line.m_poly.setNbPoint(2);
98 polygon_line.m_poly.addPoint(0, P1);
99 polygon_line.m_poly.addPoint(1, P2);
105 polygon_line.m_p1 = &polygon_line.m_poly.p[0];
106 polygon_line.m_p2 = &polygon_line.m_poly.p[1];
111 bool already_here =
false;
150 #if defined(VISP_HAVE_PCL) && defined(VISP_HAVE_PCL_SEGMENTATION) && defined(VISP_HAVE_PCL_FILTERS) && defined(VISP_HAVE_PCL_COMMON)
153 const pcl::PointCloud<pcl::PointXYZ>::ConstPtr &point_cloud,
154 vpColVector &desired_features,
unsigned int stepX,
unsigned int stepY
155 #
if DEBUG_DISPLAY_DEPTH_NORMAL
158 std::vector<std::vector<vpImagePoint> > &roiPts_vec
165 if (width == 0 || height == 0)
168 std::vector<vpImagePoint> roiPts;
172 #
if DEBUG_DISPLAY_DEPTH_NORMAL
178 if (roiPts.size() <= 2) {
180 std::cerr <<
"Error: roiPts.size() <= 2 in computeDesiredFeatures" << std::endl;
188 unsigned int top = (
unsigned int)std::max<double>(0.0, bb.
getTop());
189 unsigned int bottom = (
unsigned int)std::min<double>((
double)height, std::max<double>(0.0, bb.
getBottom()));
190 unsigned int left = (
unsigned int)std::max<double>(0.0, bb.
getLeft());
191 unsigned int right = (
unsigned int)std::min<double>((
double)width, std::max<double>(0.0, bb.
getRight()));
199 pcl::PointCloud<pcl::PointXYZ>::Ptr point_cloud_face(
new pcl::PointCloud<pcl::PointXYZ>);
200 std::vector<double> point_cloud_face_vec, point_cloud_face_custom;
218 double prev_x, prev_y, prev_z;
221 double x = 0.0, y = 0.0;
222 for (
unsigned int i = top; i < bottom; i += stepY) {
223 for (
unsigned int j = left; j < right; j += stepX) {
224 if (
vpMeTracker::inRoiMask(mask, i, j) && pcl::isFinite((*point_cloud)(j, i)) && (*point_cloud)(j, i).z > 0 &&
225 (
m_useScanLine ? (i < m_hiddenFace->getMbScanLineRenderer().getPrimitiveIDs().getHeight() &&
226 j < m_hiddenFace->getMbScanLineRenderer().getPrimitiveIDs().getWidth() &&
231 point_cloud_face->push_back((*point_cloud)(j, i));
235 point_cloud_face_vec.push_back((*point_cloud)(j, i).x);
236 point_cloud_face_vec.push_back((*point_cloud)(j, i).y);
237 point_cloud_face_vec.push_back((*point_cloud)(j, i).z);
249 prev_z = (*point_cloud)(j, i).z;
253 point_cloud_face_custom.push_back(prev_x);
254 point_cloud_face_custom.push_back(x);
256 point_cloud_face_custom.push_back(prev_y);
257 point_cloud_face_custom.push_back(y);
259 point_cloud_face_custom.push_back(prev_z);
260 point_cloud_face_custom.push_back((*point_cloud)(j, i).z);
265 point_cloud_face_custom.push_back(x);
266 point_cloud_face_custom.push_back(y);
267 point_cloud_face_custom.push_back((*point_cloud)(j, i).z);
272 #if DEBUG_DISPLAY_DEPTH_NORMAL
273 debugImage[i][j] = 255;
280 if (checkSSE2 && push) {
281 point_cloud_face_custom.push_back(prev_x);
282 point_cloud_face_custom.push_back(prev_y);
283 point_cloud_face_custom.push_back(prev_z);
287 if (point_cloud_face->empty() && point_cloud_face_custom.empty() && point_cloud_face_vec.empty()) {
304 desired_normal, centroid_point);
319 unsigned int height,
const std::vector<vpColVector> &point_cloud,
320 vpColVector &desired_features,
unsigned int stepX,
unsigned int stepY
321 #
if DEBUG_DISPLAY_DEPTH_NORMAL
324 std::vector<std::vector<vpImagePoint> > &roiPts_vec
331 if (width == 0 || height == 0)
334 std::vector<vpImagePoint> roiPts;
338 #
if DEBUG_DISPLAY_DEPTH_NORMAL
344 if (roiPts.size() <= 2) {
346 std::cerr <<
"Error: roiPts.size() <= 2 in computeDesiredFeatures" << std::endl;
354 unsigned int top = (
unsigned int)std::max<double>(0.0, bb.
getTop());
355 unsigned int bottom = (
unsigned int)std::min<double>((
double)height, std::max<double>(0.0, bb.
getBottom()));
356 unsigned int left = (
unsigned int)std::max<double>(0.0, bb.
getLeft());
357 unsigned int right = (
unsigned int)std::min<double>((
double)width, std::max<double>(0.0, bb.
getRight()));
365 std::vector<double> point_cloud_face, point_cloud_face_custom;
377 double prev_x, prev_y, prev_z;
380 double x = 0.0, y = 0.0;
381 for (
unsigned int i = top; i < bottom; i += stepY) {
382 for (
unsigned int j = left; j < right; j += stepX) {
384 (
m_useScanLine ? (i < m_hiddenFace->getMbScanLineRenderer().getPrimitiveIDs().getHeight() &&
385 j < m_hiddenFace->getMbScanLineRenderer().getPrimitiveIDs().getWidth() &&
389 point_cloud_face.push_back(point_cloud[i * width + j][0]);
390 point_cloud_face.push_back(point_cloud[i * width + j][1]);
391 point_cloud_face.push_back(point_cloud[i * width + j][2]);
403 prev_z = point_cloud[i * width + j][2];
407 point_cloud_face_custom.push_back(prev_x);
408 point_cloud_face_custom.push_back(x);
410 point_cloud_face_custom.push_back(prev_y);
411 point_cloud_face_custom.push_back(y);
413 point_cloud_face_custom.push_back(prev_z);
414 point_cloud_face_custom.push_back(point_cloud[i * width + j][2]);
419 point_cloud_face_custom.push_back(x);
420 point_cloud_face_custom.push_back(y);
421 point_cloud_face_custom.push_back(point_cloud[i * width + j][2]);
425 #if DEBUG_DISPLAY_DEPTH_NORMAL
426 debugImage[i][j] = 255;
433 if (checkSSE2 && push) {
434 point_cloud_face_custom.push_back(prev_x);
435 point_cloud_face_custom.push_back(prev_y);
436 point_cloud_face_custom.push_back(prev_z);
440 if (point_cloud_face.empty() && point_cloud_face_custom.empty()) {
447 #if defined(VISP_HAVE_PCL) && defined(VISP_HAVE_PCL_SEGMENTATION) && defined(VISP_HAVE_PCL_FILTERS) && defined(VISP_HAVE_PCL_COMMON)
449 pcl::PointCloud<pcl::PointXYZ>::Ptr point_cloud_face_pcl(
new pcl::PointCloud<pcl::PointXYZ>);
450 point_cloud_face_pcl->reserve(point_cloud_face.size() / 3);
452 for (
size_t i = 0; i < point_cloud_face.size() / 3; i++) {
453 point_cloud_face_pcl->push_back(
454 pcl::PointXYZ(point_cloud_face[3 * i], point_cloud_face[3 * i + 1], point_cloud_face[3 * i + 2]));
466 desired_normal, centroid_point);
480 unsigned int height,
const vpMatrix &point_cloud,
481 vpColVector &desired_features,
unsigned int stepX,
unsigned int stepY
482 #
if DEBUG_DISPLAY_DEPTH_NORMAL
485 std::vector<std::vector<vpImagePoint> > &roiPts_vec
492 if (width == 0 || height == 0)
495 std::vector<vpImagePoint> roiPts;
499 #
if DEBUG_DISPLAY_DEPTH_NORMAL
505 if (roiPts.size() <= 2) {
507 std::cerr <<
"Error: roiPts.size() <= 2 in computeDesiredFeatures" << std::endl;
515 unsigned int top = (
unsigned int)std::max<double>(0.0, bb.
getTop());
516 unsigned int bottom = (
unsigned int)std::min<double>((
double)height, std::max<double>(0.0, bb.
getBottom()));
517 unsigned int left = (
unsigned int)std::max<double>(0.0, bb.
getLeft());
518 unsigned int right = (
unsigned int)std::min<double>((
double)width, std::max<double>(0.0, bb.
getRight()));
526 std::vector<double> point_cloud_face, point_cloud_face_custom;
538 double prev_x, prev_y, prev_z;
541 double x = 0.0, y = 0.0;
542 for (
unsigned int i = top; i < bottom; i += stepY) {
543 for (
unsigned int j = left; j < right; j += stepX) {
545 (
m_useScanLine ? (i < m_hiddenFace->getMbScanLineRenderer().getPrimitiveIDs().getHeight() &&
546 j < m_hiddenFace->getMbScanLineRenderer().getPrimitiveIDs().getWidth() &&
550 point_cloud_face.push_back(point_cloud[i * width + j][0]);
551 point_cloud_face.push_back(point_cloud[i * width + j][1]);
552 point_cloud_face.push_back(point_cloud[i * width + j][2]);
564 prev_z = point_cloud[i * width + j][2];
568 point_cloud_face_custom.push_back(prev_x);
569 point_cloud_face_custom.push_back(x);
571 point_cloud_face_custom.push_back(prev_y);
572 point_cloud_face_custom.push_back(y);
574 point_cloud_face_custom.push_back(prev_z);
575 point_cloud_face_custom.push_back(point_cloud[i * width + j][2]);
580 point_cloud_face_custom.push_back(x);
581 point_cloud_face_custom.push_back(y);
582 point_cloud_face_custom.push_back(point_cloud[i * width + j][2]);
586 #if DEBUG_DISPLAY_DEPTH_NORMAL
587 debugImage[i][j] = 255;
594 if (checkSSE2 && push) {
595 point_cloud_face_custom.push_back(prev_x);
596 point_cloud_face_custom.push_back(prev_y);
597 point_cloud_face_custom.push_back(prev_z);
601 if (point_cloud_face.empty() && point_cloud_face_custom.empty()) {
608 #if defined(VISP_HAVE_PCL) && defined(VISP_HAVE_PCL_SEGMENTATION) && defined(VISP_HAVE_PCL_FILTERS) && defined(VISP_HAVE_PCL_COMMON)
610 pcl::PointCloud<pcl::PointXYZ>::Ptr point_cloud_face_pcl(
new pcl::PointCloud<pcl::PointXYZ>);
611 point_cloud_face_pcl->reserve(point_cloud_face.size() / 3);
613 for (
size_t i = 0; i < point_cloud_face.size() / 3; i++) {
614 point_cloud_face_pcl->push_back(
615 pcl::PointXYZ(point_cloud_face[3 * i], point_cloud_face[3 * i + 1], point_cloud_face[3 * i + 2]));
627 desired_normal, centroid_point);
639 #if defined(VISP_HAVE_PCL) && defined(VISP_HAVE_PCL_SEGMENTATION) && defined(VISP_HAVE_PCL_FILTERS) && defined(VISP_HAVE_PCL_COMMON)
646 pcl::ModelCoefficients::Ptr coefficients(
new pcl::ModelCoefficients);
647 pcl::PointIndices::Ptr inliers(
new pcl::PointIndices);
649 pcl::SACSegmentation<pcl::PointXYZ> seg;
651 seg.setOptimizeCoefficients(
true);
653 seg.setModelType(pcl::SACMODEL_PLANE);
658 seg.setInputCloud(point_cloud_face);
659 seg.segment(*inliers, *coefficients);
661 pcl::PointCloud<pcl::PointXYZ>::Ptr point_cloud_face_extracted(
new pcl::PointCloud<pcl::PointXYZ>);
663 pcl::ExtractIndices<pcl::PointXYZ> extract;
666 extract.setInputCloud(point_cloud_face);
667 extract.setIndices(inliers);
668 extract.setNegative(
false);
669 extract.filter(*point_cloud_face_extracted);
671 #if PCL_VERSION_COMPARE(>=, 1, 7, 2)
672 pcl::PointXYZ centroid_point_pcl;
673 if (pcl::computeCentroid(*point_cloud_face_extracted, centroid_point_pcl)) {
674 pcl::PointXYZ face_normal;
676 centroid_point_pcl, face_normal);
678 desired_features.
resize(3,
false);
679 desired_features[0] = -coefficients->values[0] / coefficients->values[3];
680 desired_features[1] = -coefficients->values[1] / coefficients->values[3];
681 desired_features[2] = -coefficients->values[2] / coefficients->values[3];
683 desired_normal[0] = face_normal.x;
684 desired_normal[1] = face_normal.y;
685 desired_normal[2] = face_normal.z;
687 centroid_point[0] = centroid_point_pcl.x;
688 centroid_point[1] = centroid_point_pcl.y;
689 centroid_point[2] = centroid_point_pcl.z;
692 std::cerr <<
"Cannot compute centroid!" << std::endl;
696 std::cerr <<
"Cannot compute centroid using PCL " << PCL_VERSION_PRETTY <<
"!" << std::endl;
700 catch (
const pcl::PCLException &e) {
701 std::cerr <<
"Catch a PCL exception: " << e.what() << std::endl;
710 const std::vector<double> &point_cloud_face,
716 std::vector<double> weights;
721 for (
size_t i = 0; i < point_cloud_face.size() / 3; i++) {
722 centroid_point[0] += weights[i] * point_cloud_face[3 * i];
723 centroid_point[1] += weights[i] * point_cloud_face[3 * i + 1];
724 centroid_point[2] += weights[i] * point_cloud_face[3 * i + 2];
729 centroid_point[0] /= den;
730 centroid_point[1] /= den;
731 centroid_point[2] /= den;
744 desired_features.
resize(3,
false);
745 desired_features[0] = -plane_equation_SVD[0] / plane_equation_SVD[3];
746 desired_features[1] = -plane_equation_SVD[1] / plane_equation_SVD[3];
747 desired_features[2] = -plane_equation_SVD[2] / plane_equation_SVD[3];
759 centroid_cam[0] = centroid_point[0];
760 centroid_cam[1] = centroid_point[1];
761 centroid_cam[2] = centroid_point[2];
769 face_normal_cam[0] = desired_normal[0];
770 face_normal_cam[1] = desired_normal[1];
771 face_normal_cam[2] = desired_normal[2];
772 face_normal_cam[3] = 1;
780 if (points_.empty()) {
784 if (points_.size() < 2) {
785 centroid = points_[0];
789 std::vector<vpPoint> points = points_;
790 points.push_back(points_.front());
792 double A1 = 0.0, A2 = 0.0, c_x1 = 0.0, c_x2 = 0.0, c_y = 0.0, c_z = 0.0;
794 for (
size_t i = 0; i < points.size() - 1; i++) {
796 c_x1 += (points[i].get_X() + points[i + 1].get_X()) *
797 (points[i].get_X() * points[i + 1].get_Y() - points[i + 1].get_X() * points[i].get_Y());
798 c_y += (points[i].get_Y() + points[i + 1].get_Y()) *
799 (points[i].get_X() * points[i + 1].get_Y() - points[i + 1].get_X() * points[i].get_Y());
800 A1 += points[i].
get_X() * points[i + 1].get_Y() - points[i + 1].get_X() * points[i].get_Y();
803 c_x2 += (points[i].get_X() + points[i + 1].get_X()) *
804 (points[i].get_X() * points[i + 1].get_Z() - points[i + 1].get_X() * points[i].get_Z());
805 c_z += (points[i].get_Z() + points[i + 1].get_Z()) *
806 (points[i].get_X() * points[i + 1].get_Z() - points[i + 1].get_X() * points[i].get_Z());
807 A2 += points[i].get_X() * points[i + 1].get_Z() - points[i + 1].get_X() * points[i].get_Z();
816 centroid.
set_X(c_x1);
819 centroid.
set_X(c_x2);
829 std::vector<vpImagePoint> &roiPts
830 #
if DEBUG_DISPLAY_DEPTH_NORMAL
832 std::vector<std::vector<vpImagePoint> > &roiPts_vec
841 it->m_p1->changeFrame(cMo);
842 it->m_p2->changeFrame(cMo);
846 it->m_poly.changeFrame(cMo);
847 it->m_poly.computePolygonClipped(
m_cam);
849 if (it->m_poly.polyClipped.size() == 2 &&
857 std::vector<std::pair<vpPoint, vpPoint> > linesLst;
861 for (
unsigned int i = 0; i < linesLst.size(); i++) {
862 linesLst[i].first.project();
863 linesLst[i].second.project();
871 roiPts.push_back(ip1);
872 roiPts.push_back(ip2);
874 #if DEBUG_DISPLAY_DEPTH_NORMAL
875 std::vector<vpImagePoint> roiPts_;
876 roiPts_.push_back(ip1);
877 roiPts_.push_back(ip2);
878 roiPts_vec.push_back(roiPts_);
888 #if DEBUG_DISPLAY_DEPTH_NORMAL
889 roiPts_vec.push_back(roiPts);
903 bool isvisible =
false;
907 int index = *itindex;
942 std::vector<vpImagePoint> roiPts;
945 std::vector<vpPoint> polyPts;
953 e4[0] = -centroid.
get_X();
954 e4[1] = -centroid.
get_Y();
955 e4[2] = -centroid.
get_Z();
959 double centroid_x = 0.0;
960 double centroid_y = 0.0;
961 double centroid_z = 0.0;
963 for (
size_t i = 0; i < polyPts.size(); i++) {
964 centroid_x += polyPts[i].get_X();
965 centroid_y += polyPts[i].get_Y();
966 centroid_z += polyPts[i].get_Z();
969 centroid_x /= polyPts.
size();
970 centroid_y /= polyPts.size();
971 centroid_z /= polyPts.size();
978 centroid.
set_X(centroid_x);
979 centroid.
set_Y(centroid_y);
980 centroid.
set_Z(centroid_z);
983 correct_normal.
resize(3,
false);
985 if (angle < M_PI_2) {
986 correct_normal = faceNormal;
989 correct_normal[0] = -faceNormal[0];
990 correct_normal[1] = -faceNormal[1];
991 correct_normal[2] = -faceNormal[2];
995 #if defined(VISP_HAVE_PCL) && defined(VISP_HAVE_PCL_SEGMENTATION) && defined(VISP_HAVE_PCL_FILTERS) && defined(VISP_HAVE_PCL_COMMON)
997 pcl::PointXYZ &face_normal)
1006 e4[0] = -centroid_point.x;
1007 e4[1] = -centroid_point.y;
1008 e4[2] = -centroid_point.z;
1012 if (angle < M_PI_2) {
1013 face_normal = pcl::PointXYZ(faceNormal[0], faceNormal[1], faceNormal[2]);
1016 face_normal = pcl::PointXYZ(-faceNormal[0], -faceNormal[1], -faceNormal[2]);
1024 face_normal.
resize(3,
false);
1025 face_normal[0] = nx;
1026 face_normal[1] = ny;
1027 face_normal[2] = nz;
1034 if (angle >= M_PI_2) {
1035 face_normal[0] = -face_normal[0];
1036 face_normal[1] = -face_normal[1];
1037 face_normal[2] = -face_normal[2];
1053 std::vector<vpPoint> polyPts;
1059 c[0] = centroid.
get_X();
1060 c[1] = centroid.
get_Y();
1061 c[2] = centroid.
get_Z();
1063 const double minD = L * cos(maxAngle);
1064 return fabs(D) <= minD;
1069 L.resize(3, 6,
false,
false);
1082 features.
resize(3,
false);
1083 features[0] = -ux / D;
1084 features[1] = -uy / D;
1085 features[2] = -uz / D;
1088 L[0][0] = ux * ux / D2;
1089 L[0][1] = ux * uy / D2;
1090 L[0][2] = ux * uz / D2;
1096 L[1][0] = ux * uy / D2;
1097 L[1][1] = uy * uy / D2;
1098 L[1][2] = uy * uz / D2;
1104 L[2][0] = ux * uz / D2;
1105 L[2][1] = uy * uz / D2;
1106 L[2][2] = uz * uz / D2;
1114 bool displayFullModel)
1116 std::vector<std::vector<double> > models =
1119 for (
size_t i = 0; i < models.size(); i++) {
1128 bool displayFullModel)
1130 std::vector<std::vector<double> > models =
1133 for (
size_t i = 0; i < models.size(); i++) {
1184 pt_extremity.
set_X(pt_centroid.
get_X() + correct_normal[0] * scale);
1185 pt_extremity.
set_Y(pt_centroid.
get_Y() + correct_normal[1] * scale);
1186 pt_extremity.
set_Z(pt_centroid.
get_Z() + correct_normal[2] * scale);
1239 pt_extremity.
set_X(pt_centroid.
get_X() + correct_normal[0] * scale);
1240 pt_extremity.
set_Y(pt_centroid.
get_Y() + correct_normal[1] * scale);
1241 pt_extremity.
set_Z(pt_centroid.
get_Z() + correct_normal[2] * scale);
1253 vpMbtTukeyEstimator<double> tukey_robust;
1254 std::vector<double> residues(point_cloud_face.size() / 3);
1256 w.resize(point_cloud_face.size() / 3, 1.0);
1258 unsigned int max_iter = 30, iter = 0;
1259 double error = 0.0, prev_error = -1.0;
1260 double A = 0.0, B = 0.0, C = 0.0;
1262 Mat33<double> ATA_3x3;
1271 while (std::fabs(error - prev_error) > 1e-6 && (iter < max_iter)) {
1288 if (point_cloud_face.size() / 3 >= 2) {
1289 const double *ptr_point_cloud = &point_cloud_face[0];
1290 const __m128d vA = _mm_set1_pd(A);
1291 const __m128d vB = _mm_set1_pd(B);
1292 const __m128d vC = _mm_set1_pd(C);
1293 const __m128d vones = _mm_set1_pd(1.0);
1295 double *ptr_residues = &residues[0];
1297 for (; cpt <= point_cloud_face.size() - 6; cpt += 6, ptr_point_cloud += 6, ptr_residues += 2) {
1298 const __m128d vxi = _mm_loadu_pd(ptr_point_cloud);
1299 const __m128d vyi = _mm_loadu_pd(ptr_point_cloud + 2);
1300 const __m128d vZi = _mm_loadu_pd(ptr_point_cloud + 4);
1301 const __m128d vinvZi = _mm_div_pd(vones, vZi);
1304 _mm_add_pd(_mm_add_pd(_mm_mul_pd(vA, vxi), _mm_mul_pd(vB, vyi)), _mm_sub_pd(vC, vinvZi));
1305 _mm_storeu_pd(ptr_residues, tmp);
1309 for (; cpt < point_cloud_face.size(); cpt += 3) {
1310 double xi = point_cloud_face[cpt];
1311 double yi = point_cloud_face[cpt + 1];
1312 double Zi = point_cloud_face[cpt + 2];
1314 residues[cpt / 3] = (A * xi + B * yi + C - 1 / Zi);
1318 tukey_robust.MEstimator(residues, w, 1e-2);
1320 __m128d vsum_wi2_xi2 = _mm_setzero_pd();
1321 __m128d vsum_wi2_yi2 = _mm_setzero_pd();
1322 __m128d vsum_wi2 = _mm_setzero_pd();
1323 __m128d vsum_wi2_xi_yi = _mm_setzero_pd();
1324 __m128d vsum_wi2_xi = _mm_setzero_pd();
1325 __m128d vsum_wi2_yi = _mm_setzero_pd();
1327 __m128d vsum_wi2_xi_Zi = _mm_setzero_pd();
1328 __m128d vsum_wi2_yi_Zi = _mm_setzero_pd();
1329 __m128d vsum_wi2_Zi = _mm_setzero_pd();
1333 if (point_cloud_face.size() / 3 >= 2) {
1334 const double *ptr_point_cloud = &point_cloud_face[0];
1335 double *ptr_w = &w[0];
1337 const __m128d vones = _mm_set1_pd(1.0);
1339 for (; cpt <= point_cloud_face.size() - 6; cpt += 6, ptr_point_cloud += 6, ptr_w += 2) {
1340 const __m128d vwi2 = _mm_mul_pd(_mm_loadu_pd(ptr_w), _mm_loadu_pd(ptr_w));
1342 const __m128d vxi = _mm_loadu_pd(ptr_point_cloud);
1343 const __m128d vyi = _mm_loadu_pd(ptr_point_cloud + 2);
1344 const __m128d vZi = _mm_loadu_pd(ptr_point_cloud + 4);
1345 const __m128d vinvZi = _mm_div_pd(vones, vZi);
1347 vsum_wi2_xi2 = _mm_add_pd(vsum_wi2_xi2, _mm_mul_pd(vwi2, _mm_mul_pd(vxi, vxi)));
1348 vsum_wi2_yi2 = _mm_add_pd(vsum_wi2_yi2, _mm_mul_pd(vwi2, _mm_mul_pd(vyi, vyi)));
1349 vsum_wi2 = _mm_add_pd(vsum_wi2, vwi2);
1350 vsum_wi2_xi_yi = _mm_add_pd(vsum_wi2_xi_yi, _mm_mul_pd(vwi2, _mm_mul_pd(vxi, vyi)));
1351 vsum_wi2_xi = _mm_add_pd(vsum_wi2_xi, _mm_mul_pd(vwi2, vxi));
1352 vsum_wi2_yi = _mm_add_pd(vsum_wi2_yi, _mm_mul_pd(vwi2, vyi));
1354 const __m128d vwi2_invZi = _mm_mul_pd(vwi2, vinvZi);
1355 vsum_wi2_xi_Zi = _mm_add_pd(vsum_wi2_xi_Zi, _mm_mul_pd(vxi, vwi2_invZi));
1356 vsum_wi2_yi_Zi = _mm_add_pd(vsum_wi2_yi_Zi, _mm_mul_pd(vyi, vwi2_invZi));
1357 vsum_wi2_Zi = _mm_add_pd(vsum_wi2_Zi, vwi2_invZi);
1362 _mm_storeu_pd(vtmp, vsum_wi2_xi2);
1363 double sum_wi2_xi2 = vtmp[0] + vtmp[1];
1365 _mm_storeu_pd(vtmp, vsum_wi2_yi2);
1366 double sum_wi2_yi2 = vtmp[0] + vtmp[1];
1368 _mm_storeu_pd(vtmp, vsum_wi2);
1369 double sum_wi2 = vtmp[0] + vtmp[1];
1371 _mm_storeu_pd(vtmp, vsum_wi2_xi_yi);
1372 double sum_wi2_xi_yi = vtmp[0] + vtmp[1];
1374 _mm_storeu_pd(vtmp, vsum_wi2_xi);
1375 double sum_wi2_xi = vtmp[0] + vtmp[1];
1377 _mm_storeu_pd(vtmp, vsum_wi2_yi);
1378 double sum_wi2_yi = vtmp[0] + vtmp[1];
1380 _mm_storeu_pd(vtmp, vsum_wi2_xi_Zi);
1381 double sum_wi2_xi_Zi = vtmp[0] + vtmp[1];
1383 _mm_storeu_pd(vtmp, vsum_wi2_yi_Zi);
1384 double sum_wi2_yi_Zi = vtmp[0] + vtmp[1];
1386 _mm_storeu_pd(vtmp, vsum_wi2_Zi);
1387 double sum_wi2_Zi = vtmp[0] + vtmp[1];
1389 for (; cpt < point_cloud_face.size(); cpt += 3) {
1390 double wi2 = w[cpt / 3] * w[cpt / 3];
1392 double xi = point_cloud_face[cpt];
1393 double yi = point_cloud_face[cpt + 1];
1394 double Zi = point_cloud_face[cpt + 2];
1395 double invZi = 1.0 / Zi;
1397 sum_wi2_xi2 += wi2 * xi * xi;
1398 sum_wi2_yi2 += wi2 * yi * yi;
1400 sum_wi2_xi_yi += wi2 * xi * yi;
1401 sum_wi2_xi += wi2 * xi;
1402 sum_wi2_yi += wi2 * yi;
1404 sum_wi2_xi_Zi += wi2 * xi * invZi;
1405 sum_wi2_yi_Zi += wi2 * yi * invZi;
1406 sum_wi2_Zi += wi2 * invZi;
1409 ATA_3x3[0] = sum_wi2_xi2;
1410 ATA_3x3[1] = sum_wi2_xi_yi;
1411 ATA_3x3[2] = sum_wi2_xi;
1412 ATA_3x3[3] = sum_wi2_xi_yi;
1413 ATA_3x3[4] = sum_wi2_yi2;
1414 ATA_3x3[5] = sum_wi2_yi;
1415 ATA_3x3[6] = sum_wi2_xi;
1416 ATA_3x3[7] = sum_wi2_yi;
1417 ATA_3x3[8] = sum_wi2;
1419 Mat33<double> minv = ATA_3x3.inverse();
1421 A = minv[0] * sum_wi2_xi_Zi + minv[1] * sum_wi2_yi_Zi + minv[2] * sum_wi2_Zi;
1422 B = minv[3] * sum_wi2_xi_Zi + minv[4] * sum_wi2_yi_Zi + minv[5] * sum_wi2_Zi;
1423 C = minv[6] * sum_wi2_xi_Zi + minv[7] * sum_wi2_yi_Zi + minv[8] * sum_wi2_Zi;
1431 __m128d verror = _mm_set1_pd(0.0);
1432 if (point_cloud_face.size() / 3 >= 2) {
1433 const double *ptr_point_cloud = &point_cloud_face[0];
1434 const __m128d vA = _mm_set1_pd(A);
1435 const __m128d vB = _mm_set1_pd(B);
1436 const __m128d vC = _mm_set1_pd(C);
1437 const __m128d vones = _mm_set1_pd(1.0);
1439 double *ptr_residues = &residues[0];
1441 for (; cpt <= point_cloud_face.size() - 6; cpt += 6, ptr_point_cloud += 6, ptr_residues += 2) {
1442 const __m128d vxi = _mm_loadu_pd(ptr_point_cloud);
1443 const __m128d vyi = _mm_loadu_pd(ptr_point_cloud + 2);
1444 const __m128d vZi = _mm_loadu_pd(ptr_point_cloud + 4);
1445 const __m128d vinvZi = _mm_div_pd(vones, vZi);
1447 const __m128d tmp = _mm_add_pd(_mm_add_pd(_mm_mul_pd(vA, vxi), _mm_mul_pd(vB, vyi)), _mm_sub_pd(vC, vinvZi));
1448 verror = _mm_add_pd(verror, _mm_mul_pd(tmp, tmp));
1450 _mm_storeu_pd(ptr_residues, tmp);
1454 _mm_storeu_pd(vtmp, verror);
1455 error = vtmp[0] + vtmp[1];
1457 for (
size_t idx = cpt; idx < point_cloud_face.size(); idx += 3) {
1458 double xi = point_cloud_face[idx];
1459 double yi = point_cloud_face[idx + 1];
1460 double Zi = point_cloud_face[idx + 2];
1462 error +=
vpMath::sqr(A * xi + B * yi + C - 1 / Zi);
1463 residues[idx / 3] = (A * xi + B * yi + C - 1 / Zi);
1466 error /= point_cloud_face.size() / 3;
1473 while (std::fabs(error - prev_error) > 1e-6 && (iter < max_iter)) {
1489 for (
size_t i = 0; i < point_cloud_face.size() / 3; i++) {
1490 double xi = point_cloud_face[3 * i];
1491 double yi = point_cloud_face[3 * i + 1];
1492 double Zi = point_cloud_face[3 * i + 2];
1494 residues[i] = (A * xi + B * yi + C - 1 / Zi);
1498 tukey_robust.MEstimator(residues, w, 1e-2);
1501 double sum_wi2_xi2 = 0.0, sum_wi2_yi2 = 0.0, sum_wi2 = 0.0;
1502 double sum_wi2_xi_yi = 0.0, sum_wi2_xi = 0.0, sum_wi2_yi = 0.0;
1504 double sum_wi2_xi_Zi = 0.0, sum_wi2_yi_Zi = 0.0, sum_wi2_Zi = 0.0;
1506 for (
size_t i = 0; i < point_cloud_face.size() / 3; i++) {
1507 double wi2 = w[i] * w[i];
1509 double xi = point_cloud_face[3 * i];
1510 double yi = point_cloud_face[3 * i + 1];
1511 double Zi = point_cloud_face[3 * i + 2];
1512 double invZi = 1 / Zi;
1514 sum_wi2_xi2 += wi2 * xi * xi;
1515 sum_wi2_yi2 += wi2 * yi * yi;
1517 sum_wi2_xi_yi += wi2 * xi * yi;
1518 sum_wi2_xi += wi2 * xi;
1519 sum_wi2_yi += wi2 * yi;
1521 sum_wi2_xi_Zi += wi2 * xi * invZi;
1522 sum_wi2_yi_Zi += wi2 * yi * invZi;
1523 sum_wi2_Zi += wi2 * invZi;
1526 ATA_3x3[0] = sum_wi2_xi2;
1527 ATA_3x3[1] = sum_wi2_xi_yi;
1528 ATA_3x3[2] = sum_wi2_xi;
1529 ATA_3x3[3] = sum_wi2_xi_yi;
1530 ATA_3x3[4] = sum_wi2_yi2;
1531 ATA_3x3[5] = sum_wi2_yi;
1532 ATA_3x3[6] = sum_wi2_xi;
1533 ATA_3x3[7] = sum_wi2_yi;
1534 ATA_3x3[8] = sum_wi2;
1536 Mat33<double> minv = ATA_3x3.inverse();
1538 A = minv[0] * sum_wi2_xi_Zi + minv[1] * sum_wi2_yi_Zi + minv[2] * sum_wi2_Zi;
1539 B = minv[3] * sum_wi2_xi_Zi + minv[4] * sum_wi2_yi_Zi + minv[5] * sum_wi2_Zi;
1540 C = minv[6] * sum_wi2_xi_Zi + minv[7] * sum_wi2_yi_Zi + minv[8] * sum_wi2_Zi;
1546 for (
size_t i = 0; i < point_cloud_face.size() / 3; i++) {
1547 double xi = point_cloud_face[3 * i];
1548 double yi = point_cloud_face[3 * i + 1];
1549 double Zi = point_cloud_face[3 * i + 2];
1551 error +=
vpMath::sqr(A * xi + B * yi + C - 1 / Zi);
1552 residues[i] = (A * xi + B * yi + C - 1 / Zi);
1555 error /= point_cloud_face.size() / 3;
1561 x_estimated.
resize(3,
false);
1571 unsigned int max_iter = 10;
1572 double prev_error = 1e3;
1573 double error = 1e3 - 1;
1575 std::vector<double> weights(point_cloud_face.size() / 3, 1.0);
1576 std::vector<double> residues(point_cloud_face.size() / 3);
1577 vpMatrix M((
unsigned int)(point_cloud_face.size() / 3), 3);
1578 vpMbtTukeyEstimator<double> tukey;
1581 for (
unsigned int iter = 0; iter < max_iter && std::fabs(error - prev_error) > 1e-6; iter++) {
1583 tukey.MEstimator(residues, weights, 1e-4);
1596 for (
size_t i = 0; i < point_cloud_face.size() / 3; i++) {
1597 residues[i] = std::fabs(A * point_cloud_face[3 * i] + B * point_cloud_face[3 * i + 1] +
1598 C * point_cloud_face[3 * i + 2] + D) /
1599 sqrt(A * A + B * B + C * C);
1602 tukey.MEstimator(residues, weights, 1e-4);
1603 plane_equation_estimated.
resize(4,
false);
1607 double centroid_x = 0.0, centroid_y = 0.0, centroid_z = 0.0;
1608 double total_w = 0.0;
1610 for (
size_t i = 0; i < point_cloud_face.size() / 3; i++) {
1611 centroid_x += weights[i] * point_cloud_face[3 * i];
1612 centroid_y += weights[i] * point_cloud_face[3 * i + 1];
1613 centroid_z += weights[i] * point_cloud_face[3 * i + 2];
1614 total_w += weights[i];
1617 centroid_x /= total_w;
1618 centroid_y /= total_w;
1619 centroid_z /= total_w;
1622 for (
size_t i = 0; i < point_cloud_face.size() / 3; i++) {
1623 M[(
unsigned int)i][0] = weights[i] * (point_cloud_face[3 * i] - centroid_x);
1624 M[(
unsigned int)i][1] = weights[i] * (point_cloud_face[3 * i + 1] - centroid_y);
1625 M[(
unsigned int)i][2] = weights[i] * (point_cloud_face[3 * i + 2] - centroid_z);
1634 double smallestSv = W[0];
1635 unsigned int indexSmallestSv = 0;
1636 for (
unsigned int i = 1; i < W.
size(); i++) {
1637 if (W[i] < smallestSv) {
1639 indexSmallestSv = i;
1643 normal = V.
getCol(indexSmallestSv);
1646 double A = normal[0], B = normal[1], C = normal[2];
1647 double D = -(A * centroid_x + B * centroid_y + C * centroid_z);
1650 plane_equation_estimated[0] = A;
1651 plane_equation_estimated[1] = B;
1652 plane_equation_estimated[2] = C;
1653 plane_equation_estimated[3] = D;
1658 for (
size_t i = 0; i < point_cloud_face.size() / 3; i++) {
1659 residues[i] = std::fabs(A * point_cloud_face[3 * i] + B * point_cloud_face[3 * i + 1] +
1660 C * point_cloud_face[3 * i + 2] + D) /
1661 sqrt(A * A + B * B + C * C);
1662 error += weights[i] * residues[i];
1668 tukey.MEstimator(residues, weights, 1e-4);
1671 centroid.
resize(3,
false);
1672 double total_w = 0.0;
1674 for (
size_t i = 0; i < point_cloud_face.size() / 3; i++) {
1675 centroid[0] += weights[i] * point_cloud_face[3 * i];
1676 centroid[1] += weights[i] * point_cloud_face[3 * i + 1];
1677 centroid[2] += weights[i] * point_cloud_face[3 * i + 2];
1678 total_w += weights[i];
1681 centroid[0] /= total_w;
1682 centroid[1] /= total_w;
1683 centroid[2] /= total_w;
1686 double A = normal[0], B = normal[1], C = normal[2];
1687 double D = -(A * centroid[0] + B * centroid[1] + C * centroid[2]);
1690 plane_equation_estimated[0] = A;
1691 plane_equation_estimated[1] = B;
1692 plane_equation_estimated[2] = C;
1693 plane_equation_estimated[3] = D;
1701 std::vector<std::vector<double> >
1704 std::vector<std::vector<double> > features;
1729 #if (VISP_CXX_STANDARD > VISP_CXX_STANDARD_98)
1730 std::vector<double> params = { 2,
1731 im_centroid.
get_i(),
1732 im_centroid.
get_j(),
1733 im_extremity.
get_i(),
1734 im_extremity.
get_j() };
1736 std::vector<double> params;
1737 params.push_back(2);
1738 params.push_back(im_centroid.
get_i());
1739 params.push_back(im_centroid.
get_j());
1740 params.push_back(im_extremity.
get_i());
1741 params.push_back(im_extremity.
get_j());
1743 features.push_back(params);
1761 pt_extremity.
set_X(pt_centroid.
get_X() + correct_normal[0] * scale);
1762 pt_extremity.
set_Y(pt_centroid.
get_Y() + correct_normal[1] * scale);
1763 pt_extremity.
set_Z(pt_centroid.
get_Z() + correct_normal[2] * scale);
1769 #if (VISP_CXX_STANDARD > VISP_CXX_STANDARD_98)
1770 std::vector<double> params = { 3,
1771 im_centroid.
get_i(),
1772 im_centroid.
get_j(),
1773 im_extremity.
get_i(),
1774 im_extremity.
get_j() };
1776 std::vector<double> params;
1777 params.push_back(3);
1778 params.push_back(im_centroid.
get_i());
1779 params.push_back(im_centroid.
get_j());
1780 params.push_back(im_extremity.
get_i());
1781 params.push_back(im_extremity.
get_j());
1783 features.push_back(params);
1804 bool displayFullModel)
1806 std::vector<std::vector<double> > models;
1814 std::vector<std::vector<double> > lineModels =
1816 models.insert(models.end(), lineModels.begin(), lineModels.end());
1838 if (dx <= std::numeric_limits<double>::epsilon() && dy <= std::numeric_limits<double>::epsilon() &&
1839 dz <= std::numeric_limits<double>::epsilon())
1851 (*it)->setCameraParameters(camera);
1861 (*it)->useScanLine = v;
unsigned int size() const
Return the number of elements of the 2D array.
Generic class defining intrinsic camera parameters.
void computeFov(const unsigned int &w, const unsigned int &h)
Implementation of column vector and the associated operations.
static double dotProd(const vpColVector &a, const vpColVector &b)
vpColVector & normalize()
double frobeniusNorm() const
void resize(unsigned int i, bool flagNullify=true)
Class to define RGB colors available for display functionalities.
static const vpColor blue
static void displayLine(const vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1, bool segment=true)
static void displayArrow(const vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color=vpColor::white, unsigned int w=4, unsigned int h=2, unsigned int thickness=1)
error that can be emitted by ViSP classes.
@ badValue
Used to indicate that a value is not in the allowed range.
Implementation of an homogeneous matrix and operations on such kind of matrices.
vpHomogeneousMatrix inverse() const
vpTranslationVector getTranslationVector() const
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
unsigned int getWidth() const
unsigned int getHeight() const
static double sqr(double x)
Implementation of a matrix and operations on matrices.
void svd(vpColVector &w, vpMatrix &V)
vpColVector getCol(unsigned int j) const
vpMbScanLine & getMbScanLineRenderer()
bool isVisible(unsigned int i)
void computeScanLineQuery(const vpPoint &a, const vpPoint &b, std::vector< std::pair< vpPoint, vpPoint > > &lines, const bool &displayResults=false)
Manage the line of a polygon used in the model-based tracker.
void setIndex(unsigned int i)
vpPoint * p2
The second extremity.
std::list< int > Lindex_polygon
Index of the faces which contain the line.
void buildFrom(vpPoint &_p1, vpPoint &_p2, vpUniRand &rand_gen)
vpMbHiddenFaces< vpMbtPolygon > * hiddenface
Pointer to the list of faces.
std::vector< std::vector< double > > getModelForDisplay(unsigned int width, unsigned int height, const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, bool displayFullModel=false)
bool useScanLine
Use scanline rendering.
vpPoint * p1
The first extremity.
void setCameraParameters(const vpCameraParameters &camera)
void setName(const std::string &line_name)
void setVisible(bool _isvisible)
void addPolygon(const int &index)
vpMbtPolygon & getPolygon()
double m_pclPlaneEstimationRansacThreshold
PCL plane estimation RANSAC threshold.
int m_pclPlaneEstimationMethod
PCL plane estimation method.
double m_distNearClip
Distance for near clipping.
void computeInteractionMatrix(const vpHomogeneousMatrix &cMo, vpMatrix &L, vpColVector &features)
std::vector< std::vector< double > > getModelForDisplay(unsigned int width, unsigned int height, const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, bool displayFullModel=false)
void addLine(vpPoint &p1, vpPoint &p2, vpMbHiddenFaces< vpMbtPolygon > *const faces, vpUniRand &rand_gen, int polygon=-1, std::string name="")
void setCameraParameters(const vpCameraParameters &camera)
void computeDesiredFeaturesSVD(const std::vector< double > &point_cloud_face, const vpHomogeneousMatrix &cMo, vpColVector &desired_features, vpColVector &desired_normal, vpColVector ¢roid_point)
double m_distFarClip
Distance for near clipping.
bool samePoint(const vpPoint &P1, const vpPoint &P2) const
void displayFeature(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, double scale=0.05, unsigned int thickness=1)
vpMbHiddenFaces< vpMbtPolygon > * m_hiddenFace
Pointer to the list of faces.
std::vector< std::vector< double > > getFeaturesForDisplay(const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, double scale=0.05)
bool computePolygonCentroid(const std::vector< vpPoint > &points, vpPoint ¢roid)
void computeROI(const vpHomogeneousMatrix &cMo, unsigned int width, unsigned int height, std::vector< vpImagePoint > &roiPts)
void setScanLineVisibilityTest(bool v)
void estimatePlaneEquationSVD(const std::vector< double > &point_cloud_face, const vpHomogeneousMatrix &cMo, vpColVector &plane_equation_estimated, vpColVector ¢roid)
std::vector< vpMbtDistanceLine * > m_listOfFaceLines
void computeDesiredNormalAndCentroid(const vpHomogeneousMatrix &cMo, const vpColVector &desired_normal, const vpColVector ¢roid_point)
bool m_isTrackedDepthNormalFace
vpFeatureEstimationType m_featureEstimationMethod
Method to estimate the desired features.
vpMbtPolygon * m_polygon
Polygon defining the face.
vpPoint m_faceDesiredCentroid
Desired centroid (computed from the sensor)
void display(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, const vpColor &col, unsigned int thickness=1, bool displayFullModel=false)
vpCameraParameters m_cam
Camera intrinsic parameters.
@ ROBUST_FEATURE_ESTIMATION
Robust scheme to estimate the normal of the plane.
@ ROBUST_SVD_PLANE_ESTIMATION
Use SVD and robust scheme to estimate the normal of the plane.
@ PCL_PLANE_ESTIMATION
Use PCL to estimate the normal of the plane.
vpPlane m_planeObject
Plane equation described in the object frame.
void computeVisibilityDisplay()
bool m_faceActivated
True if the face should be considered by the tracker.
@ GEOMETRIC_CENTROID
Compute the geometric centroid.
vpFaceCentroidType m_faceCentroidMethod
Method to compute the face centroid for the current features.
bool planeIsInvalid(const vpHomogeneousMatrix &cMo, double maxAngle)
int m_pclPlaneEstimationRansacMaxIter
PCL pane estimation max number of iterations.
unsigned int m_clippingFlag
Flags specifying which clipping to used.
void computeDesiredFeaturesRobustFeatures(const std::vector< double > &point_cloud_face_custom, const std::vector< double > &point_cloud_face, const vpHomogeneousMatrix &cMo, vpColVector &desired_features, vpColVector &desired_normal, vpColVector ¢roid_point)
vpPoint m_faceDesiredNormal
Face (normalized) normal (computed from the sensor)
void estimateFeatures(const std::vector< double > &point_cloud_face, const vpHomogeneousMatrix &cMo, vpColVector &x_estimated, std::vector< double > &weights)
virtual ~vpMbtFaceDepthNormal()
std::vector< PolygonLine > m_polygonLines
bool computeDesiredFeaturesPCL(const pcl::PointCloud< pcl::PointXYZ >::ConstPtr &point_cloud_face, vpColVector &desired_features, vpColVector &desired_normal, vpColVector ¢roid_point)
void computeNormalVisibility(double nx, double ny, double nz, const vpColVector ¢roid_point, vpColVector &face_normal)
bool m_useScanLine
Scan line visibility.
bool computeDesiredFeatures(const vpHomogeneousMatrix &cMo, unsigned int width, unsigned int height, const pcl::PointCloud< pcl::PointXYZ >::ConstPtr &point_cloud, vpColVector &desired_features, unsigned int stepX, unsigned int stepY, const vpImage< bool > *mask=nullptr)
virtual bool isVisible(const vpHomogeneousMatrix &cMo, double alpha, const bool &modulo=false, const vpCameraParameters &cam=vpCameraParameters(), unsigned int width=0, unsigned int height=0)
static bool inRoiMask(const vpImage< bool > *mask, unsigned int i, unsigned int j)
static void convertPoint(const vpCameraParameters &cam, const double &x, const double &y, double &u, double &v)
static void convertPoint(const vpCameraParameters &cam, const double &u, const double &v, double &x, double &y)
void changeFrame(const vpHomogeneousMatrix &cMo)
Class that defines a 3D point in the object frame and allows forward projection of a 3D point in the ...
double get_oX() const
Get the point oX coordinate in the object frame.
double get_y() const
Get the point y coordinate in the image plane.
double get_Y() const
Get the point cY coordinate in the camera frame.
double get_oZ() const
Get the point oZ coordinate in the object frame.
void set_X(double cX)
Set the point cX coordinate in the camera frame.
double get_x() const
Get the point x coordinate in the image plane.
void set_Y(double cY)
Set the point cY coordinate in the camera frame.
double get_Z() const
Get the point cZ coordinate in the camera frame.
void set_Z(double cZ)
Set the point cZ coordinate in the camera frame.
double get_oY() const
Get the point oY coordinate in the object frame.
void changeFrame(const vpHomogeneousMatrix &cMo, vpColVector &cP) const VP_OVERRIDE
double get_X() const
Get the point cX coordinate in the camera frame.
void setWorldCoordinates(double oX, double oY, double oZ)
Implements a 3D polygon with render functionalities like clipping.
void setFarClippingDistance(const double &dist)
void setNearClippingDistance(const double &dist)
void setClipping(const unsigned int &flags)
void getRoiClipped(const vpCameraParameters &cam, std::vector< vpImagePoint > &roi)
void getPolygonClipped(std::vector< std::pair< vpPoint, unsigned int > > &poly)
Defines a generic 2D polygon.
vpRect getBoundingBox() const
bool isInside(const vpImagePoint &iP, const PointInPolygonMethod &method=PnPolyRayCasting) const
Defines a rectangle in the plane.
void setRight(double pos)
void setBottom(double pos)
Class that consider the case of a translation vector.
Class for generating random numbers with uniform probability density.
VISP_EXPORT bool checkSSE2()