Commit e2c79e8e authored by Davis King's avatar Davis King

Changed extract_image_chips() so that it doesn't build image pyramids larger

than necessary when pulling out chips.
parent e3c38ba0
...@@ -1556,7 +1556,8 @@ namespace dlib ...@@ -1556,7 +1556,8 @@ namespace dlib
{ {
chip_details() : angle(0), rows(0), cols(0) {} chip_details() : angle(0), rows(0), cols(0) {}
chip_details(const rectangle& rect_) : rect(rect_),angle(0), rows(rect_.height()), cols(rect_.width()) {} chip_details(const rectangle& rect_) : rect(rect_),angle(0), rows(rect_.height()), cols(rect_.width()) {}
chip_details(const drectangle& rect_) : rect(rect_),angle(0), rows(rect_.height()), cols(rect_.width()) {} chip_details(const drectangle& rect_) : rect(rect_),angle(0),
rows((unsigned long)(rect_.height()+0.5)), cols((unsigned long)(rect_.width()+0.5)) {}
chip_details(const drectangle& rect_, unsigned long size) : rect(rect_),angle(0) chip_details(const drectangle& rect_, unsigned long size) : rect(rect_),angle(0)
{ compute_dims_from_size(size); } { compute_dims_from_size(size); }
chip_details(const drectangle& rect_, unsigned long size, double angle_) : rect(rect_),angle(angle_) chip_details(const drectangle& rect_, unsigned long size, double angle_) : rect(rect_),angle(angle_)
...@@ -1617,6 +1618,8 @@ namespace dlib ...@@ -1617,6 +1618,8 @@ namespace dlib
const double relative_size = std::sqrt(size/(double)rect.area()); const double relative_size = std::sqrt(size/(double)rect.area());
rows = static_cast<unsigned long>(rect.height()*relative_size + 0.5); rows = static_cast<unsigned long>(rect.height()*relative_size + 0.5);
cols = static_cast<unsigned long>(size/(double)rows + 0.5); cols = static_cast<unsigned long>(size/(double)rows + 0.5);
rows = std::max(1ul,rows);
cols = std::max(1ul,cols);
} }
}; };
...@@ -1738,22 +1741,36 @@ namespace dlib ...@@ -1738,22 +1741,36 @@ namespace dlib
// interpolation. So we use an image pyramid to make sure the interpolation is // interpolation. So we use an image pyramid to make sure the interpolation is
// fast but also high quality. The first thing we do is figure out how deep the // fast but also high quality. The first thing we do is figure out how deep the
// image pyramid needs to be. // image pyramid needs to be.
rectangle bounding_box;
for (unsigned long i = 0; i < chip_locations.size(); ++i) for (unsigned long i = 0; i < chip_locations.size(); ++i)
{ {
long depth = 0; long depth = 0;
double grow = 2;
drectangle rect = pyr.rect_down(chip_locations[i].rect); drectangle rect = pyr.rect_down(chip_locations[i].rect);
while (rect.area() > chip_locations[i].size()) while (rect.area() > chip_locations[i].size())
{ {
rect = pyr.rect_down(rect); rect = pyr.rect_down(rect);
++depth; ++depth;
// We drop the image size by a factor of 2 each iteration and then assume a
// border of 2 pixels is needed to avoid any border effects of the crop.
grow = grow*2 + 2;
} }
drectangle rot_rect;
const vector<double,2> cent = center(chip_locations[i].rect);
rot_rect += rotate_point<double>(cent,chip_locations[i].rect.tl_corner(),chip_locations[i].angle);
rot_rect += rotate_point<double>(cent,chip_locations[i].rect.tr_corner(),chip_locations[i].angle);
rot_rect += rotate_point<double>(cent,chip_locations[i].rect.bl_corner(),chip_locations[i].angle);
rot_rect += rotate_point<double>(cent,chip_locations[i].rect.br_corner(),chip_locations[i].angle);
bounding_box += grow_rect(rot_rect, grow).intersect(get_rect(img));
max_depth = std::max(depth,max_depth); max_depth = std::max(depth,max_depth);
} }
//std::cout << "max_depth: " << max_depth << std::endl;
//std::cout << "crop amount: " << bounding_box.area()/(double)get_rect(img).area() << std::endl;
// now make an image pyramid // now make an image pyramid
dlib::array<array2d<typename image_traits<image_type1>::pixel_type> > levels(max_depth); dlib::array<array2d<typename image_traits<image_type1>::pixel_type> > levels(max_depth);
if (levels.size() != 0) if (levels.size() != 0)
pyr(img,levels[0]); pyr(sub_image(img,bounding_box),levels[0]);
for (unsigned long i = 1; i < levels.size(); ++i) for (unsigned long i = 1; i < levels.size(); ++i)
pyr(levels[i-1],levels[i]); pyr(levels[i-1],levels[i]);
...@@ -1777,7 +1794,7 @@ namespace dlib ...@@ -1777,7 +1794,7 @@ namespace dlib
// figure out which level in the pyramid to use to extract the chip // figure out which level in the pyramid to use to extract the chip
int level = -1; int level = -1;
drectangle rect = chip_locations[i].rect; drectangle rect = translate_rect(chip_locations[i].rect, -bounding_box.tl_corner());
while (pyr.rect_down(rect).area() > chip_locations[i].size()) while (pyr.rect_down(rect).area() > chip_locations[i].size())
{ {
++level; ++level;
...@@ -1795,7 +1812,7 @@ namespace dlib ...@@ -1795,7 +1812,7 @@ namespace dlib
// now extract the actual chip // now extract the actual chip
if (level == -1) if (level == -1)
transform_image(img,chips[i],interpolate_bilinear(),trns); transform_image(sub_image(img,bounding_box),chips[i],interpolate_bilinear(),trns);
else else
transform_image(levels[level],chips[i],interpolate_bilinear(),trns); transform_image(levels[level],chips[i],interpolate_bilinear(),trns);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment