Added extract_image_4points()

This commit is contained in:
Davis King 2018-05-23 22:53:18 -04:00
parent 5edab25c58
commit 844b355232
2 changed files with 146 additions and 0 deletions

View File

@ -2145,6 +2145,98 @@ namespace dlib
return res;
}
// ----------------------------------------------------------------------------------------
template <
typename image_type
>
void extract_image_4points (
const image_type& img_,
image_type& out_,
const std::vector<dpoint>& pts
)
{
DLIB_CASSERT(pts.size() == 4);
const_image_view<image_type> img(img_);
image_view<image_type> out(out_);
if (out.size() == 0)
return;
drectangle bounding_box;
for (auto& p : pts)
bounding_box += p;
const std::array<dpoint,4> corners = {bounding_box.tl_corner(), bounding_box.tr_corner(),
bounding_box.bl_corner(), bounding_box.br_corner()};
matrix<double> dists(4,4);
for (long r = 0; r < dists.nr(); ++r)
{
for (long c = 0; c < dists.nc(); ++c)
{
dists(r,c) = length_squared(corners[r] - pts[c]);
}
}
matrix<long long> idists = matrix_cast<long long>(-round(std::numeric_limits<long long>::max()*(dists/max(dists))));
const drectangle area = get_rect(out);
std::vector<dpoint> from_points = {area.tl_corner(), area.tr_corner(),
area.bl_corner(), area.br_corner()};
// find the assignment of corners to pts
auto assignment = max_cost_assignment(idists);
std::vector<dpoint> to_points(4);
for (size_t i = 0; i < assignment.size(); ++i)
to_points[i] = pts[assignment[i]];
auto tform = find_projective_transform(from_points, to_points);
transform_image(img_, out_, interpolate_bilinear(), tform);
}
template <
typename image_type
>
void extract_image_4points (
const image_type& img,
image_type& out,
const std::vector<line>& lines
)
{
DLIB_CASSERT(lines.size() == 4);
// first find the pair of lines that are most parallel to each other
size_t best_i=0, best_j=1;
double best_angle = 1000;
for (size_t i = 0; i < lines.size(); ++i)
{
for (size_t j = i+1; j < lines.size(); ++j)
{
double angle = angle_between_lines(lines[i],lines[j]);
if (angle < best_angle)
{
best_angle = angle;
best_i = i;
best_j = j;
}
}
}
std::vector<dpoint> pts;
// now find the corners of the best quadrilateral we can make from these lines.
for (size_t k = 0; k < lines.size(); ++k)
{
if (k == best_i || k == best_j)
continue;
pts.emplace_back(intersect(lines[k], lines[best_i]));
pts.emplace_back(intersect(lines[k], lines[best_j]));
}
extract_image_4points(img, out, pts);
}
// ----------------------------------------------------------------------------------------
template <

View File

@ -1448,6 +1448,60 @@ namespace dlib
one for each input full_object_detection.
!*/
// ----------------------------------------------------------------------------------------
template <
typename image_type
>
void extract_image_4points (
const image_type& img,
image_type& out,
const std::vector<dpoint>& pts
);
/*!
requires
- image_type == an image object that implements the interface defined in
dlib/image_processing/generic_image.h
- pixel_traits<typename image_traits<image_type>::pixel_type>::has_alpha == false
- pts.size() == 4
ensures
- The 4 points in pts define a convex quadrilateral and this function extracts
that part of the image and stores it into #out. Therefore, each corner of
the quadrilateral is associated to a corner of #out and bilinear
interpolation and a projective mapping is used to transform the pixels in the
quadrilateral in img into #out. To determine which corners of the
quadrilateral map to which corners of #out we fit the tightest possible
rectangle to the quadrilateral and map its vertices to their nearest
rectangle corners. These corners are then trivially mapped to #out (i.e.
upper left corner to upper left corner, upper right corner to upper right
corner, etc.).
- #out.nr() == out.nr() && #out.nc() == out.nc().
I.e. out should already be sized to whatever size you want it to be.
!*/
template <
typename image_type
>
void extract_image_4points (
const image_type& img,
image_type& out,
const std::vector<line>& lines
);
/*!
requires
- image_type == an image object that implements the interface defined in
dlib/image_processing/generic_image.h
- pixel_traits<typename image_traits<image_type>::pixel_type>::has_alpha == false
- lines.size() == 4
ensures
- This routine simply finds the 4 intersecting points of the given lines and
uses them in a call to the version of extract_image_4points() defined above.
i.e. extract_image_chips(img, out, intersections_between_lines)
- Since 4 lines might intersect at more than 4 locations, we select the
intersections that give a quadrilateral with opposing sides that are as
parallel as possible.
!*/
// ----------------------------------------------------------------------------------------
template <