00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef V4R_LINEBASE_H
00022 #define V4R_LINEBASE_H
00023
00024 #include <opencv/cv.h>
00025 #include <cstdio>
00026
00027 namespace V4R {
00028
00029 #ifndef V4R_LINE2D
00030 #define V4R_LINE2D
00031 template <typename T>
00032 class Line2D {
00033 friend class Line2DHdl;
00034 protected:
00035 cv::Vec<T,3> eq_;
00036 public:
00037 Line2D() {};
00038 Line2D(const Line2D &l): eq_(l.eq_) {};
00039 Line2D(cv::Vec<T,3> &r, bool normalize = true)
00040 : eq_(r) {
00041 if (normalize) this->normalize();
00042 };
00043 Line2D(cv::Mat &r, bool normalize = true)
00044 : eq_(*r.ptr<T>(0), *r.ptr<T>(1), *r.ptr<T>(2)) {
00045 if (normalize) this->normalize();
00046
00047 };
00048 template <typename T2>
00049 Line2D(const T2 &x1, const T2 &y1, const T2 &x2, const T2 &y2, bool normalize = true) {
00050 set(cv::Point_<T2>(x1,y1), cv::Point_<T2>(x2,y2), normalize);
00051 }
00052 template <typename T2>
00053 Line2D(const cv::Point_<T2> &pt1, const cv::Point_<T2> &pt2, bool normalize = true) {
00054 set(pt1, pt2, normalize);
00055 }
00056 template <typename T2>
00057 Line2D(const cv::Point3_<T2> &pt1, const cv::Point3_<T2> &pt2, bool normalize = true) {
00058 set(pt1, pt2, normalize);
00059 }
00060 template <typename T2, int cn>
00061 Line2D(const cv::Vec<T2, cn> &v1, const cv::Vec<T2, cn> &v2, bool normalize = true) {
00062 set(v1, v2, normalize);
00063 }
00064 T &A() {
00065 return eq_.val[0];
00066 }
00067 const T &A() const {
00068 return eq_.val[0];
00069 }
00070 T &B() {
00071 return eq_.val[1];
00072 }
00073 const T &B() const {
00074 return eq_.val[1];
00075 }
00076 T &C() {
00077 return eq_.val[2];
00078 }
00079 const T &C() const {
00080 return eq_.val[2];
00081 }
00082 void normalize() {
00083 double r = sqrt(eq_[0]*eq_[0] + eq_[1]*eq_[1]);
00084 eq_[0] /= r, eq_[1] /= r, eq_[2] /= r;
00085 }
00087 template <typename T2>
00088 T distanceToLine(const cv::Point_<T2> &p) {
00089 return eq_[0]*((T)p.x) + eq_[1]*((T)p.y) + eq_[2];
00090 }
00092 template <typename T2>
00093 std::vector<T> distanceToLine(const std::vector <cv::Point_<T2> > &points) {
00094 std::vector<T> d(points.size());
00095 for (int i = 0; i < d.size(); i++) d[i] = distanceToLine(points[i]);
00096 return d;
00097 }
00099 template <typename T2>
00100 cv::Point_<T> nearestPointOnLine(const cv::Point_<T2> &p) {
00101 T d = distanceToLine(p);
00102 return cv::Point_<T>(p.x - d * A(), p.y - d * B());
00103 }
00104 cv::Point_<T> intersection(const Line2D<T> &l) const{
00105 cv::Vec<T,3> h = eq_.cross(l.eq_);
00106 return cv::Point_<T>(h[0]/h[2],h[1]/h[2]);
00107 }
00108 cv::Vec<T,3> &eq() {
00109 return eq_;
00110 }
00111 cv::Vec<T,2> normal() {
00112 return cv::Vec<T,2>(eq_[0], eq_[1]);
00113 }
00114 const cv::Vec<T,3> &vec() const {
00115 return *this;
00116 }
00117 template <typename T2>
00118 void set(const cv::Point_<T2> &pt1, const cv::Point_<T2> &pt2, bool normalize = true) {
00119 cv::Vec<T, 3> p1(pt1.x, pt1.y, 1);
00120 cv::Vec<T, 3> p2(pt2.x, pt2.y, 1);
00121 eq_ = p1.cross(p2);
00122 if (normalize) this->normalize();
00123 }
00124 template <typename T2>
00125 void set(const cv::Point3_<T2> &pt1, const cv::Point3_<T2> &pt2, bool normalize = true) {
00126 cv::Vec<T, 3> p1(pt1.x, pt1.y, 1);
00127 cv::Vec<T, 3> p2(pt2.x, pt2.y, 1);
00128 eq_ = p1.cross(p2);
00129 if (normalize) this->normalize();
00130 }
00131 template <typename T2, int cn>
00132 void set(const cv::Vec<T2, cn> &v1, const cv::Vec<T2, cn> &v2, bool normalize = true) {
00133 cv::Vec<T, 3> p1(v1[0], v1[1], 1);
00134 cv::Vec<T, 3> p2(v2[0], v2[1], 1);
00135 eq_ = p1.cross(p2);
00136 if (normalize) this->normalize();
00137 }
00142 std::string human_readable() const
00143 {
00144 char pText[0xFF];
00145 sprintf ( pText, "l = [ %-8.3f, %-8.3f, %-8.3f]", (double) A(), (double) B(), (double) C());
00146 return pText;
00147 }
00148 };
00149 typedef Line2D<float> Line2Df;
00150 typedef Line2D<double> Line2Dd;
00151 #endif //V4R_LINE2D
00152
00153 #ifndef V4R_LINESEGMENT2D
00154 #define V4R_LINESEGMENT2D
00155 template <typename T>
00156 class LineSegment2D {
00157 friend class Line2DHdl;
00158 protected:
00159 cv::Point_<T> p1_, p2_;
00160 public:
00161 LineSegment2D() {};
00162 LineSegment2D(const LineSegment2D &l) : p1_(l.p1_), p2_(l.p2_) {};
00163 LineSegment2D(cv::Vec<T,4> &v) :p1_(v[0], v[1]), p2_(v[2], v[3]) {};
00164 template <typename T2>
00165 LineSegment2D(const cv::Point_<T2> &pt1, const cv::Point_<T2> &pt2):p1_(pt1), p2_(pt2) {};
00166 template <typename T2, typename T3>
00167 LineSegment2D(const cv::Vec<T2,3> &eq, const cv::Rect_<T3> &rect) {
00168 p1_.x = rect.x;
00169 p2_.x = rect.x + rect.width-1;
00170 p1_.y = -(eq[0] * p1_.x() + eq[2]) / eq[1];
00171 p2_.y = -(eq[0] * p2_.x() + eq[2]) / eq[1];
00172 };
00173 template <typename T2, typename T3>
00174 LineSegment2D(const cv::Vec<T2,3> &eq, const cv::Size_<T3> &size) {
00175 p1_.x = 0;
00176 p2_.x = size.width-1;
00177 p1_.y = -(eq[2]) / eq[1];
00178 p2_.y = -(eq[0] * p2_.x + eq[2]) / eq[1];
00179 };
00180 template <typename T2, typename T3>
00181 LineSegment2D(const Line2D<T2> &line, const cv::Size_<T3> &size) {
00182 p1_.x = 0;
00183 p2_.x = size.width-1;
00184 p1_.y = -(line.C()) / line.B();
00185 p2_.y = -(line.A() * p2_.x + line.C()) / line.B();
00186 };
00187 T &x1() {
00188 return p1_.x;
00189 }
00190 const T &x1() const {
00191 return p1_.x;
00192 }
00193 T &y1() {
00194 return p1_.y;
00195 }
00196 const T &y1() const {
00197 return p1_.y;
00198 }
00199 T &x2() {
00200 return p2_.x;
00201 }
00202 const T &x2() const {
00203 return p2_.x;
00204 }
00205 T &y2() {
00206 return p2_.y;;
00207 }
00208 const T &y2() const {
00209 return p2_.y;
00210 }
00211 cv::Point_<T> &p1() {
00212 return p1_;
00213 }
00214 const cv::Point_<T> &p1() const {
00215 return p1_;
00216 }
00217 cv::Point_<T> &p2() {
00218 return p2_;
00219 }
00220 const cv::Point_<T> &p2() const {
00221 return p2_;
00222 }
00223 };
00224 typedef LineSegment2D<float> LineSegment2Df;
00225 typedef LineSegment2D<double> LineSegment2Dd;
00226 #endif //V4R_LINESEGMENT2D
00227
00228 };
00229 #endif // V4R_LINE_H