tesseract
3.03
|
#include <detlinefit.h>
Classes | |
struct | PointWidth |
Public Member Functions | |
DetLineFit () | |
~DetLineFit () | |
void | Clear () |
void | Add (const ICOORD &pt) |
void | Add (const ICOORD &pt, int halfwidth) |
double | Fit (ICOORD *pt1, ICOORD *pt2) |
double | Fit (int skip_first, int skip_last, ICOORD *pt1, ICOORD *pt2) |
double | ConstrainedFit (const FCOORD &direction, double min_dist, double max_dist, bool debug, ICOORD *line_pt) |
bool | SufficientPointsForIndependentFit () const |
double | Fit (float *m, float *c) |
double | ConstrainedFit (double m, float *c) |
Definition at line 56 of file detlinefit.h.
Definition at line 39 of file detlinefit.cpp.
: square_length_(0.0) { }
Definition at line 42 of file detlinefit.cpp.
{ }
void tesseract::DetLineFit::Add | ( | const ICOORD & | pt | ) |
Definition at line 52 of file detlinefit.cpp.
{ pts_.push_back(PointWidth(pt, 0)); }
void tesseract::DetLineFit::Add | ( | const ICOORD & | pt, |
int | halfwidth | ||
) |
Definition at line 59 of file detlinefit.cpp.
{ pts_.push_back(PointWidth(pt, halfwidth)); }
void tesseract::DetLineFit::Clear | ( | ) |
Definition at line 46 of file detlinefit.cpp.
double tesseract::DetLineFit::ConstrainedFit | ( | const FCOORD & | direction, |
double | min_dist, | ||
double | max_dist, | ||
bool | debug, | ||
ICOORD * | line_pt | ||
) |
Definition at line 131 of file detlinefit.cpp.
{ ComputeConstrainedDistances(direction, min_dist, max_dist); // Do something sensible with no points or computed distances. if (pts_.empty() || distances_.empty()) { line_pt->set_x(0); line_pt->set_y(0); return 0.0; } int median_index = distances_.choose_nth_item(distances_.size() / 2); *line_pt = distances_[median_index].data; if (debug) { tprintf("Constrained fit to dir %g, %g = %d, %d :%d distances:\n", direction.x(), direction.y(), line_pt->x(), line_pt->y(), distances_.size()); for (int i = 0; i < distances_.size(); ++i) { tprintf("%d: %d, %d -> %g\n", i, distances_[i].data.x(), distances_[i].data.y(), distances_[i].key); } tprintf("Result = %d\n", median_index); } // Center distances on the fitted point. double dist_origin = direction * *line_pt; for (int i = 0; i < distances_.size(); ++i) { distances_[i].key -= dist_origin; } return sqrt(EvaluateLineFit()); }
double tesseract::DetLineFit::ConstrainedFit | ( | double | m, |
float * | c | ||
) |
Definition at line 186 of file detlinefit.cpp.
{ // Do something sensible with no points. if (pts_.empty()) { *c = 0.0f; return 0.0; } double cos = 1.0 / sqrt(1.0 + m * m); FCOORD direction(cos, m * cos); ICOORD line_pt; double error = ConstrainedFit(direction, -MAX_FLOAT32, MAX_FLOAT32, false, &line_pt); *c = line_pt.y() - line_pt.x() * m; return error; }
double tesseract::DetLineFit::Fit | ( | ICOORD * | pt1, |
ICOORD * | pt2 | ||
) | [inline] |
Definition at line 75 of file detlinefit.h.
{ return Fit(0, 0, pt1, pt2); }
double tesseract::DetLineFit::Fit | ( | int | skip_first, |
int | skip_last, | ||
ICOORD * | pt1, | ||
ICOORD * | pt2 | ||
) |
Definition at line 66 of file detlinefit.cpp.
{ // Do something sensible with no points. if (pts_.empty()) { pt1->set_x(0); pt1->set_y(0); *pt2 = *pt1; return 0.0; } // Count the points and find the first and last kNumEndPoints. int pt_count = pts_.size(); ICOORD* starts[kNumEndPoints]; if (skip_first >= pt_count) skip_first = pt_count - 1; int start_count = 0; int end_i = MIN(skip_first + kNumEndPoints, pt_count); for (int i = skip_first; i < end_i; ++i) { starts[start_count++] = &pts_[i].pt; } ICOORD* ends[kNumEndPoints]; if (skip_last >= pt_count) skip_last = pt_count - 1; int end_count = 0; end_i = MAX(0, pt_count - kNumEndPoints - skip_last); for (int i = pt_count - 1 - skip_last; i >= end_i; --i) { ends[end_count++] = &pts_[i].pt; } // 1 or 2 points need special treatment. if (pt_count <= 2) { *pt1 = *starts[0]; if (pt_count > 1) *pt2 = *ends[0]; else *pt2 = *pt1; return 0.0; } // Although with between 2 and 2*kNumEndPoints-1 points, there will be // overlap in the starts, ends sets, this is OK and taken care of by the // if (*start != *end) test below, which also tests for equal input points. double best_uq = -1.0; // Iterate each pair of points and find the best fitting line. for (int i = 0; i < start_count; ++i) { ICOORD* start = starts[i]; for (int j = 0; j < end_count; ++j) { ICOORD* end = ends[j]; if (*start != *end) { ComputeDistances(*start, *end); // Compute the upper quartile error from the line. double dist = EvaluateLineFit(); if (dist < best_uq || best_uq < 0.0) { best_uq = dist; *pt1 = *start; *pt2 = *end; } } } } // Finally compute the square root to return the true distance. return best_uq > 0.0 ? sqrt(best_uq) : best_uq; }
double tesseract::DetLineFit::Fit | ( | float * | m, |
float * | c | ||
) |
bool tesseract::DetLineFit::SufficientPointsForIndependentFit | ( | ) | const |
Definition at line 163 of file detlinefit.cpp.
{ return distances_.size() >= kMinPointsForErrorCount; }