Commit 30963435 authored by Davis King's avatar Davis King

Made the spatial filtering functions always center their filters over the

output pixel exactly the same way as defined by centered_rect().
parent 4dd693e4
......@@ -658,8 +658,6 @@ namespace dlib
unsigned long width, height;
compute_fhog_window_size(width,height);
const point anchor((width+1)%2,
(height+1)%2);
array2d<float> saliency_image;
pyramid_type pyr;
......@@ -677,7 +675,7 @@ namespace dlib
// if we found a detection
if (saliency_image[r][c] >= thresh)
{
rectangle rect = fhog_to_image(centered_rect(point(c,r)+anchor,width-2*padding,height-2*padding), cell_size, height,width);
rectangle rect = fhog_to_image(centered_rect(point(c,r),width-2*padding,height-2*padding), cell_size, height,width);
rect = pyr.rect_up(rect, l);
dets.push_back(std::make_pair(saliency_image[r][c], rect));
}
......
......@@ -64,10 +64,10 @@ namespace dlib
// figure out the range that we should apply the filter to
const long first_row = (filter.nr()-1)/2;
const long first_col = (filter.nc()-1)/2;
const long last_row = in_img.nr() - (filter.nr()/2);
const long last_col = in_img.nc() - (filter.nc()/2);
const long first_row = filter.nr()/2;
const long first_col = filter.nc()/2;
const long last_row = in_img.nr() - ((filter.nr()-1)/2);
const long last_col = in_img.nc() - ((filter.nc()-1)/2);
const rectangle non_border = rectangle(first_col, first_row, last_col-1, last_row-1);
if (!add_to)
......@@ -153,10 +153,10 @@ namespace dlib
// figure out the range that we should apply the filter to
const long first_row = (filter.nr()-1)/2;
const long first_col = (filter.nc()-1)/2;
const long last_row = in_img.nr() - (filter.nr()/2);
const long last_col = in_img.nc() - (filter.nc()/2);
const long first_row = filter.nr()/2;
const long first_col = filter.nc()/2;
const long last_row = in_img.nr() - ((filter.nr()-1)/2);
const long last_col = in_img.nc() - ((filter.nc()-1)/2);
const rectangle non_border = rectangle(first_col, first_row, last_col-1, last_row-1);
if (!add_to)
......@@ -347,10 +347,10 @@ namespace dlib
// figure out the range that we should apply the filter to
const long first_row = (filter.nr()-1)/2;
const long first_col = (filter.nc()-1)/2;
const long last_row = in_img.nr() - (filter.nr()/2);
const long last_col = in_img.nc() - (filter.nc()/2);
const long first_row = filter.nr()/2;
const long first_col = filter.nc()/2;
const long last_row = in_img.nr() - ((filter.nr()-1)/2);
const long last_col = in_img.nc() - ((filter.nc()-1)/2);
const rectangle non_border = rectangle(first_col, first_row, last_col-1, last_row-1);
zero_border_pixels(out_img, non_border);
......@@ -458,10 +458,10 @@ namespace dlib
// figure out the range that we should apply the filter to
const long first_row = (col_filter.size()-1)/2;
const long first_col = (row_filter.size()-1)/2;
const long last_row = in_img.nr() - (col_filter.size()/2);
const long last_col = in_img.nc() - (row_filter.size()/2);
const long first_row = col_filter.size()/2;
const long first_col = row_filter.size()/2;
const long last_row = in_img.nr() - ((col_filter.size()-1)/2);
const long last_col = in_img.nc() - ((row_filter.size()-1)/2);
const rectangle non_border = rectangle(first_col, first_row, last_col-1, last_row-1);
if (!add_to)
......@@ -593,10 +593,10 @@ namespace dlib
out_img.set_size(in_img.nr(),in_img.nc());
// figure out the range that we should apply the filter to
const long first_row = (col_filter.size()-1)/2;
const long first_col = (row_filter.size()-1)/2;
const long last_row = in_img.nr() - (col_filter.size()/2);
const long last_col = in_img.nc() - (row_filter.size()/2);
const long first_row = col_filter.size()/2;
const long first_col = row_filter.size()/2;
const long last_row = in_img.nr() - ((col_filter.size()-1)/2);
const long last_col = in_img.nc() - ((row_filter.size()-1)/2);
const rectangle non_border = rectangle(first_col, first_row, last_col-1, last_row-1);
if (!add_to)
......@@ -814,10 +814,10 @@ namespace dlib
// figure out the range that we should apply the filter to
const long first_row = (col_filter.size()-1)/2;
const long first_col = (row_filter.size()-1)/2;
const long last_row = in_img.nr() - (col_filter.size()/2);
const long last_col = in_img.nc() - (row_filter.size()/2);
const long first_row = col_filter.size()/2;
const long first_col = row_filter.size()/2;
const long last_row = in_img.nr() - ((col_filter.size()-1)/2);
const long last_col = in_img.nc() - ((row_filter.size()-1)/2);
const rectangle non_border = rectangle(first_col, first_row, last_col-1, last_row-1);
zero_border_pixels(out_img, non_border);
......
......@@ -53,7 +53,10 @@ namespace dlib
- pixel values after filtering that are < 0 are converted to their absolute values.
- The filter is applied such that it's centered over the pixel it writes its
output into. For centering purposes, we consider the center element of the
filter to be filter((filter.nr()-1)/2,(filter.nc()-1)/2).
filter to be filter(filter.nr()/2,filter.nc()/2). This means that the filter
that writes its output to a pixel at location point(c,r) and is W by H (width
by height) pixels in size operates on exactly the pixels in the rectangle
centered_rect(point(c,r),W,H) within in_img.
- Pixels close enough to the edge of in_img to not have the filter still fit
inside the image are always set to zero.
- #out_img.nc() == in_img.nc()
......@@ -117,7 +120,10 @@ namespace dlib
- pixel values after filtering that are < 0 are converted to their absolute values
- The filter is applied such that it's centered over the pixel it writes its
output into. For centering purposes, we consider the center element of the
filter to be FILT((col_filter.size()-1)/2,(row_filter.size()-1)/2).
filter to be FILT(col_filter.size()/2,row_filter.size()/2). This means that
the filter that writes its output to a pixel at location point(c,r) and is W
by H (width by height) pixels in size operates on exactly the pixels in the
rectangle centered_rect(point(c,r),W,H) within in_img.
- Pixels close enough to the edge of in_img to not have the filter still fit
inside the image are always set to zero.
- #out_img.nc() == in_img.nc()
......
......@@ -1091,47 +1091,6 @@ namespace
}
}
void test_small_filter()
{
array2d<int> img(3,3), out;
assign_all_pixels(img, 1);
matrix<int> filt(2,2);
filt = 1;
spatially_filter_image(img, out, filt);
DLIB_TEST(out[0][0] == 4);
DLIB_TEST(out[0][1] == 4);
DLIB_TEST(out[0][2] == 0);
DLIB_TEST(out[1][0] == 4);
DLIB_TEST(out[1][1] == 4);
DLIB_TEST(out[1][2] == 0);
DLIB_TEST(out[2][0] == 0);
DLIB_TEST(out[2][1] == 0);
DLIB_TEST(out[2][2] == 0);
matrix<int> rfilt(2,1), cfilt(2,1);
rfilt = 1;
cfilt = 1;
assign_all_pixels(out, 9);
spatially_filter_image_separable(img, out, rfilt, cfilt);
DLIB_TEST(out[0][0] == 4);
DLIB_TEST(out[0][1] == 4);
DLIB_TEST(out[0][2] == 0);
DLIB_TEST(out[1][0] == 4);
DLIB_TEST(out[1][1] == 4);
DLIB_TEST(out[1][2] == 0);
DLIB_TEST(out[2][0] == 0);
DLIB_TEST(out[2][1] == 0);
DLIB_TEST(out[2][2] == 0);
}
void test_zero_border_pixels(
)
......@@ -1614,6 +1573,104 @@ namespace
DLIB_TEST(mat(img) == mat(img3));
}
// ----------------------------------------------------------------------------------------
template <typename T>
void test_filtering_center (
dlib::rand& rnd
)
{
array2d<T> img(rnd.get_random_32bit_number()%100+1,
rnd.get_random_32bit_number()%100+1);
matrix<T> filt(rnd.get_random_32bit_number()%10+1,
rnd.get_random_32bit_number()%10+1);
for (long r = 0; r < img.nr(); ++r)
{
for (long c = 0; c < img.nc(); ++c)
{
img[r][c] = rnd.get_random_32bit_number()%100;
}
}
for (long r = 0; r < filt.nr(); ++r)
{
for (long c = 0; c < filt.nc(); ++c)
{
filt(r,c) = rnd.get_random_32bit_number()%100;
}
}
array2d<T> out;
const rectangle area = spatially_filter_image(img, out, filt);
for (long r = 0; r < out.nr(); ++r)
{
for (long c = 0; c < out.nc(); ++c)
{
const rectangle rect = centered_rect(point(c,r), filt.nc(), filt.nr());
if (get_rect(out).contains(rect))
{
T val = sum(pointwise_multiply(filt, subm(mat(img),rect)));
DLIB_CASSERT(val == out[r][c],"err: " << val-out[r][c]);
DLIB_CASSERT(area.contains(point(c,r)),"");
}
else
{
DLIB_CASSERT(!area.contains(point(c,r)),"");
}
}
}
}
template <typename T>
void test_separable_filtering_center (
dlib::rand& rnd
)
{
array2d<T> img(rnd.get_random_32bit_number()%100+1,
rnd.get_random_32bit_number()%100+1);
matrix<T,1,0> row_filt(rnd.get_random_32bit_number()%10+1);
matrix<T,0,1> col_filt(rnd.get_random_32bit_number()%10+1);
for (long r = 0; r < img.nr(); ++r)
{
for (long c = 0; c < img.nc(); ++c)
{
img[r][c] = rnd.get_random_32bit_number()%10;
}
}
for (long r = 0; r < row_filt.size(); ++r)
{
row_filt(r) = rnd.get_random_32bit_number()%10;
}
for (long r = 0; r < col_filt.size(); ++r)
{
col_filt(r) = rnd.get_random_32bit_number()%10;
}
array2d<T> out;
const rectangle area = spatially_filter_image_separable(img, out, row_filt, col_filt);
for (long r = 0; r < out.nr(); ++r)
{
for (long c = 0; c < out.nc(); ++c)
{
const rectangle rect = centered_rect(point(c,r), row_filt.size(), col_filt.size());
if (get_rect(out).contains(rect))
{
T val = sum(pointwise_multiply(col_filt*row_filt, subm(mat(img),rect)));
DLIB_CASSERT(val == out[r][c],"err: " << val-out[r][c]);
DLIB_CASSERT(area.contains(point(c,r)),"");
}
else
{
DLIB_CASSERT(!area.contains(point(c,r)),"");
}
}
}
}
// ----------------------------------------------------------------------------------------
class image_tester : public tester
......@@ -1628,7 +1685,6 @@ namespace
void perform_test (
)
{
test_small_filter();
image_test();
test_integral_image<long, unsigned char>();
test_integral_image<double, int>();
......@@ -1669,15 +1725,22 @@ namespace
dlib::rand rnd;
for (int i = 0; i < 10; ++i)
{
// the spatial filtering stuff is the same as xcorr_same when the filter
// sizes are odd.
test_filtering2(3,3,rnd);
test_filtering2(3,4,rnd);
test_filtering2(4,3,rnd);
test_filtering2(4,4,rnd);
test_filtering2(4,7,rnd);
test_filtering2(5,5,rnd);
test_filtering2(7,7,rnd);
test_filtering2(7,5,rnd);
}
for (int i = 0; i < 100; ++i)
test_filtering_center<float>(rnd);
for (int i = 0; i < 100; ++i)
test_filtering_center<int>(rnd);
for (int i = 0; i < 100; ++i)
test_separable_filtering_center<int>(rnd);
for (int i = 0; i < 100; ++i)
test_separable_filtering_center<float>(rnd);
}
} a;
......
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