mirror of https://github.com/davisking/dlib.git
Clarified the spec for extract_image_chips() and also made it so the user can
explicitly specify the dimensions of the extracted chips.
This commit is contained in:
parent
5d659af761
commit
fe3d5901c1
|
@ -1398,15 +1398,49 @@ namespace dlib
|
|||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
struct chip_dims
|
||||
{
|
||||
chip_dims (
|
||||
unsigned long rows_,
|
||||
unsigned long cols_
|
||||
) : rows(rows_), cols(cols_) { }
|
||||
|
||||
unsigned long rows;
|
||||
unsigned long cols;
|
||||
};
|
||||
|
||||
struct chip_details
|
||||
{
|
||||
chip_details() : size(0), angle(0) {}
|
||||
chip_details(const rectangle& rect_, unsigned long size_) : rect(rect_),size(size_),angle(0) {}
|
||||
chip_details(const rectangle& rect_, unsigned long size_, double angle_) : rect(rect_),size(size_),angle(angle_) {}
|
||||
chip_details() : angle(0), rows(0), cols(0) {}
|
||||
chip_details(const rectangle& rect_, unsigned long size) : rect(rect_),angle(0)
|
||||
{ compute_dims_from_size(size); }
|
||||
chip_details(const rectangle& rect_, unsigned long size, double angle_) : rect(rect_),angle(angle_)
|
||||
{ compute_dims_from_size(size); }
|
||||
|
||||
chip_details(const rectangle& rect_, const chip_dims& dims) :
|
||||
rect(rect_),angle(0),rows(dims.rows), cols(dims.cols) {}
|
||||
chip_details(const rectangle& rect_, const chip_dims& dims, double angle_) :
|
||||
rect(rect_),angle(angle_),rows(dims.rows), cols(dims.cols) {}
|
||||
|
||||
rectangle rect;
|
||||
unsigned long size;
|
||||
double angle;
|
||||
unsigned long rows;
|
||||
unsigned long cols;
|
||||
|
||||
inline unsigned long size() const
|
||||
{
|
||||
return rows*cols;
|
||||
}
|
||||
|
||||
private:
|
||||
void compute_dims_from_size (
|
||||
unsigned long size
|
||||
)
|
||||
{
|
||||
const double relative_size = std::sqrt(size/(double)rect.area());
|
||||
rows = static_cast<unsigned long>(rect.height()*relative_size + 0.5);
|
||||
cols = static_cast<unsigned long>(size/(double)rows + 0.5);
|
||||
}
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
@ -1425,11 +1459,11 @@ namespace dlib
|
|||
#ifdef ENABLE_ASSERTS
|
||||
for (unsigned long i = 0; i < chip_locations.size(); ++i)
|
||||
{
|
||||
DLIB_CASSERT(chip_locations[i].size != 0 &&
|
||||
DLIB_CASSERT(chip_locations[i].size() != 0 &&
|
||||
chip_locations[i].rect.is_empty() == false,
|
||||
"\t void extract_image_chips()"
|
||||
<< "\n\t Invalid inputs were given to this function."
|
||||
<< "\n\t chip_locations["<<i<<"].size: " << chip_locations[i].size
|
||||
<< "\n\t chip_locations["<<i<<"].size(): " << chip_locations[i].size()
|
||||
<< "\n\t chip_locations["<<i<<"].rect.is_empty(): " << chip_locations[i].rect.is_empty()
|
||||
);
|
||||
}
|
||||
|
@ -1447,7 +1481,7 @@ namespace dlib
|
|||
{
|
||||
long depth = 0;
|
||||
rectangle 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);
|
||||
++depth;
|
||||
|
@ -1468,15 +1502,12 @@ namespace dlib
|
|||
chips.resize(chip_locations.size());
|
||||
for (unsigned long i = 0; i < chips.size(); ++i)
|
||||
{
|
||||
const double relative_size = std::sqrt(chip_locations[i].size/(double)chip_locations[i].rect.area());
|
||||
const long chip_height = static_cast<long>(chip_locations[i].rect.height()*relative_size + 0.5);
|
||||
const long chip_width = static_cast<long>(chip_locations[i].size/(double)chip_height + 0.5);
|
||||
chips[i].set_size(chip_height, chip_width);
|
||||
chips[i].set_size(chip_locations[i].rows, chip_locations[i].cols);
|
||||
|
||||
// figure out which level in the pyramid to use to extract the chip
|
||||
int level = -1;
|
||||
rectangle rect = chip_locations[i].rect;
|
||||
while (pyr.rect_down(rect).area() > chip_locations[i].size)
|
||||
while (pyr.rect_down(rect).area() > chip_locations[i].size())
|
||||
{
|
||||
++level;
|
||||
rect = pyr.rect_down(rect);
|
||||
|
|
|
@ -858,6 +858,25 @@ namespace dlib
|
|||
!*/
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
struct chip_dims
|
||||
{
|
||||
/*!
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
This is a simple tool for passing in a pair of row and column values to the
|
||||
chip_details constructor.
|
||||
!*/
|
||||
|
||||
chip_dims (
|
||||
unsigned long rows_,
|
||||
unsigned long cols_
|
||||
) : rows(rows_), cols(cols_) { }
|
||||
|
||||
unsigned long rows;
|
||||
unsigned long cols;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
struct chip_details
|
||||
|
@ -868,8 +887,8 @@ namespace dlib
|
|||
another image. In particular, it specifies that the image chip is
|
||||
contained within the rectangle this->rect and that prior to extraction the
|
||||
image should be rotated counter-clockwise by this->angle radians. Finally,
|
||||
the extracted chip should have this->size pixels in it regardless of the
|
||||
size of this->rect.
|
||||
the extracted chip should have this->rows rows and this->cols columns in it
|
||||
regardless of the shape of this->rect.
|
||||
|
||||
!*/
|
||||
|
||||
|
@ -878,8 +897,10 @@ namespace dlib
|
|||
/*!
|
||||
ensures
|
||||
- #rect.is_empty() == true
|
||||
- #size == 0
|
||||
- #size() == 0
|
||||
- #angle == 0
|
||||
- #rows == 0
|
||||
- #cols == 0
|
||||
!*/
|
||||
|
||||
chip_details(
|
||||
|
@ -889,8 +910,18 @@ namespace dlib
|
|||
/*!
|
||||
ensures
|
||||
- #rect == rect_
|
||||
- #size == size_
|
||||
- #size() == size_
|
||||
- #angle == 0
|
||||
- #rows and #cols is set such that the total size of the chip is as close
|
||||
to size_ as possible but still matches the aspect ratio of rect_.
|
||||
- As long as size_ and the aspect ratio of of rect_ stays constant then
|
||||
#rows and #cols will always have the same values. This means that, for
|
||||
example, if you want all your chips to have the same dimensions then
|
||||
ensure that size_ is always the same and also that rect_ always has the
|
||||
same aspect ratio. Otherwise the calculated values of #rows and #cols
|
||||
may be different for different chips. Alternatively, you can use the
|
||||
chip_details constructor below that lets you specify the exact values for
|
||||
rows and cols.
|
||||
!*/
|
||||
|
||||
chip_details(
|
||||
|
@ -901,13 +932,57 @@ namespace dlib
|
|||
/*!
|
||||
ensures
|
||||
- #rect == rect_
|
||||
- #size == size_
|
||||
- #size() == size_
|
||||
- #angle == angle_
|
||||
- #rows and #cols is set such that the total size of the chip is as close
|
||||
to size_ as possible but still matches the aspect ratio of rect_.
|
||||
- As long as size_ and the aspect ratio of of rect_ stays constant then
|
||||
#rows and #cols will always have the same values. This means that, for
|
||||
example, if you want all your chips to have the same dimensions then
|
||||
ensure that size_ is always the same and also that rect_ always has the
|
||||
same aspect ratio. Otherwise the calculated values of #rows and #cols
|
||||
may be different for different chips. Alternatively, you can use the
|
||||
chip_details constructor below that lets you specify the exact values for
|
||||
rows and cols.
|
||||
!*/
|
||||
|
||||
chip_details(
|
||||
const rectangle& rect_,
|
||||
const chip_dims& dims
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #rect == rect_
|
||||
- #size() == dims.rows*dims.cols
|
||||
- #angle == 0
|
||||
- #rows == dims.rows
|
||||
- #cols == dims.cols
|
||||
!*/
|
||||
|
||||
chip_details(
|
||||
const rectangle& rect_,
|
||||
const chip_dims& dims,
|
||||
double angle_
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #rect == rect_
|
||||
- #size() == dims.rows*dims.cols
|
||||
- #angle == angle_
|
||||
- #rows == dims.rows
|
||||
- #cols == dims.cols
|
||||
!*/
|
||||
|
||||
inline unsigned long size() const { return rows*cols; }
|
||||
/*!
|
||||
ensures
|
||||
- returns the number of pixels in this chip. This is just rows*cols.
|
||||
!*/
|
||||
|
||||
rectangle rect;
|
||||
unsigned long size;
|
||||
double angle;
|
||||
unsigned long rows;
|
||||
unsigned long cols;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
@ -940,21 +1015,11 @@ namespace dlib
|
|||
- for all valid i:
|
||||
- #chips[i] == The image chip extracted from the position
|
||||
chip_locations[i].rect in img.
|
||||
- #chips[i].nr()/#chips[i].nc() is approximately equal to
|
||||
chip_locations[i].rect.height()/chip_locations[i].rect.width() (i.e. the
|
||||
aspect ratio of the chip is as similar as possible to the aspect ratio of
|
||||
the rectangle that defines the chip's location in the original image)
|
||||
- #chips[i].size() is as close to chip_locations[i].size as possible given that
|
||||
we attempt to keep the chip's aspect ratio similar to chip_locations[i].rect.
|
||||
- #chips[i].nr() == chip_locations[i].rows
|
||||
- #chips[i].nc() == chip_locations[i].cols
|
||||
- The image will have been rotated counter-clockwise by
|
||||
chip_locations[i].angle radians, around the center of
|
||||
chip_locations[i].rect, before the chip was extracted.
|
||||
- As long as chip_locations[i].size and the aspect ratio of of
|
||||
chip_locations[i].rect stays constant then the dimensions of #chips[i] is
|
||||
always the same. This means that, for example, if you want all your
|
||||
chips to have the same dimensions then ensure that chip_location[i].size
|
||||
is always the same and also that chip_location[i].rect always has the
|
||||
same aspect ratio.
|
||||
- Any pixels in an image chip that go outside img are set to 0 (i.e. black).
|
||||
!*/
|
||||
|
||||
|
|
Loading…
Reference in New Issue