Commit a081d4de authored by Davis King's avatar Davis King

- Renamed spatially_filter_image() for the separable case to spatially_filter_image_separable()

 - Changed the behavior of spatially_filter_image().  Now it won't truncate signed pixel values
   to 0 if they go negative.
parent 4d8e96ef
......@@ -19,20 +19,21 @@ namespace dlib
template <
typename in_image_type,
typename out_image_type,
typename EXP
typename EXP,
typename T
>
void spatially_filter_image (
const in_image_type& in_img,
out_image_type& out_img,
const matrix_exp<EXP>& filter,
unsigned long scale = 1,
T scale,
bool use_abs = false
)
{
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 );
DLIB_ASSERT(scale > 0 &&
DLIB_ASSERT(scale != 0 &&
filter.nr()%2 == 1 &&
filter.nc()%2 == 1,
"\tvoid spatially_filter_image()"
......@@ -85,17 +86,9 @@ namespace dlib
temp /= scale;
// Catch any underflow or apply abs as appropriate
if (temp < 0)
if (use_abs && temp < 0)
{
if (use_abs)
{
temp = -temp;
}
else
{
temp = 0;
}
temp = -temp;
}
// save this pixel to the output image
......@@ -105,32 +98,47 @@ namespace dlib
}
}
template <
typename in_image_type,
typename out_image_type,
typename EXP
>
void spatially_filter_image (
const in_image_type& in_img,
out_image_type& out_img,
const matrix_exp<EXP>& filter
)
{
spatially_filter_image(in_img,out_img,filter,1);
}
// ----------------------------------------------------------------------------------------
template <
typename in_image_type,
typename out_image_type,
typename EXP1,
typename EXP2
typename EXP2,
typename T
>
void spatially_filter_image (
void spatially_filter_image_separable (
const in_image_type& in_img,
out_image_type& out_img,
const matrix_exp<EXP1>& row_filter,
const matrix_exp<EXP2>& col_filter,
unsigned long scale = 1,
T scale,
bool use_abs = false
)
{
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 );
DLIB_ASSERT(scale > 0 &&
DLIB_ASSERT(scale != 0 &&
row_filter.size()%2 == 1 &&
col_filter.size()%2 == 1 &&
is_vector(row_filter) &&
is_vector(col_filter),
"\tvoid spatially_filter_image()"
"\tvoid spatially_filter_image_separable()"
<< "\n\t Invalid inputs were given to this function."
<< "\n\t scale: "<< scale
<< "\n\t row_filter.size(): "<< row_filter.size()
......@@ -139,7 +147,7 @@ namespace dlib
<< "\n\t is_vector(col_filter): "<< is_vector(col_filter)
);
DLIB_ASSERT(is_same_object(in_img, out_img) == false,
"\tvoid spatially_filter_image()"
"\tvoid spatially_filter_image_separable()"
<< "\n\tYou must give two different image objects"
);
......@@ -199,17 +207,9 @@ namespace dlib
temp /= scale;
// Catch any underflow or apply abs as appropriate
if (temp < 0)
if (use_abs && temp < 0)
{
if (use_abs)
{
temp = -temp;
}
else
{
temp = 0;
}
temp = -temp;
}
// save this pixel to the output image
......@@ -219,6 +219,22 @@ namespace dlib
}
}
template <
typename in_image_type,
typename out_image_type,
typename EXP1,
typename EXP2
>
void spatially_filter_image_separable (
const in_image_type& in_img,
out_image_type& out_img,
const matrix_exp<EXP1>& row_filter,
const matrix_exp<EXP2>& col_filter
)
{
spatially_filter_image_separable(in_img,out_img,row_filter,col_filter,1);
}
// ----------------------------------------------------------------------------------------
template <
......
......@@ -14,13 +14,14 @@ namespace dlib
template <
typename in_image_type,
typename out_image_type,
typename EXP
typename EXP,
typename T
>
void spatially_filter_image (
const in_image_type& in_img,
out_image_type& out_img,
const matrix_exp<EXP>& filter,
unsigned long scale = 1,
T scale = 1,
bool use_abs = false
);
/*!
......@@ -30,21 +31,20 @@ namespace dlib
- pixel_traits<typename in_image_type::type>::has_alpha == false
- pixel_traits<typename out_image_type::type>::has_alpha == false
- is_same_object(in_img, out_img) == false
- scale > 0
- T must be some scalar type
- scale != 0
- filter.nr() % 2 == 1 (i.e. must be odd)
- filter.nc() % 2 == 1 (i.e. must be odd)
ensures
- Applies the given spatial filter to in_img and stores the result in out_img. Also
divides each resulting pixel by scale.
- pixel values after filtering that are > pixel_traits<out_image_type>::max() are
set to pixel_traits<out_image_type>::max()
- Pixel values are stored into out_img using the assign_pixel() function and therefore
any applicable color space conversion or value saturation is performed.
- if (pixel_traits<typename in_image_type::type>::grayscale == false) then
- the pixel values are converted to the HSI color space and the filtering
is done on the intensity channel only.
- if (use_abs == true) then
- pixel values after filtering that are < 0 are converted to their absolute values
- else
- pixel values after filtering that are < 0 are assigned the value of 0
- pixel values after filtering that are < 0 are converted to their absolute values.
- Pixels close enough to the edge of in_img to not have the filter still fit
inside the image are set to zero.
- #out_img.nc() == in_img.nc()
......@@ -57,14 +57,15 @@ namespace dlib
typename in_image_type,
typename out_image_type,
typename EXP1,
typename EXP2
typename EXP2,
typename T
>
void spatially_filter_image (
void spatially_filter_image_separable (
const in_image_type& in_img,
out_image_type& out_img,
const matrix_exp<EXP1>& row_filter,
const matrix_exp<EXP2>& col_filter,
unsigned long scale = 1,
T scale = 1,
bool use_abs = false
);
/*!
......@@ -74,7 +75,8 @@ namespace dlib
- pixel_traits<typename in_image_type::type>::has_alpha == false
- pixel_traits<typename out_image_type::type>::has_alpha == false
- is_same_object(in_img, out_img) == false
- scale > 0
- T must be some scalar type
- scale != 0
- is_vector(row_filter) == true
- is_vector(col_filter) == true
- row_filter.size() % 2 == 1 (i.e. must be odd)
......@@ -85,15 +87,13 @@ namespace dlib
effect as calling the regular spatially_filter_image() routine with a filter,
FILT, defined as follows:
- FILT(r,c) == col_filter(r)*row_filter(c)
- pixel values after filtering that are > pixel_traits<out_image_type>::max() are
set to pixel_traits<out_image_type>::max()
- Pixel values are stored into out_img using the assign_pixel() function and therefore
any applicable color space conversion or value saturation is performed.
- if (pixel_traits<typename in_image_type::type>::grayscale == false) then
- the pixel values are converted to the HSI color space and the filtering
is done on the intensity channel only.
- if (use_abs == true) then
- pixel values after filtering that are < 0 are converted to their absolute values
- else
- pixel values after filtering that are < 0 are assigned the value of 0
- Pixels close enough to the edge of in_img to not have the filter still fit
inside the image are set to zero.
- #out_img.nc() == in_img.nc()
......
......@@ -808,7 +808,7 @@ namespace
row_filter = 1,1,1,1,1;
col_filter = 1,1,1;
spatially_filter_image(img, img3, row_filter, col_filter);
spatially_filter_image_separable(img, img3, row_filter, col_filter);
DLIB_TEST(array_to_matrix(img2) == array_to_matrix(img3));
......@@ -840,9 +840,117 @@ namespace
assign_all_pixels(img3,3);
// Just make sure both filtering methods give the same results.
spatially_filter_image(img, img2, filter, scale, use_abs);
spatially_filter_image(img, img3, row_filter, col_filter, scale, use_abs);
spatially_filter_image_separable(img, img3, row_filter, col_filter, scale, use_abs);
DLIB_TEST(array_to_matrix(img2) == array_to_matrix(img3));
}
{
array2d<int> img, img2;
img.set_size(3,4);
matrix<int> filter(3,3);
filter = 1;
assign_all_pixels(img,-1);
spatially_filter_image(img,img2,filter);
DLIB_TEST(img2[0][0] == 0);
DLIB_TEST(img2[0][1] == 0);
DLIB_TEST(img2[0][2] == 0);
DLIB_TEST(img2[0][3] == 0);
DLIB_TEST(img2[1][0] == 0);
DLIB_TEST(img2[1][1] == -9);
DLIB_TEST(img2[1][2] == -9);
DLIB_TEST(img2[1][3] == 0);
DLIB_TEST(img2[2][0] == 0);
DLIB_TEST(img2[2][1] == 0);
DLIB_TEST(img2[2][2] == 0);
DLIB_TEST(img2[2][3] == 0);
assign_all_pixels(img,-1);
spatially_filter_image(img,img2,filter,2,true);
DLIB_TEST(img2[0][0] == 0);
DLIB_TEST(img2[0][1] == 0);
DLIB_TEST(img2[0][2] == 0);
DLIB_TEST(img2[0][3] == 0);
DLIB_TEST(img2[1][0] == 0);
DLIB_TEST(img2[1][1] == 4);
DLIB_TEST(img2[1][2] == 4);
DLIB_TEST(img2[1][3] == 0);
DLIB_TEST(img2[2][0] == 0);
DLIB_TEST(img2[2][1] == 0);
DLIB_TEST(img2[2][2] == 0);
DLIB_TEST(img2[2][3] == 0);
matrix<int> rowf(3,1), colf(3,1);
rowf = 1;
colf = 1;
assign_all_pixels(img,-1);
spatially_filter_image_separable(img,img2,rowf,colf);
DLIB_TEST(img2[0][0] == 0);
DLIB_TEST(img2[0][1] == 0);
DLIB_TEST(img2[0][2] == 0);
DLIB_TEST(img2[0][3] == 0);
DLIB_TEST(img2[1][0] == 0);
DLIB_TEST(img2[1][1] == -9);
DLIB_TEST(img2[1][2] == -9);
DLIB_TEST(img2[1][3] == 0);
DLIB_TEST(img2[2][0] == 0);
DLIB_TEST(img2[2][1] == 0);
DLIB_TEST(img2[2][2] == 0);
DLIB_TEST(img2[2][3] == 0);
spatially_filter_image_separable(img,img2,rowf,colf,1,true);
DLIB_TEST(img2[0][0] == 0);
DLIB_TEST(img2[0][1] == 0);
DLIB_TEST(img2[0][2] == 0);
DLIB_TEST(img2[0][3] == 0);
DLIB_TEST(img2[1][0] == 0);
DLIB_TEST(img2[1][1] == 9);
DLIB_TEST(img2[1][2] == 9);
DLIB_TEST(img2[1][3] == 0);
DLIB_TEST(img2[2][0] == 0);
DLIB_TEST(img2[2][1] == 0);
DLIB_TEST(img2[2][2] == 0);
DLIB_TEST(img2[2][3] == 0);
}
{
array2d<double> img, img2;
img.set_size(3,4);
matrix<double> filter(3,3);
filter = 1;
assign_all_pixels(img,-1);
spatially_filter_image(img,img2,filter,2);
DLIB_TEST(img2[0][0] == 0);
DLIB_TEST(img2[0][1] == 0);
DLIB_TEST(img2[0][2] == 0);
DLIB_TEST(img2[0][3] == 0);
DLIB_TEST(img2[1][0] == 0);
DLIB_TEST((img2[1][1] - -4.5) < 1e-14);
DLIB_TEST((img2[1][2] - -4.5) < 1e-14);
DLIB_TEST(img2[1][3] == 0);
DLIB_TEST(img2[2][0] == 0);
DLIB_TEST(img2[2][1] == 0);
DLIB_TEST(img2[2][2] == 0);
DLIB_TEST(img2[2][3] == 0);
}
}
void test_zero_border_pixels(
......
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