// Copyright (C) 2013 Davis E. King (davis@dlib.net) // License: Boost Software License See LICENSE.txt for the full license. #include #include #include #include #include #include "indexing.h" using namespace dlib; using namespace std; using namespace boost::python; typedef matrix cv; void cv_set_size(cv& m, long s) { m.set_size(s); m = 0; } double dotprod ( const cv& a, const cv& b) { return dot(a,b); } string cv__str__(const cv& v) { ostringstream sout; for (long i = 0; i < v.size(); ++i) { sout << v(i); if (i+1 < v.size()) sout << "\n"; } return sout.str(); } string cv__repr__ (const cv& v) { std::ostringstream sout; sout << "dlib.vector(["; for (long i = 0; i < v.size(); ++i) { sout << v(i); if (i+1 < v.size()) sout << ", "; } sout << "])"; return sout.str(); } boost::shared_ptr cv_from_object(object obj) { extract thesize(obj); if (thesize.check()) { long nr = thesize; boost::shared_ptr temp(new cv(nr)); *temp = 0; return temp; } else { const long nr = len(obj); boost::shared_ptr temp(new cv(nr)); for ( long r = 0; r < nr; ++r) { (*temp)(r) = extract(obj[r]); } return temp; } } long cv__len__(cv& c) { return c.size(); } void cv__setitem__(cv& c, long p, double val) { if (p < 0) { p = c.size() + p; // negative index } if (p > c.size()-1) { PyErr_SetString( PyExc_IndexError, "index out of range" ); boost::python::throw_error_already_set(); } c(p) = val; } double cv__getitem__(cv& m, long r) { if (r < 0) { r = m.size() + r; // negative index } if (r > m.size()-1 || r < 0) { PyErr_SetString( PyExc_IndexError, "index out of range" ); boost::python::throw_error_already_set(); } return m(r); } cv cv__getitem2__(cv& m, slice r) { slice::range bounds; bounds = r.get_indicies<>(m.begin(), m.end()); long num = (bounds.stop-bounds.start+1); // round num up to the next multiple of bounds.step. if ((num%bounds.step) != 0) num += bounds.step - num%bounds.step; cv temp(num/bounds.step); if (temp.size() == 0) return temp; long ii = 0; while(bounds.start != bounds.stop) { temp(ii++) = *bounds.start; std::advance(bounds.start, bounds.step); } temp(ii) = *bounds.start; return temp; } boost::python::tuple cv_get_matrix_size(cv& m) { return boost::python::make_tuple(m.nr(), m.nc()); } // ---------------------------------------------------------------------------------------- string point__repr__ (const point& p) { std::ostringstream sout; sout << "point(" << p.x() << ", " << p.y() << ")"; return sout.str(); } string point__str__(const point& p) { std::ostringstream sout; sout << "(" << p.x() << ", " << p.y() << ")"; return sout.str(); } long point_x(const point& p) { return p.x(); } long point_y(const point& p) { return p.y(); } // ---------------------------------------------------------------------------------------- void bind_vector() { using boost::python::arg; { class_("vector", "This object represents the mathematical idea of a column vector.", init<>()) .def("set_size", &cv_set_size) .def("resize", &cv_set_size) .def("__init__", make_constructor(&cv_from_object)) .def("__repr__", &cv__repr__) .def("__str__", &cv__str__) .def("__len__", &cv__len__) .def("__getitem__", &cv__getitem__) .def("__getitem__", &cv__getitem2__) .def("__setitem__", &cv__setitem__) .add_property("shape", &cv_get_matrix_size) .def_pickle(serialize_pickle()); def("dot", dotprod, "Compute the dot product between two dense column vectors."); } { typedef point type; class_("point", "This object represents a single point of integer coordinates that maps directly to a dlib::point.") .def(init((arg("x"), arg("y")))) .def("__repr__", &point__repr__) .def("__str__", &point__str__) .add_property("x", &point_x, "The x-coordinate of the point.") .add_property("y", &point_y, "The y-coordinate of the point.") .def_pickle(serialize_pickle()); } { typedef std::vector type; class_("points", "An array of point objects.") .def(vector_indexing_suite()) .def("clear", &type::clear) .def("resize", resize) .def_pickle(serialize_pickle()); } }