Commit 770067a0 authored by Davis King's avatar Davis King

Added a version of pyramid_down which scales at a ratio of 5:4

parent 59f69052
...@@ -799,6 +799,297 @@ namespace dlib ...@@ -799,6 +799,297 @@ namespace dlib
private: private:
};
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
class pyramid_down_5_4 : noncopyable
{
public:
template <typename T>
vector<double,2> point_down (
const vector<T,2>& p
) const
{
const double ratio = 4.0/5.0;
//do return (p - vector<T,2>(1,1))*ratio;
return p*ratio - vector<double,2>(ratio,ratio);
}
template <typename T>
vector<double,2> point_up (
const vector<T,2>& p
) const
{
const double ratio = 5.0/4.0;
return p*ratio + vector<T,2>(1,1);
}
// -----------------------------
template <typename T>
vector<double,2> point_down (
const vector<T,2>& p,
unsigned int levels
) const
{
vector<double,2> temp = p;
for (unsigned int i = 0; i < levels; ++i)
temp = point_down(temp);
return temp;
}
template <typename T>
vector<double,2> point_up (
const vector<T,2>& p,
unsigned int levels
) const
{
vector<double,2> temp = p;
for (unsigned int i = 0; i < levels; ++i)
temp = point_up(temp);
return temp;
}
// -----------------------------
rectangle rect_up (
const rectangle& rect
) const
{
return rectangle(point_up(rect.tl_corner()), point_up(rect.br_corner()));
}
rectangle rect_up (
const rectangle& rect,
unsigned int levels
) const
{
return rectangle(point_up(rect.tl_corner(),levels), point_up(rect.br_corner(),levels));
}
// -----------------------------
rectangle rect_down (
const rectangle& rect
) const
{
return rectangle(point_down(rect.tl_corner()), point_down(rect.br_corner()));
}
rectangle rect_down (
const rectangle& rect,
unsigned int levels
) const
{
return rectangle(point_down(rect.tl_corner(),levels), point_down(rect.br_corner(),levels));
}
// -----------------------------
private:
template <typename T, typename U>
struct both_images_rgb
{
const static bool value = pixel_traits<typename T::type>::rgb &&
pixel_traits<typename U::type>::rgb;
};
public:
template <
typename in_image_type,
typename out_image_type
>
typename disable_if<both_images_rgb<in_image_type,out_image_type> >::type operator() (
const in_image_type& original,
out_image_type& down
) const
{
// make sure requires clause is not broken
DLIB_ASSERT(original.nr() > 10 && original.nc() > 10 &&
is_same_object(original, down) == false,
"\t void pyramid_down_5_4::operator()"
<< "\n\t original.nr(): " << original.nr()
<< "\n\t original.nc(): " << original.nc()
<< "\n\t is_same_object(original, down): " << is_same_object(original, down)
<< "\n\t this: " << this
);
COMPILE_TIME_ASSERT( pixel_traits<typename in_image_type::type>::has_alpha == false );
COMPILE_TIME_ASSERT( pixel_traits<typename out_image_type::type>::has_alpha == false );
const long size_in = 5;
const long size_out = 4;
typedef typename pixel_traits<typename in_image_type::type>::basic_pixel_type bp_type;
typedef typename promote<bp_type>::type ptype;
down.set_size(size_out*((original.nr()-2)/size_in), size_out*((original.nc()-2)/size_in));
long rr = 1;
for (long r = 0; r < down.nr(); r+=size_out)
{
long cc = 1;
for (long c = 0; c < down.nc(); c+=size_out)
{
ptype block[size_in][size_in];
separable_3x3_filter_block_grayscale(block, original, rr, cc, 3, 10, 3);
// bi-linearly interpolate block
assign_pixel(down[r][c] , (block[0][0]*49 + block[1][0]*7 + block[0][1]*7 + block[1][1] )/(64*256));
assign_pixel(down[r][c+1] , (block[0][1]*35 + block[0][2]*21 + block[1][1]*5 + block[1][2]*3 )/(64*256));
assign_pixel(down[r][c+2] , (block[0][3]*35 + block[0][2]*21 + block[1][3]*5 + block[1][2]*3 )/(64*256));
assign_pixel(down[r][c+3] , (block[0][4]*49 + block[0][3]*7 + block[1][4]*7 + block[1][3] )/(64*256));
assign_pixel(down[r+1][c] , (block[1][0]*35 + block[1][1]*5 + block[2][0]*21 + block[1][1]*3 )/(64*256));
assign_pixel(down[r+1][c+1] , (block[1][1]*25 + block[1][2]*15 + block[2][1]*15 + block[2][2]*9 )/(64*256));
assign_pixel(down[r+1][c+2] , (block[1][2]*15 + block[1][3]*25 + block[2][2]*9 + block[2][3]*15)/(64*256));
assign_pixel(down[r+1][c+3] , (block[1][3]*5 + block[1][4]*35 + block[2][3]*3 + block[2][4]*21)/(64*256));
assign_pixel(down[r+2][c] , (block[3][0]*35 + block[3][1]*5 + block[2][0]*21 + block[1][1]*3 )/(64*256));
assign_pixel(down[r+2][c+1] , (block[3][1]*25 + block[3][2]*15 + block[2][1]*15 + block[2][2]*9 )/(64*256));
assign_pixel(down[r+2][c+2] , (block[3][2]*15 + block[3][3]*25 + block[2][2]*9 + block[2][3]*15)/(64*256));
assign_pixel(down[r+2][c+3] , (block[3][3]*5 + block[3][4]*35 + block[2][3]*3 + block[2][4]*21)/(64*256));
assign_pixel(down[r+3][c] , (block[4][0]*49 + block[3][0]*7 + block[4][1]*7 + block[3][1] )/(64*256));
assign_pixel(down[r+3][c+1] , (block[4][1]*35 + block[4][2]*21 + block[3][1]*5 + block[3][2]*3 )/(64*256));
assign_pixel(down[r+3][c+2] , (block[4][3]*35 + block[4][2]*21 + block[3][3]*5 + block[3][2]*3 )/(64*256));
assign_pixel(down[r+3][c+3] , (block[4][4]*49 + block[4][3]*7 + block[3][4]*7 + block[3][3] )/(64*256));
cc += size_in;
}
rr += size_in;
}
}
private:
struct rgbptype
{
uint32 red;
uint32 green;
uint32 blue;
};
public:
// ------------------------------------------
// OVERLOAD FOR RGB TO RGB IMAGES
// ------------------------------------------
template <
typename in_image_type,
typename out_image_type
>
typename enable_if<both_images_rgb<in_image_type,out_image_type> >::type operator() (
const in_image_type& original,
out_image_type& down
) const
{
// make sure requires clause is not broken
DLIB_ASSERT(original.nr() > 10 && original.nc() > 10 &&
is_same_object(original, down) == false,
"\t void pyramid_down_5_4::operator()"
<< "\n\t original.nr(): " << original.nr()
<< "\n\t original.nc(): " << original.nc()
<< "\n\t is_same_object(original, down): " << is_same_object(original, down)
<< "\n\t this: " << this
);
COMPILE_TIME_ASSERT( pixel_traits<typename in_image_type::type>::has_alpha == false );
COMPILE_TIME_ASSERT( pixel_traits<typename out_image_type::type>::has_alpha == false );
const long size_in = 5;
const long size_out = 4;
down.set_size(size_out*((original.nr()-2)/size_in), size_out*((original.nc()-2)/size_in));
long rr = 1;
for (long r = 0; r < down.nr(); r+=size_out)
{
long cc = 1;
for (long c = 0; c < down.nc(); c+=size_out)
{
rgbptype block[size_in][size_in];
separable_3x3_filter_block_rgb(block, original, rr, cc, 3, 10, 3);
// bi-linearly interpolate block
down[r][c].red = (block[0][0].red*49 + block[1][0].red*7 + block[0][1].red*7 + block[1][1].red )/(64*256);
down[r][c].green = (block[0][0].green*49 + block[1][0].green*7 + block[0][1].green*7 + block[1][1].green )/(64*256);
down[r][c].blue = (block[0][0].blue*49 + block[1][0].blue*7 + block[0][1].blue*7 + block[1][1].blue )/(64*256);
down[r][c+1].red = (block[0][1].red*35 + block[0][2].red*21 + block[1][1].red*5 + block[1][2].red*3 )/(64*256);
down[r][c+1].green = (block[0][1].green*35 + block[0][2].green*21 + block[1][1].green*5 + block[1][2].green*3 )/(64*256);
down[r][c+1].blue = (block[0][1].blue*35 + block[0][2].blue*21 + block[1][1].blue*5 + block[1][2].blue*3 )/(64*256);
down[r][c+2].red = (block[0][3].red*35 + block[0][2].red*21 + block[1][3].red*5 + block[1][2].red*3 )/(64*256);
down[r][c+2].green = (block[0][3].green*35 + block[0][2].green*21 + block[1][3].green*5 + block[1][2].green*3 )/(64*256);
down[r][c+2].blue = (block[0][3].blue*35 + block[0][2].blue*21 + block[1][3].blue*5 + block[1][2].blue*3 )/(64*256);
down[r][c+3].red = (block[0][4].red*49 + block[0][3].red*7 + block[1][4].red*7 + block[1][3].red )/(64*256);
down[r][c+3].green = (block[0][4].green*49 + block[0][3].green*7 + block[1][4].green*7 + block[1][3].green )/(64*256);
down[r][c+3].blue = (block[0][4].blue*49 + block[0][3].blue*7 + block[1][4].blue*7 + block[1][3].blue )/(64*256);
down[r+1][c].red = (block[1][0].red*35 + block[1][1].red*5 + block[2][0].red*21 + block[1][1].red*3 )/(64*256);
down[r+1][c].green = (block[1][0].green*35 + block[1][1].green*5 + block[2][0].green*21 + block[1][1].green*3 )/(64*256);
down[r+1][c].blue = (block[1][0].blue*35 + block[1][1].blue*5 + block[2][0].blue*21 + block[1][1].blue*3 )/(64*256);
down[r+1][c+1].red = (block[1][1].red*25 + block[1][2].red*15 + block[2][1].red*15 + block[2][2].red*9 )/(64*256);
down[r+1][c+1].green = (block[1][1].green*25 + block[1][2].green*15 + block[2][1].green*15 + block[2][2].green*9 )/(64*256);
down[r+1][c+1].blue = (block[1][1].blue*25 + block[1][2].blue*15 + block[2][1].blue*15 + block[2][2].blue*9 )/(64*256);
down[r+1][c+2].red = (block[1][2].red*15 + block[1][3].red*25 + block[2][2].red*9 + block[2][3].red*15 )/(64*256);
down[r+1][c+2].green = (block[1][2].green*15 + block[1][3].green*25 + block[2][2].green*9 + block[2][3].green*15)/(64*256);
down[r+1][c+2].blue = (block[1][2].blue*15 + block[1][3].blue*25 + block[2][2].blue*9 + block[2][3].blue*15 )/(64*256);
down[r+1][c+3].red = (block[1][3].red*5 + block[1][4].red*35 + block[2][3].red*3 + block[2][4].red*21 )/(64*256);
down[r+1][c+3].green = (block[1][3].green*5 + block[1][4].green*35 + block[2][3].green*3 + block[2][4].green*21)/(64*256);
down[r+1][c+3].blue = (block[1][3].blue*5 + block[1][4].blue*35 + block[2][3].blue*3 + block[2][4].blue*21 )/(64*256);
down[r+2][c].red = (block[3][0].red*35 + block[3][1].red*5 + block[2][0].red*21 + block[1][1].red*3 )/(64*256);
down[r+2][c].green = (block[3][0].green*35 + block[3][1].green*5 + block[2][0].green*21 + block[1][1].green*3 )/(64*256);
down[r+2][c].blue = (block[3][0].blue*35 + block[3][1].blue*5 + block[2][0].blue*21 + block[1][1].blue*3 )/(64*256);
down[r+2][c+1].red = (block[3][1].red*25 + block[3][2].red*15 + block[2][1].red*15 + block[2][2].red*9 )/(64*256);
down[r+2][c+1].green = (block[3][1].green*25 + block[3][2].green*15 + block[2][1].green*15 + block[2][2].green*9 )/(64*256);
down[r+2][c+1].blue = (block[3][1].blue*25 + block[3][2].blue*15 + block[2][1].blue*15 + block[2][2].blue*9 )/(64*256);
down[r+2][c+2].red = (block[3][2].red*15 + block[3][3].red*25 + block[2][2].red*9 + block[2][3].red*15 )/(64*256);
down[r+2][c+2].green = (block[3][2].green*15 + block[3][3].green*25 + block[2][2].green*9 + block[2][3].green*15)/(64*256);
down[r+2][c+2].blue = (block[3][2].blue*15 + block[3][3].blue*25 + block[2][2].blue*9 + block[2][3].blue*15 )/(64*256);
down[r+2][c+3].red = (block[3][3].red*5 + block[3][4].red*35 + block[2][3].red*3 + block[2][4].red*21 )/(64*256);
down[r+2][c+3].green = (block[3][3].green*5 + block[3][4].green*35 + block[2][3].green*3 + block[2][4].green*21)/(64*256);
down[r+2][c+3].blue = (block[3][3].blue*5 + block[3][4].blue*35 + block[2][3].blue*3 + block[2][4].blue*21 )/(64*256);
down[r+3][c].red = (block[4][0].red*49 + block[3][0].red*7 + block[4][1].red*7 + block[3][1].red )/(64*256);
down[r+3][c].green = (block[4][0].green*49 + block[3][0].green*7 + block[4][1].green*7 + block[3][1].green )/(64*256);
down[r+3][c].blue = (block[4][0].blue*49 + block[3][0].blue*7 + block[4][1].blue*7 + block[3][1].blue )/(64*256);
down[r+3][c+1].red = (block[4][1].red*35 + block[4][2].red*21 + block[3][1].red*5 + block[3][2].red*3 )/(64*256);
down[r+3][c+1].green = (block[4][1].green*35 + block[4][2].green*21 + block[3][1].green*5 + block[3][2].green*3 )/(64*256);
down[r+3][c+1].blue = (block[4][1].blue*35 + block[4][2].blue*21 + block[3][1].blue*5 + block[3][2].blue*3 )/(64*256);
down[r+3][c+2].red = (block[4][3].red*35 + block[4][2].red*21 + block[3][3].red*5 + block[3][2].red*3 )/(64*256);
down[r+3][c+2].green = (block[4][3].green*35 + block[4][2].green*21 + block[3][3].green*5 + block[3][2].green*3 )/(64*256);
down[r+3][c+2].blue = (block[4][3].blue*35 + block[4][2].blue*21 + block[3][3].blue*5 + block[3][2].blue*3 )/(64*256);
down[r+3][c+3].red = (block[4][4].red*49 + block[4][3].red*7 + block[3][4].red*7 + block[3][3].red )/(64*256);
down[r+3][c+3].green = (block[4][4].green*49 + block[4][3].green*7 + block[3][4].green*7 + block[3][3].green )/(64*256);
down[r+3][c+3].blue = (block[4][4].blue*49 + block[4][3].blue*7 + block[3][4].blue*7 + block[3][3].blue )/(64*256);
cc += size_in;
}
rr += size_in;
}
}
private:
}; };
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
......
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