31#include <visp3/core/vpConfig.h>
32#include <visp3/rbt/vpRBSilhouetteCCDTracker.h>
34#ifdef VISP_HAVE_OPENMP
38#define VISP_DEBUG_CCD_TRACKER 0
75 for (
unsigned int i = 0; i < A.
getRows(); ++i) {
76 C[i][0] = A[i][0] * B.
data[0] + A[i][1] * B.
data[3] + A[i][2] * B.
data[6];
77 C[i][1] = A[i][0] * B.
data[1] + A[i][1] * B.
data[4] + A[i][2] * B.
data[7];
78 C[i][2] = A[i][0] * B.
data[2] + A[i][1] * B.
data[5] + A[i][2] * B.
data[8];
96 for (
unsigned int i = 0; i < 6; ++i) {
97 const T *d = &A.
data[i * 3];
98 T *c = &C.
data[i * 3];
99 c[0] = d[0] * B.
data[0] + d[1] * B.
data[3] + d[2] * B.
data[6];
100 c[1] = d[0] * B.
data[1] + d[1] * B.
data[4] + d[2] * B.
data[7];
101 c[2] = d[0] * B.
data[2] + d[1] * B.
data[5] + d[2] * B.
data[8];
107 for (
unsigned int i = 0; i < 6; ++i) {
108 const double *a = &A.
data[i * 3];
111 c[0] = a[0] * B[0] + a[1] * B[1] + a[2] * B[2];
112 c[1] = a[0] * B[3] + a[1] * B[4] + a[2] * B[5];
113 c[2] = a[0] * B[6] + a[1] * B[7] + a[2] * B[8];
115 c[3] = a[0] * B[9] + a[1] * B[10] + a[2] * B[11];
116 c[4] = a[0] * B[12] + a[1] * B[13] + a[2] * B[14];
117 c[5] = a[0] * B[15] + a[1] * B[16] + a[2] * B[17];
132 C[0] = A[0] * B[0] + A[1] * B[1] + A[2] * B[2];
133 C[1] = A[3] * B[0] + A[4] * B[1] + A[5] * B[2];
134 C[2] = A[6] * B[0] + A[7] * B[1] + A[8] * B[2];
135 C[3] = A[9] * B[0] + A[10] * B[1] + A[11] * B[2];
136 C[4] = A[12] * B[0] + A[13] * B[1] + A[14] * B[2];
137 C[5] = A[15] * B[0] + A[16] * B[1] + A[17] * B[2];
161 std::vector<std::vector<vpRBSilhouetteControlPoint>> pointsPerThread;
162#ifdef VISP_HAVE_OPENMP
166#ifdef VISP_HAVE_OPENMP
169 unsigned int numThreads = omp_get_num_threads();
170 pointsPerThread.resize(numThreads);
174 pointsPerThread.resize(1);
177#ifdef VISP_HAVE_OPENMP
178 unsigned int threadIdx = omp_get_thread_num();
180 unsigned int threadIdx = 0;
182 std::vector<vpRBSilhouetteControlPoint> localControlPoints;
183#ifdef VISP_HAVE_OPENMP
188 int ii = sp.
i, jj = sp.
j;
215 localControlPoints.push_back(std::move(pccd));
219 pointsPerThread[threadIdx] = std::move(localControlPoints);
222 unsigned int numElements = 0;
223 for (
const std::vector<vpRBSilhouetteControlPoint> &points: pointsPerThread) {
224 numElements +=
static_cast<unsigned int>(points.size());
228 for (
const std::vector<vpRBSilhouetteControlPoint> &points: pointsPerThread) {
235 std::vector<vpRBSilhouetteControlPoint> finalPoints;
237 for (
size_t index : keptIndices) {
247 unsigned int numNormalPoints = numPoints * 2 * normalsPerPoint;
261#if defined(VISP_HAVE_OPENMP)
262#pragma omp parallel for
264 for (
int i = 0; i < static_cast<int>(
m_gradients.size()); ++i) {
280 unsigned int resolution =
static_cast<unsigned int>(
m_controlPoints.size());
284 m_stats.reinit(resolution, normal_points_number);
285 m_prevStats.reinit(resolution, normal_points_number);
301 unsigned int resolution =
static_cast<unsigned int>(
m_controlPoints.size());
305 m_prevStats.reinit(resolution, normal_points_number);
306 m_stats.reinit(resolution, normal_points_number);
375 unsigned nerror_per_point = 2 * normal_points_number * 3;
385 double maxPointError = 0.0;
388 for (
unsigned int j = 0; j < nerror_per_point; ++j) {
389 sum +=
m_error[i * nerror_per_point + j];
391 if (sum > maxPointError) {
394 errorPerPoint[i] = sum;
398 const double diffR =
static_cast<double>(worstColor.
R) -
static_cast<double>(bestColor.
R);
399 const double diffG =
static_cast<double>(worstColor.
G) -
static_cast<double>(bestColor.
G);
400 const double diffB =
static_cast<double>(worstColor.
B) -
static_cast<double>(bestColor.
B);
403 const double weight = errorPerPoint[idx] / maxPointError;
406 c.
R =
static_cast<unsigned char>(
static_cast<double>(bestColor.
R) + diffR * weight);
407 c.
G =
static_cast<unsigned char>(
static_cast<double>(bestColor.
G) + diffG * weight);
408 c.
B =
static_cast<unsigned char>(
static_cast<double>(bestColor.
B) + diffB * weight);
410 vpDisplay::displayCross(IRGB,
static_cast<int>(p.icpoint.get_i()),
static_cast<int>(p.icpoint.get_j()), 3, c, 1);
418 for (
unsigned int j = 0; j < nerror_per_point; ++j) {
419 sum +=
m_weights[i * nerror_per_point + j];
422 weightPerPoint[i] = sum / nerror_per_point;
427 const double weight = weightPerPoint[idx];
430 c.
G =
static_cast<unsigned char>(255.f * weight);
433 vpDisplay::displayCross(IRGB,
static_cast<int>(p.icpoint.get_i()),
static_cast<int>(p.icpoint.get_j()), 3, c, 1);
442 double sumError = 0.0;
443 for (
unsigned int j = 0; j < nerror_per_point; ++j) {
444 sum +=
m_weights[i * nerror_per_point + j];
445 sumError +=
m_error[i * nerror_per_point + j];
447 weightPerPoint[i] = sum / nerror_per_point;
448 errorPerPoint[i] = sumError / nerror_per_point;
455 c.
R =
static_cast<unsigned char>((errorPerPoint[idx] / maxError) * 255.0);
457 c.
B =
static_cast<unsigned char>(255.0 * weightPerPoint[idx]);
463 vpDisplay::displayCross(IRGB,
static_cast<int>(p.icpoint.get_i()),
static_cast<int>(p.icpoint.get_j()), 3, c, 1);
476 p.updateSilhouettePoint(cMo, cRo);
480bool extremitiesOutsideOfImage(
int h,
int w,
unsigned int l,
const double *nv_ptr,
double i,
double j)
484 jd =
static_cast<int>(round(j - l * nv_ptr[0]));
485 id =
static_cast<int>(round(i - l * nv_ptr[1]));
487 if (
id < 0 || jd < 0 || id >= h || jd >= w) {
491 jd =
static_cast<int>(round(j + l * nv_ptr[0]));
492 id =
static_cast<int>(round(i + l * nv_ptr[1]));
494 if (
id < 0 || jd < 0 || id >= h || jd >= w) {
510 unsigned int resolution =
static_cast<unsigned int>(
m_controlPoints.size());
517#ifdef VISP_HAVE_OPENMP
518#pragma omp parallel for
520 for (
int kk = 0; kk < static_cast<int>(
m_controlPoints.size()); kk++) {
523 std::array<double, 2> pt1, pt2;
527 std::array<double, 2> dist1, dist2;
531 double *nv_ptr = stats.
nv[kk];
536 if (extremitiesOutsideOfImage(
static_cast<int>(I.getHeight()),
static_cast<int>(I.getWidth()), ccdh, nv_ptr, p.icpoint.get_i(), p.icpoint.get_j())) {
543#if VISP_DEBUG_CCD_TRACKER
544 if (std::isnan(nv_ptr[0]) || std::isnan(nv_ptr[1])) {
551 double *vic_ptr = stats.
vic[kk];
557 pt1[0] = round(p.icpoint.get_u() + j * nv_ptr[0]);
559 pt1[1] = round(p.icpoint.get_v() + j * nv_ptr[1]);
562 dist1[0] = (pt1[0] - p.icpoint.get_u()) * nv_ptr[0] + (pt1[1] - p.icpoint.get_v()) * nv_ptr[1];
565 dist1[1] = (pt1[0] - p.icpoint.get_u()) * nv_ptr[1] - (pt1[1] - p.icpoint.get_v()) * nv_ptr[0];
566 vic_ptr[10 * k + 0] = pt1[1];
567 vic_ptr[10 * k + 1] = pt1[0];
568 vic_ptr[10 * k + 2] = dist1[0];
569 vic_ptr[10 * k + 3] = dist1[1];
572 vic_ptr[10 * k + 4] = 0.5 * (erf((dist1[0]) / (sqrt(2) * sigma)) + 1.0);
578 vic_ptr[10 * k + 5] = wp1 * wp1 * wp1 * wp1;
582 double wp2 = (1 - vic_ptr[10 * k + 4] - 0.25);
583 vic_ptr[10 * k + 6] = -64 * wp2 * wp2 * wp2 * wp2 + 0.25;
585 vic_ptr[10 * k + 7] = std::max((exp(-0.5 * dist1[0] * dist1[0] / (sigma_hat * sigma_hat)) - minus_exp_gamma2), 0.0);
587 vic_ptr[10 * k + 8] = 0.5 * exp(-abs(dist1[1]) / alpha) / alpha;
589 vic_ptr[10 * k + 9] = exp(-dist1[0] * dist1[0] / (2 * sigma * sigma)) / (sqrt(2.0 * M_PI) * sigma);
593 normalized_param[kk][0] += vic_ptr[10 * k + 7];
598 pt2[0] = round(p.icpoint.get_u() - j * nv_ptr[0]);
599 pt2[1] = round(p.icpoint.get_v() - j * nv_ptr[1]);
604 dist2[0] = (pt2[0] - p.icpoint.get_u()) * nv_ptr[0] + (pt2[1] - p.icpoint.get_v()) * nv_ptr[1];
605 dist2[1] = (pt2[0] - p.icpoint.get_u()) * nv_ptr[1] - (pt2[1] - p.icpoint.get_v()) * nv_ptr[0];
607 vic_ptr[10 * negative_normal + 0] = pt2[1];
608 vic_ptr[10 * negative_normal + 1] = pt2[0];
609 vic_ptr[10 * negative_normal + 2] = dist2[0];
610 vic_ptr[10 * negative_normal + 3] = dist2[1];
611 vic_ptr[10 * negative_normal + 4] = 0.5 * (erf(dist2[0] / (sqrt(2) * sigma)) + 1);
614 wp1 = (vic_ptr[10 * negative_normal + 4] - 0.25);
615 vic_ptr[10 * negative_normal + 5] = -64 * wp1 * wp1 * wp1 * wp1 + 0.25;
617 vic_ptr[10 * negative_normal + 6] = wp2 * wp2 * wp2 * wp2;
618 vic_ptr[10 * negative_normal + 7] = std::max((exp(-0.5 * dist2[0] * dist2[0] / (sigma_hat * sigma_hat)) - minus_exp_gamma2), 0.0);
619 vic_ptr[10 * negative_normal + 8] = 0.5 * exp(-abs(dist2[0]) / alpha) / alpha;
620 vic_ptr[10 * negative_normal + 9] = exp(-dist2[0] * dist2[0] / (2 * sigma * sigma)) / (sqrt(2 * M_PI) * sigma);
621 normalized_param[kk][1] += vic_ptr[10 * negative_normal + 7];
625#ifdef VISP_HAVE_OPENMP
626#pragma omp parallel for
628 for (
int i = 0; i < static_cast<int>(resolution); ++i) {
635 double w1 = 0.0, w2 = 0.0;
638 std::array<double, 3> m1 { 0.0, 0.0, 0.0 }, m2 { 0.0, 0.0, 0.0 };
641 std::array<double, 9> m1_o2 { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
642 std::array<double, 9> m2_o2 { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
647 double wp1 = 0.0, wp2 = 0.0;
649 double *vic_ptr = stats.
vic[i];
650 double *mean_vic_ptr = stats.
mean_vic[i];
651 double *cov_vic_ptr = stats.
cov_vic[i];
655 wp1 = 0.0, wp2 = 0.0;
657 const double *vic_k = vic_ptr + 10 * k;
660 wp1 = (vic_k[5] * vic_k[7] / normalized_param[i][0]);
663 wp2 = (vic_k[6] * vic_k[7] / normalized_param[i][1]);
672#if VISP_DEBUG_CCD_TRACKER
673 if (vic_k[0] >= I.getHeight() || vic_k[1] >= I.getWidth()) {
677 const vpRGBa pixelRGBa = I(
static_cast<unsigned int>(vic_k[0]),
static_cast<unsigned int>(vic_k[1]));
678 double *pixel = pix_ptr + k * 3;
679 pixel[0] =
static_cast<double>(pixelRGBa.
R);
680 pixel[1] =
static_cast<double>(pixelRGBa.
G);
681 pixel[2] =
static_cast<double>(pixelRGBa.
B);
683 m1[0] += wp1 * pixel[0];
684 m1[1] += wp1 * pixel[1];
685 m1[2] += wp1 * pixel[2];
687 m2[0] += wp2 * pixel[0];
688 m2[1] += wp2 * pixel[1];
689 m2[2] += wp2 * pixel[2];
693 for (
unsigned int m = 0; m < 3; ++m) {
694 for (
unsigned int n = 0; n < 3; ++n) {
695 m1_o2[m * 3 + n] += wp1 * pixel[m] * pixel[n];
696 m2_o2[m * 3 + n] += wp2 * pixel[m] * pixel[n];
699 const double *vic_neg = vic_ptr + 10 * negative_normal;
700 const vpRGBa pixelNegRGBa = I(
static_cast<unsigned int>(vic_neg[0]),
static_cast<unsigned int>(vic_neg[1]));
701 double *pixelNeg = pix_ptr + negative_normal * 3;
703 pixelNeg[0] =
static_cast<double>(pixelNegRGBa.
R);
704 pixelNeg[1] =
static_cast<double>(pixelNegRGBa.
G);
705 pixelNeg[2] =
static_cast<double>(pixelNegRGBa.
B);
706 wp1 = (vic_neg[5] * vic_neg[7] / normalized_param[i][0]);
707 wp2 = (vic_neg[6] * vic_neg[7] / normalized_param[i][1]);
711 m1[0] += wp1 * pixelNeg[0];
712 m1[1] += wp1 * pixelNeg[1];
713 m1[2] += wp1 * pixelNeg[2];
715 m2[0] += wp2 * pixelNeg[0];
716 m2[1] += wp2 * pixelNeg[1];
717 m2[2] += wp2 * pixelNeg[2];
719 for (
unsigned int m = 0; m < 3; ++m) {
720 for (
unsigned int n = 0; n < 3; ++n) {
721 m1_o2[m * 3 + n] += wp1 * pixelNeg[m] * pixelNeg[n];
722 m2_o2[m * 3 + n] += wp2 * pixelNeg[m] * pixelNeg[n];
726 mean_vic_ptr[0] = m1[0] / w1;
727 mean_vic_ptr[1] = m1[1] / w1;
728 mean_vic_ptr[2] = m1[2] / w1;
730 mean_vic_ptr[3] = m2[0] / w2;
731 mean_vic_ptr[4] = m2[1] / w2;
732 mean_vic_ptr[5] = m2[2] / w2;
734 for (
unsigned int m = 0; m < 3; ++m) {
735 for (
unsigned int n = 0; n < 3; ++n) {
736 cov_vic_ptr[m * 3 + n] = m1_o2[m * 3 + n] / w1 - m1[m] * m1[n] / (w1 * w1);
737 cov_vic_ptr[9 + m * 3 + n] = m2_o2[m * 3 + n] / w2 - m2[m] * m2[n] / (w2 * w2);
747void sumGradientsAndHessians(
const std::vector<vpColVector> &gradients,
const std::vector<vpMatrix> &hessians,
const vpColVector &weights,
vpColVector &gradient,
vpMatrix &hessian,
vpMatrix &L)
749 std::vector<vpColVector> gradientPerThread;
750 std::vector<vpMatrix> hessianPerThread;
753#ifdef VISP_HAVE_OPENMP
757#ifdef VISP_HAVE_OPENMP
760 unsigned int numThreads = omp_get_num_threads();
761 gradientPerThread.resize(numThreads);
762 hessianPerThread.resize(numThreads);
766 gradientPerThread.resize(1);
767 hessianPerThread.resize(1);
771#ifdef VISP_HAVE_OPENMP
772 unsigned int threadIdx = omp_get_thread_num();
774 unsigned int threadIdx = 0;
779#ifdef VISP_HAVE_OPENMP
782 for (
int ii = 0; ii < static_cast<int>(gradients.size()); ++ii) {
783 const unsigned int i =
static_cast<unsigned int>(ii);
784 const double *g = gradients[
i].data;
785 const double *
h = hessians[
i].data;
786 double *Ldata = L[
i];
787 double w = weights[
i];
789 for (
unsigned int j = 0;
j < 6; ++
j) {
791 localGradient[
j] += g[
j] *
w;
792 const double *hj =
h +
j* 6;
793 for (
unsigned int k = 0; k < 6; ++k) {
795 localHessian[
j][k] += hj[k] *
w;
801 gradientPerThread[threadIdx] = localGradient;
802 hessianPerThread[threadIdx] = localHessian;
806 for (
unsigned int i = 0;
i < gradientPerThread.size(); ++
i) {
807 gradient += gradientPerThread[
i];
808 hessian += hessianPerThread[
i];
812template<
bool hasTemporalSmoothing>
815 const unsigned int npointsccd =
static_cast<unsigned int>(
m_controlPoints.size());
817 const unsigned int nerror_ccd = 2 * normal_points_number * 3 * npointsccd;
818 m_error.resize(nerror_ccd,
false);
821 m_L.resize(nerror_ccd, 6,
false,
false);
822#ifdef VISP_HAVE_OPENMP
837 objectFrameProj = cVo *
m_oJo;
840#ifdef VISP_HAVE_OPENMP
844 const unsigned int ui =
static_cast<unsigned int>(i);
846 errorPerPoint[ui] = 0.0;
848 for (
unsigned int j = 0; j < 2 * normal_points_number; ++j) {
849 for (
unsigned int m = 0; m < 3; ++m) {
850 m_error[ui * 2 * normal_points_number * 3 + j * 3 + m] = 0.0;
856 const double *vic_ptr =
m_stats.vic[ui];
857 const double *nv_ptr =
m_stats.nv[ui];
858 const double *mean_vic_ptr =
m_stats.mean_vic[ui];
859 const double *cov_vic_ptr =
m_stats.cov_vic[ui];
860 const double *pix_ptr =
m_stats.imgPoints[ui];
862 const double *mean_vic_ptr_prev =
m_prevStats.mean_vic[ui];
863 const double *cov_vic_ptr_prev =
m_prevStats.cov_vic[ui];
867 Lnvp[0][0] = (-nv_ptr[0] / p.Zs);
868 Lnvp[0][1] = (-nv_ptr[1] / p.Zs);
869 Lnvp[0][2] = ((nv_ptr[0] * p.xs + nv_ptr[1] * p.ys) / p.Zs);
870 Lnvp[0][3] = (nv_ptr[0] * p.xs * p.ys + nv_ptr[1] * (1.0 + p.ys * p.ys));
871 Lnvp[0][4] = (-nv_ptr[1] * p.xs * p.ys - nv_ptr[0] * (1.0 + p.xs * p.xs));
872 Lnvp[0][5] = (nv_ptr[0] * p.ys - nv_ptr[1] * p.xs);
874 Lnvp = Lnvp * objectFrameProj;
877 for (
unsigned int j = 0; j < 2 * normal_points_number; ++j) {
878 const double *vic_j = vic_ptr + 10 * j;
879 const double *pix_j = pix_ptr + j * 3;
880 const double errf = vic_j[4];
882 double *error_ccd_j =
m_error.data + i * 2 * normal_points_number * 3 + j * 3;
884 for (
unsigned n = 0; n < 9; ++n) {
886 tmp_cov[n] = errf * cov_vic_ptr[n] + (1.0 - errf) * cov_vic_ptr[n + 9];
887 if constexpr (hasTemporalSmoothing) {
888 tmp_cov[n] += smooth2 * (errf * cov_vic_ptr_prev[n] + (1.0 - errf) * cov_vic_ptr_prev[n + 9]);
895 for (
int m = 0; m < 3; ++m) {
896 double err = (pix_j[m] - errf * mean_vic_ptr[m] - (1.0 - errf) * mean_vic_ptr[m + 3]);
897 if constexpr (hasTemporalSmoothing) {
898 err +=
m_temporalSmoothingFac * (pix_j[m] - errf * mean_vic_ptr_prev[m] - (1.0 - errf) * mean_vic_ptr_prev[m + 3]);
901 tmp_pixel_diff[m] = err;
902 error_ccd_j[m] = err;
903 errorPerPoint[ui] += err;
908 for (
unsigned int n = 0; n < 3; ++n) {
909 const double f = -cam.get_px() * (vic_j[9] * (mean_vic_ptr[n] - mean_vic_ptr[n + 3]));
910 const double facPrev = hasTemporalSmoothing ? -cam.get_px() *
m_temporalSmoothingFac * (vic_j[9] * (mean_vic_ptr_prev[n] - mean_vic_ptr_prev[n + 3])) : 0.0;
911 for (
unsigned int dof = 0; dof < 6; ++dof) {
912 tmp_jacobian.
data[dof * 3 + n] = f * Lnvp[0][dof];
913 if constexpr (hasTemporalSmoothing) {
914 tmp_jacobian.
data[dof * 3 + n] += facPrev * Lnvp[0][dof];
934 for (
unsigned int j = 0; j < static_cast<unsigned int>(2 * normal_points_number * 3); ++j) {
935 m_weights[i * 2 * normal_points_number * 3 + j] = w;
945 hessian_E_inv =
m_hessian.pseudoInverse();
948 hessian_E_inv =
m_hessian.inverseByCholesky();
T operator[](const size_t i) const
T & operator[](const size_t i)
void inverse(FastMat33< T > &minv) const
static void multiply(const vpMatrix &A, const FastMat33< double > &B, vpMatrix &C)
static void multiplyBTranspose(const FastMat63< double > &A, const FastMat63< double > &B, vpMatrix &C)
static void multiply(const FastMat63< T > &A, const FastMat33< T > &B, FastMat63 &C)
T operator[](const size_t i) const
T & operator[](const size_t i)
T & operator[](const size_t i)
T operator[](const size_t i) const
static void multiply(const FastMat63< double > &A, const FastVec3< double > &B, vpColVector &C)
unsigned int getCols() const
void resize(unsigned int nrows, unsigned int ncols, bool flagNullify=true, bool recopy_=true)
unsigned int getRows() const
vpMatrix imgPoints
Normal vector.
vpMatrix mean_vic
Vicinity data.
Generic class defining intrinsic camera parameters.
Implementation of column vector and the associated operations.
static vpColVector view(double *raw_data, unsigned int rows)
Create a column vector view of a raw data array. The view can modify the contents of the raw data arr...
Class to define RGB colors available for display functionalities.
static const vpColor green
static void displayCross(const vpImage< unsigned char > &I, const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)
static void displayPoint(const vpImage< unsigned char > &I, const vpImagePoint &ip, const vpColor &color, 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.
Definition of the vpImage class member functions.
unsigned int getWidth() const
unsigned int getHeight() const
Implementation of a matrix and operations on matrices.
static vpMatrix view(double *data, unsigned int rows, unsigned int cols)
Create a matrix view of a raw data array. The view can modify the contents of the raw data array,...
vpColVector m_weights
Weighted VS error.
bool m_jacobianInObjectSpace
Matrix representation of the estimated DOFS.
vpMatrix m_LTL
Error jacobian (In VS terms, the interaction matrix).
bool hasIgnoredDofs() const
vpColVector m_LTR
Left side of the Gauss newton minimization.
bool m_vvsConverged
User-defined weight for this specific type of feature.
unsigned m_numFeatures
Error weights.
vpColVector m_weighted_error
Raw VS Error vector.
vpMatrix m_cov
Right side of the Gauss Newton minimization.
const vpRBFeatureTrackerInput * m_previousFrame
void buildGradientAndHessianStorageViews(unsigned int normalsPerPoint, bool clear)
Update the gradient and hessian storage views. Reserve new memory if required and ensure that gradien...
vpRobust m_robust
Silhouette points where to compute CCD statistics.
vpRBSilhouetteCCDTracker()
void extractFeatures(const vpRBFeatureTrackerInput &frame, const vpRBFeatureTrackerInput &previousFrame, const vpHomogeneousMatrix &cMo) VP_OVERRIDE
Extract features from the frame data and the current pose estimate.
vpCCDStatistics m_prevStats
void updateCCDPoints(const vpHomogeneousMatrix &cMo)
double m_minMaskConfidence
void computeErrorAndInteractionMatrix(const vpHomogeneousMatrix &cMo)
void computeLocalStatistics(const vpImage< vpRGBa > &I, vpCCDStatistics &stats)
std::vector< double > m_hessianData
vpDisplayType m_displayType
std::vector< vpColVector > m_gradients
std::vector< double > m_gradientData
double m_temporalSmoothingFac
Sum of local hessians.
std::vector< vpRBSilhouetteControlPoint > m_controlPoints
void initVVS(const vpRBFeatureTrackerInput &frame, const vpRBFeatureTrackerInput &previousFrame, const vpHomogeneousMatrix &cMo) VP_OVERRIDE
vpCCDParameters m_ccdParameters
static const unsigned int BASE_SEED
vpMatrix m_hessian
Sum of local gradients.
std::vector< vpMatrix > m_hessians
bool m_useMask
Smoothing factor used to integrate data from the previous frame.
double m_vvsConvergenceThreshold
void changeScale()
To be called when the scale of the normal vectors is changed.
void computeVVSIter(const vpRBFeatureTrackerInput &frame, const vpHomogeneousMatrix &cMo, unsigned int iteration) VP_OVERRIDE
void onTrackingIterStart(const vpRBFeatureTrackerInput &, const vpHomogeneousMatrix &) VP_OVERRIDE
Method called when starting a tracking iteration.
void display(const vpCameraParameters &cam, const vpImage< unsigned char > &I, const vpImage< vpRGBa > &IRGB, const vpImage< unsigned char > &depth) const VP_OVERRIDE
Trackable silhouette point representation.
void buildSilhouettePoint(int n, int m, const double &Z, double orient, const vpColVector &normo, const vpHomogeneousMatrix &cMo, const vpHomogeneousMatrix &oMc, const vpCameraParameters &cam)
double getMaxMaskGradientAlongLine(const vpImage< float > &mask, int searchSize) const
Silhouette point simple candidate representation.
double Z
angle of the normal in the image.
vpColVector normal
Pixel coordinates of the silhouette point.
double orientation
Normal to the silhouette at point i,j, in world frame.
bool isSilhouette
Point depth.
unsigned char B
Blue component.
unsigned char R
Red component.
unsigned char G
Green component.
@ TUKEY
Tukey influence function.
Implementation of a rotation matrix and operations on such kind of matrices.