21 #include <opencv2/imgproc/imgproc.hpp> 22 #include <opencv2/calib3d/calib3d.hpp> 26 #include <boost/foreach.hpp> 45 cv::Mat cameraMatrix, distCoeffs;
46 for(
unsigned int i = 0; i <
contours_.size(); i++) {
58 for(
unsigned int j = 0; j < count; j++) {
144 for(
unsigned int i = 0; i <
ellipses_.size(); i++) {
161 for(
unsigned int i = 0; i <
ellipses_.size(); i++) {
183 if ( boxEllipseRatio < param_->threshold_ring_ratio ) {
192 for(std::vector<Ellipse>::iterator a =
ellipses_.begin(); a !=
ellipses_.end(); a++) {
193 if((a->innerRing >= 0) || (a->outerRing >= 0) || (a->detection !=
VALID))
continue;
195 for(std::vector<Ellipse>::iterator b =
ellipses_.begin(); b !=
ellipses_.end(); b++) {
196 if((a->id == b->id) || (b->innerRing != -1) || (b->outerRing != -1) || (b->detection !=
VALID) ) {
199 double d = cv::norm(a->boxEllipse.center - b->boxEllipse.center);
200 if(d < threshold_center) {
201 Ellipse *outer = &(*a), *inner = &(*b);
202 if(a->radiusEllipseMax < b->radiusEllipseMax) outer = &(*b), inner = &(*a);
203 double ratioRadiusRingMax = fabs(inner->radiusEllipseMax / outer->
radiusEllipseMax-0.5);
204 double ratioRadiusRingMin = fabs(inner->radiusEllipseMax / outer->
radiusEllipseMax-0.5);
209 inner->outerRing = outer->
id;
214 if((a->innerRing == -1) && (a->outerRing == -1)) a->detection =
INVALID_NO_RING;
226 const std::vector<cv::Point2f> &contour = *(ellipse.
contourUndistort.get());
228 std::vector<double > &distances = *(ellipse.
distances.get());
229 const cv::Point2f &pc = ellipse.
boxEllipse.center;
231 double ca = cos(angle), sa = sin(angle);
234 distances.reserve(contour.size());
235 for(
unsigned int i = 0; i < contour.size(); i++) {
236 double dx = contour[i].x - pc.x, dy = contour[i].y - pc.y;
237 double u = ca*dx + sa*dy, v = -sa*dx + ca*dy;
238 cv::Point2d p(contour[i].
x - pc.x, contour[i].y - pc.y);
239 double d = (u*u)/(a*a) + (v*v)/(b*b);
240 distances.push_back(d);
244 double mean = sum / distances.size();
245 double diff = fabs((mean - 1.));
257 cv::Mat_<double> rvec, tvec;
259 cv::Mat objectPoints = (cv::Mat_<double>(5,3) << 0, 0, 0, -radius, +radius, 0, +radius, +radius, 0, +radius, -radius, 0, -radius, -radius, 0);
260 for(std::vector<Ellipse>::iterator it =
ellipses_.begin(); it !=
ellipses_.end(); it++) {
266 cv::Mat imagePoints = (cv::Mat_<double>(5,2) << pc.x, pc.y, pi[0].x, pi[0].y, pi[1].x, pi[1].y, pi[2].x, pi[2].y, pi[3].x, pi[3].y);
270 cv::Rodrigues(rvec, ellipse.
cone.
R[0]);
273 ellipse.
cone.
R[1] = ellipse.
cone.
R[0].clone();
287 for(std::vector<Ellipse>::iterator ellipse =
ellipses_.begin(); ellipse !=
ellipses_.end(); ellipse++) {
288 if(ellipse->detection !=
VALID)
continue;
298 cv::Mat_<double> tvec(translations[i]);
299 cv::Mat_<double> nvec = R[i] * (cv::Mat_<double>(3,1) << 0, 0, 1);
300 double d0 = cv::norm(tvec - nvec);
301 double d1 = cv::norm(tvec + nvec);
305 normals[i][0] = nvec(0), normals[i][1] = nvec(1), normals[i][2] = nvec(2);
308 cv::Mat_<double> unitZ = (cv::Mat_<double>(3,1) << 0, 0, 1);
309 cv::Mat_<double> nvec(normals[i]);
310 nvec = nvec/cv::norm(nvec);
311 cv::Mat_<double> c2 = nvec;
312 cv::Mat_<double> c1 = unitZ.cross(c2);
313 cv::Mat_<double> c0 = c1.cross(c2);
314 c1 = c1/cv::norm(c1);
315 c0 = c0/cv::norm(c0);
316 R[i] = (cv::Mat_<double>(3,3) << c0(0), c1(0), c2(0), c0(1), c1(1), c2(1), c0(2), c1(2), c2(2));
321 cv::Mat_<double> P = (cv::Mat_<double>(3,1) << p.x, p.y, 1);
322 cv::Mat_<double> D = P.t() * C * P;
327 double a = box.size.width/2., b = box.size.height/2.;
328 double angle = M_PI/180.0 * (float) box.angle;
329 double ca = cos(angle), sa = sin(angle);
330 double cx = intrinsic(0,2), cy = intrinsic(1,2);
331 cv::Mat_<double> Re = (cv::Mat_<double>(2,2) << ca, -sa, sa, ca);
332 cv::Mat_<double> ABInvTAB = (cv::Mat_<double>(2,2) << 1./(a*a), 0., 0., 1./(b*b));
333 cv::Mat_<double> X0 = (cv::Mat_<double>(2,1) << box.center.x-cx, box.center.y-cy);
334 cv::Mat_<double> M = Re * ABInvTAB * Re.t();
335 cv::Mat_<double> Mf = X0.t() * M * X0;
339 double D = - A * X0(0) - B * X0(1);
340 double E = - B * X0(0) - C * X0(1);
341 double F = Mf(0,0) - 1.0;
342 this->C = (cv::Mat_<double>(3,3) << A, B, D,
351 cv::Mat_<double> Q, V, E;
353 double fx = intrinsic(0,0), fy = intrinsic(1,1);
354 double focalLength = (fx+fy)/2.0;
355 if(focalLength == 0)
return;
357 Q(0,0) = this->C(0,0);
358 Q(0,1) = this->C(0,1);
359 Q(0,2) = this->C(0,2) / (focalLength);
360 Q(1,0) = this->C(1,0);
361 Q(1,1) = this->C(1,1);
362 Q(1,2) = this->C(1,2) / (focalLength);
363 Q(2,0) = this->C(2,0) / (focalLength);
364 Q(2,1) = this->C(2,1) / (focalLength);
365 Q(2,2) = this->C(2,2) / (focalLength*focalLength);
369 double e1 = E.at<
double>(0);
370 double e2 = E.at<
double>(1);
371 double e3 = E.at<
double>(2);
372 double S1[] = {+1,+1,+1,+1,-1,-1,-1,-1};
373 double S2[] = {+1,+1,-1,-1,+1,+1,-1,-1};
374 double S3[] = {+1,-1,+1,-1,+1,-1,+1,-1};
376 double g = sqrt((e2-e3)/(e1-e3));
377 double h = sqrt((e1-e2)/(e1-e3));
378 translations[0] = translations[1] = cv::Point3d(0,0,0);
379 normals[0] = normals[1] = cv::Vec3d(0,0,0);
380 projections[0] = projections[1] = cv::Point2d(0,0);
382 for(
int i = 0; i < 8; i++) {
384 double z0 = S3[i] * (e2 * radius) / sqrt(-e1*e3);
385 double Tx = S2[i] * e3/e2 * h;
387 double Tz = -S1[i] * e1/e2 * g;
388 double Nx = S2[i] * h;
390 double Nz = -S1[i] * g;
392 cv::Mat_<double> t = (z0 * V * (cv::Mat_<double>(3,1) << Tx, Ty, Tz));
393 cv::Mat_<double> n = (V * (cv::Mat_<double>(3,1) << Nx, Ny, Nz));
396 if((t(2) > 0) && (n(2)<0)) {
398 translations[k] = cv::Point3d(t(0), t(1), t(2));
399 normals[k] = cv::Vec3d(n(0), n(1), n(2));
401 cv::Mat_<double> Pc = intrinsic * t;
402 projections[k].x = Pc(0)/Pc(2);
403 projections[k].y = Pc(1)/Pc(2);
cv::Mat_< double > distCoeffs
std::list< Marker > markers_
EdgeDetection edge_detection
boost::shared_ptr< std::vector< cv::Point2f > > contourUndistort
boost::posix_time::ptime tstampLast_
double distance(const cv::Point2d p)
cv::Mat_< double > projectionMatrix
double threshold_ring_ratio
void normal2Roation(int i)
PoseEstimation pose_estimation
cv::RotatedRect boxEllipse
void Perform(unsigned char *pImgEdgeStrength, int defEdgeLinkMode=MODE_CONTOUR, void *pImgEdgeDirection=NULL, int defImgEdgeDirectionType=ANGLE_8U)
Starts the edge linking with a certain mode.
void edge_detection(const cv::Mat &m)
tuw::EllipseRefinement ellipseRefinementDual
DetectionState filterContourMean(Ellipse &ellipse)
TFSIMD_FORCE_INLINE tfScalar angle(const Quaternion &q1, const Quaternion &q2)
int threshold_edge_detection1
void Init(unsigned int iImgWidth, unsigned int iImgHeight, bool bAllowToModifyTheSources=false, unsigned char iEdgeToProcess=0xFF, unsigned char iEdgeInProcess=0xFF-1, unsigned char iEdgeProcessed=0xFF-2, unsigned char iEdgeStrengthRemoved=0)
Inititalized the class and reserves the momory needed.
boost::shared_ptr< std::vector< cv::Point2f > > contourDistort
std::vector< std::vector< cv::Point > > contours_
tuw::Contour contour_detector_
bool refine(const cv::Mat_< short > &im_dx, const cv::Mat_< short > &im_dy, const std::vector< cv::Point2f > &points, Ellipse &ellipse)
double threshold_contour_mean
std::vector< Ellipse > ellipses_
int getContours(std::vector< std::vector< cv::Point > > &contours, unsigned min_length=0)
Returns the contour as vector of vector points.
void Canny(const cv::Mat &image, cv::Mat &edges, cv::Mat &gradient, cv::Mat &direction, cv::Mat &sobel_dx, cv::Mat &sobel_dy, double threshold1, double threshold2, int apertureSize=3, bool L2gradient=false)
int threshold_contour_min_points
static const int MODE_COMPLEX
Static const variable used to define the methode used to find the contour (linked edges) ...
cv::Mat_< double > cameraMatrix
DetectionState EllipseRedefinement(Ellipse &ellipse)
boost::posix_time::ptime tstamp_
TFSIMD_FORCE_INLINE const tfScalar & x() const
double threshold_max_radius
void createEllipseCanditates()
double threshold_ring_center
cv::Mat_< double > R[2]
two plausible translations solutions
double threshold_min_radius
boost::shared_ptr< std::vector< cv::Point > > polygon
void setEllipse(const double &_x, const double &_y, const double &_a, const double &_b, const double &_phi)
boost::shared_ptr< std::vector< double > > distances
int kernel_size_edge_detection
void set(const ObliqueCone &c)
two plausible roations
void get(cv::RotatedRect &r)
bool ellipse_redefinement
static const int MODE_CONTOUR
Static const variable used to define the methode used to find the contour (linked edges) ...
void pose(cv::Mat_< double > intrinsic, cv::Mat_< double > distCoeffs, double radius)
void rotation2Normal(int i)
int threshold_edge_detection2
void fit_ellipses_opencv(const cv::Mat &m, const cv::Mat cameraMatrix, const cv::Mat distCoeffs, const cv::Mat projectionMatrix, const boost::posix_time::ptime &tstamp)
static const int MODE_SIMPLE
Static const variable used to define the methode used to find the contour (linked edges) ...
EllipsesDetection(Parameters *parm)
DetectionState filterContour(Ellipse &ellipse)
cv::Point3d translations[2]
ellipse equation
DetectionState filterEllipse(Ellipse &ellipse)