| 287 | |
| 288 | template <typename T> |
| 289 | point_transform_affine find_affine_transform ( |
| 290 | const std::vector<dlib::vector<T,2> >& from_points, |
| 291 | const std::vector<dlib::vector<T,2> >& to_points |
| 292 | ) |
| 293 | { |
| 294 | // make sure requires clause is not broken |
| 295 | DLIB_ASSERT(from_points.size() == to_points.size() && |
| 296 | from_points.size() >= 3, |
| 297 | "\t point_transform_affine find_affine_transform(from_points, to_points)" |
| 298 | << "\n\t Invalid inputs were given to this function." |
| 299 | << "\n\t from_points.size(): " << from_points.size() |
| 300 | << "\n\t to_points.size(): " << to_points.size() |
| 301 | ); |
| 302 | |
| 303 | matrix<double,3,0> P(3, from_points.size()); |
| 304 | matrix<double,2,0> Q(2, from_points.size()); |
| 305 | |
| 306 | for (unsigned long i = 0; i < from_points.size(); ++i) |
| 307 | { |
| 308 | P(0,i) = from_points[i].x(); |
| 309 | P(1,i) = from_points[i].y(); |
| 310 | P(2,i) = 1; |
| 311 | |
| 312 | Q(0,i) = to_points[i].x(); |
| 313 | Q(1,i) = to_points[i].y(); |
| 314 | } |
| 315 | |
| 316 | const matrix<double,2,3> m = Q*pinv(P); |
| 317 | return point_transform_affine(subm(m,0,0,2,2), colm(m,2)); |
| 318 | } |
| 319 | |
| 320 | // ---------------------------------------------------------------------------------------- |
| 321 | |