36 #include <opencv2/imgproc/imgproc.hpp>
38 #include <Eigen/Dense>
48 return (box1 & box2).area() > 0;
54 std::vector<cv::Vec2d> points;
57 std::vector<cv::Vec2d> points_t;
60 points.push_back(cv::Vec2d(rect.x, rect.y));
61 points.push_back(cv::Vec2d(rect.x + rect.width, rect.y));
62 points.push_back(cv::Vec2d(rect.x + rect.width, rect.y + rect.height));
63 points.push_back(cv::Vec2d(rect.x, rect.y + rect.height));
67 cv::transform(cv::InputArray(points), cv::OutputArray(points_t), rigid_transform);
77 if (ellipsoid.rows == 3 && ellipsoid.cols == 3 && ellipsoid.type() == CV_32FC1)
79 if (ellipsoid.at<
float>(2, 2) >= std::numeric_limits<double>::max() * 0.5)
81 ellipse.create(2, 2, CV_32FC1);
82 ellipse.at<
float>(0, 0) = ellipsoid.at<
float>(0, 0);
83 ellipse.at<
float>(0, 1) = ellipsoid.at<
float>(0, 1);
84 ellipse.at<
float>(1, 0) = ellipsoid.at<
float>(1, 0);
85 ellipse.at<
float>(1, 1) = ellipsoid.at<
float>(1, 1);
91 for (
size_t r = 0; r < 3; r++)
93 for (
size_t c = 0; c < 3; c++)
95 A(r, c) = ellipsoid.at<
float>(r, c);
107 Eigen::Vector3d n_ax;
114 Eigen::Matrix3d A_sym_temp = A.transpose() + A;
117 Eigen::Matrix3d N_ax_temp = n_ax * n_ax.transpose();
121 Eigen::Matrix3d A_prime_1 = A_sym_temp * N_ax_temp;
125 Eigen::Matrix3d A_prime_2 = A_prime_1 * A_sym_temp;
128 Eigen::RowVector3d scale_1 = n_ax.transpose() * A;
132 double scale = (scale_1 * n_ax)(0,0) * -4.0;
136 Eigen::Matrix3d A_temp = A * scale;
140 Eigen::Matrix3d Aprime = A_prime_2 + A_temp;
147 Eigen::RowVector3d C_temp = n_ax.transpose() * A;
151 double cp = (-4.0 * C_temp) * n_ax;
154 Eigen::Matrix3d Bprime = Aprime / cp;
158 Eigen::Matrix<double, 3, 2> Jp;
168 Eigen::Matrix<double, 2, 3> Dprime_temp = Jp.transpose() * Bprime;
172 Eigen::Matrix2d Dprime = Dprime_temp * Jp;
174 for (
size_t r = 0; r < 2; r++)
176 for (
size_t c = 0; c < 2; c++)
178 if (Dprime(r, c) != Dprime(r, c))
185 ellipse.create(2, 2, CV_32FC1);
186 ellipse.at<
float>(0, 0) = Dprime(0, 0);
187 ellipse.at<
float>(0, 1) = Dprime(0, 1);
188 ellipse.at<
float>(1, 0) = Dprime(1, 0);
189 ellipse.at<
float>(1, 1) = Dprime(1, 1);
196 const cv::Mat& ellipse,
197 const tf::Vector3& center,
201 std::vector<tf::Vector3> perimeter;
203 if (ellipse.rows == 2 && ellipse.cols == 2 && ellipse.type() == CV_32FC1 &&
206 Eigen::Matrix2d Dprime;
207 Dprime(0, 0) = ellipse.at<
float>(0, 0);
208 Dprime(0, 1) = ellipse.at<
float>(0, 1);
209 Dprime(1, 0) = ellipse.at<
float>(1, 0);
210 Dprime(1, 1) = ellipse.at<
float>(1, 1);
212 Eigen::JacobiSVD<Eigen::Matrix2d> svd(Dprime, Eigen::ComputeFullV);
214 Eigen::Vector2d Sigma = svd.singularValues();
215 Eigen::Matrix2d Vt = svd.matrixV().transpose();
217 double xprime_scale = std::sqrt(Sigma(0));
218 double yprime_scale = std::sqrt(Sigma(1));
220 if (xprime_scale <= 0 || yprime_scale <= 0)
225 Eigen::MatrixX2d Xp1(num_points, 2);
226 for (int32_t i = 0; i < num_points; i++)
229 (
static_cast<double>(i) /
static_cast<double>(num_points))
232 Xp1(i, 0) = xprime_scale * std::cos(phi) * scale;
233 Xp1(i, 1) = yprime_scale * std::sin(phi) * scale;
237 Eigen::MatrixX2d Xell = Xp1 * Vt;
239 perimeter.resize(num_points);
240 for (int32_t i = 0; i < num_points; i++)
242 perimeter[i].setX(Xell(i, 0) + center.x());
243 perimeter[i].setY(Xell(i, 1) + center.y());