mirror of
https://github.com/davisking/dlib.git
synced 2024-11-01 10:14:53 +08:00
Added extract_image_4points()
This commit is contained in:
parent
5edab25c58
commit
844b355232
@ -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 <
|
||||
|
@ -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 <
|
||||
|
Loading…
Reference in New Issue
Block a user