mirror of
https://github.com/davisking/dlib.git
synced 2024-11-01 10:14:53 +08:00
Added a 4:3 pyramid down tool.
This commit is contained in:
parent
b3682d98bb
commit
59f6905284
@ -546,6 +546,259 @@ namespace dlib
|
||||
private:
|
||||
|
||||
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class pyramid_down_4_3 : noncopyable
|
||||
{
|
||||
public:
|
||||
|
||||
template <typename T>
|
||||
vector<double,2> point_down (
|
||||
const vector<T,2>& p
|
||||
) const
|
||||
{
|
||||
const double ratio = 3.0/4.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 = 4.0/3.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_4_3::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 = 4;
|
||||
const long size_out = 3;
|
||||
|
||||
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]*25 + block[1][0]*5 + block[0][1]*5 + block[1][1])/(36*256));
|
||||
assign_pixel(down[r][c+1] , (block[0][1]*5 + block[0][2]*5 + block[1][1] + block[1][2])/(12*256));
|
||||
assign_pixel(down[r][c+2] , (block[0][3]*25 + block[1][3]*5 + block[0][2]*5 + block[1][2])/(36*256));
|
||||
|
||||
assign_pixel(down[r+1][c] , (block[1][0]*5 + block[2][0]*5 + block[1][1] + block[2][1])/(12*256));
|
||||
assign_pixel(down[r+1][c+1] , (block[1][1] + block[1][2] + block[2][1] + block[2][2])/(4*256));
|
||||
assign_pixel(down[r+1][c+2] , (block[1][3]*5 + block[2][3]*5 + block[1][2] + block[2][2])/(12*256));
|
||||
|
||||
assign_pixel(down[r+2][c] , (block[3][0]*25 + block[2][0]*5 + block[3][1]*5 + block[2][1])/(36*256));
|
||||
assign_pixel(down[r+2][c+1] , (block[3][1]*5 + block[3][2]*5 + block[2][1] + block[2][2])/(12*256));
|
||||
assign_pixel(down[r+2][c+2] , (block[3][3]*25 + block[2][3]*5 + block[3][2]*5 + block[2][2])/(36*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_4_3::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 = 4;
|
||||
const long size_out = 3;
|
||||
|
||||
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*25 + block[1][0].red*5 + block[0][1].red*5 + block[1][1].red )/(36*256);
|
||||
down[r][c].green = (block[0][0].green*25 + block[1][0].green*5 + block[0][1].green*5 + block[1][1].green)/(36*256);
|
||||
down[r][c].blue = (block[0][0].blue*25 + block[1][0].blue*5 + block[0][1].blue*5 + block[1][1].blue )/(36*256);
|
||||
|
||||
down[r][c+1].red = (block[0][1].red*5 + block[0][2].red*5 + block[1][1].red + block[1][2].red )/(12*256);
|
||||
down[r][c+1].green = (block[0][1].green*5 + block[0][2].green*5 + block[1][1].green + block[1][2].green)/(12*256);
|
||||
down[r][c+1].blue = (block[0][1].blue*5 + block[0][2].blue*5 + block[1][1].blue + block[1][2].blue )/(12*256);
|
||||
|
||||
down[r][c+2].red = (block[0][3].red*25 + block[1][3].red*5 + block[0][2].red*5 + block[1][2].red )/(36*256);
|
||||
down[r][c+2].green = (block[0][3].green*25 + block[1][3].green*5 + block[0][2].green*5 + block[1][2].green)/(36*256);
|
||||
down[r][c+2].blue = (block[0][3].blue*25 + block[1][3].blue*5 + block[0][2].blue*5 + block[1][2].blue )/(36*256);
|
||||
|
||||
down[r+1][c].red = (block[1][0].red*5 + block[2][0].red*5 + block[1][1].red + block[2][1].red )/(12*256);
|
||||
down[r+1][c].green = (block[1][0].green*5 + block[2][0].green*5 + block[1][1].green + block[2][1].green)/(12*256);
|
||||
down[r+1][c].blue = (block[1][0].blue*5 + block[2][0].blue*5 + block[1][1].blue + block[2][1].blue )/(12*256);
|
||||
|
||||
down[r+1][c+1].red = (block[1][1].red + block[1][2].red + block[2][1].red + block[2][2].red )/(4*256);
|
||||
down[r+1][c+1].green = (block[1][1].green + block[1][2].green + block[2][1].green + block[2][2].green)/(4*256);
|
||||
down[r+1][c+1].blue = (block[1][1].blue + block[1][2].blue + block[2][1].blue + block[2][2].blue )/(4*256);
|
||||
|
||||
down[r+1][c+2].red = (block[1][3].red*5 + block[2][3].red*5 + block[1][2].red + block[2][2].red )/(12*256);
|
||||
down[r+1][c+2].green = (block[1][3].green*5 + block[2][3].green*5 + block[1][2].green + block[2][2].green)/(12*256);
|
||||
down[r+1][c+2].blue = (block[1][3].blue*5 + block[2][3].blue*5 + block[1][2].blue + block[2][2].blue )/(12*256);
|
||||
|
||||
down[r+2][c].red = (block[3][0].red*25 + block[2][0].red*5 + block[3][1].red*5 + block[2][1].red )/(36*256);
|
||||
down[r+2][c].green = (block[3][0].green*25 + block[2][0].green*5 + block[3][1].green*5 + block[2][1].green)/(36*256);
|
||||
down[r+2][c].blue = (block[3][0].blue*25 + block[2][0].blue*5 + block[3][1].blue*5 + block[2][1].blue )/(36*256);
|
||||
|
||||
down[r+2][c+1].red = (block[3][1].red*5 + block[3][2].red*5 + block[2][1].red + block[2][2].red )/(12*256);
|
||||
down[r+2][c+1].green = (block[3][1].green*5 + block[3][2].green*5 + block[2][1].green + block[2][2].green)/(12*256);
|
||||
down[r+2][c+1].blue = (block[3][1].blue*5 + block[3][2].blue*5 + block[2][1].blue + block[2][2].blue )/(12*256);
|
||||
|
||||
down[r+2][c+2].red = (block[3][3].red*25 + block[2][3].red*5 + block[3][2].red*5 + block[2][2].red )/(36*256);
|
||||
down[r+2][c+2].green = (block[3][3].green*25 + block[2][3].green*5 + block[3][2].green*5 + block[2][2].green)/(36*256);
|
||||
down[r+2][c+2].blue = (block[3][3].blue*25 + block[2][3].blue*5 + block[3][2].blue*5 + block[2][2].blue )/(36*256);
|
||||
|
||||
cc += size_in;
|
||||
}
|
||||
rr += size_in;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user