diff --git a/dlib/image_transforms/spatial_filtering.h b/dlib/image_transforms/spatial_filtering.h index 5010bd531..c908c17f3 100644 --- a/dlib/image_transforms/spatial_filtering.h +++ b/dlib/image_transforms/spatial_filtering.h @@ -809,9 +809,7 @@ namespace dlib const typename image_type1::type& thresh ) { - DLIB_ASSERT((width%2)==1 && - (height%2)==1 && - width > 0 && + DLIB_ASSERT( width > 0 && height > 0 && out.nr() == img.nr() && out.nc() == img.nc() && @@ -832,21 +830,21 @@ namespace dlib dlib::impl::fast_deque > Q(std::max(width,height)); - const long last_col = std::max(img.nc(), (width/2)); - const long last_row = std::max(img.nr(), (height/2)); + const long last_col = std::max(img.nc(), ((width-1)/2)); + const long last_row = std::max(img.nr(), ((height-1)/2)); // run max filter along rows of img for (long r = 0; r < img.nr(); ++r) { Q.clear(); - for (long c = 0; c < width/2 && c < img.nc(); ++c) + for (long c = 0; c < (width-1)/2 && c < img.nc(); ++c) { while (!Q.empty() && img[r][c] >= Q.back().second) Q.pop_back(); Q.push_back(make_pair(c,img[r][c])); } - for (long c = width/2; c < img.nc(); ++c) + for (long c = (width-1)/2; c < img.nc(); ++c) { while (!Q.empty() && img[r][c] >= Q.back().second) Q.pop_back(); @@ -854,15 +852,15 @@ namespace dlib Q.pop_front(); Q.push_back(make_pair(c,img[r][c])); - img[r][c-(width/2)] = Q.front().second; + img[r][c-((width-1)/2)] = Q.front().second; } - for (long c = last_col; c < img.nc() + (width/2); ++c) + for (long c = last_col; c < img.nc() + ((width-1)/2); ++c) { while (!Q.empty() && Q.front().first <= c-width) Q.pop_front(); - img[r][c-(width/2)] = Q.front().second; + img[r][c-((width-1)/2)] = Q.front().second; } } @@ -870,14 +868,14 @@ namespace dlib for (long cc = 0; cc < img.nc(); ++cc) { Q.clear(); - for (long rr = 0; rr < height/2 && rr < img.nr(); ++rr) + for (long rr = 0; rr < (height-1)/2 && rr < img.nr(); ++rr) { while (!Q.empty() && img[rr][cc] >= Q.back().second) Q.pop_back(); Q.push_back(make_pair(rr,img[rr][cc])); } - for (long rr = height/2; rr < img.nr(); ++rr) + for (long rr = (height-1)/2; rr < img.nr(); ++rr) { while (!Q.empty() && img[rr][cc] >= Q.back().second) Q.pop_back(); @@ -885,15 +883,15 @@ namespace dlib Q.pop_front(); Q.push_back(make_pair(rr,img[rr][cc])); - out[rr-(height/2)][cc] += std::max(Q.front().second, thresh); + out[rr-((height-1)/2)][cc] += std::max(Q.front().second, thresh); } - for (long rr = last_row; rr < img.nr() + (height/2); ++rr) + for (long rr = last_row; rr < img.nr() + ((height-1)/2); ++rr) { while (!Q.empty() && Q.front().first <= rr-height) Q.pop_front(); - out[rr-(height/2)][cc] += std::max(Q.front().second, thresh); + out[rr-((height-1)/2)][cc] += std::max(Q.front().second, thresh); } } } diff --git a/dlib/image_transforms/spatial_filtering_abstract.h b/dlib/image_transforms/spatial_filtering_abstract.h index 6cbdab5c4..e305532c4 100644 --- a/dlib/image_transforms/spatial_filtering_abstract.h +++ b/dlib/image_transforms/spatial_filtering_abstract.h @@ -360,8 +360,6 @@ namespace dlib - image_type2 == an implementation of array2d/array2d_kernel_abstract.h and it must contain a scalar type - is_same_object(img,out) == false - - (width%2)==1 && (height%2)==1 - (i.e. width and height must be odd) - width > 0 && height > 0 ensures - for all valid r and c: diff --git a/dlib/test/scan_image.cpp b/dlib/test/scan_image.cpp index 6ecb46c2e..0cbfee208 100644 --- a/dlib/test/scan_image.cpp +++ b/dlib/test/scan_image.cpp @@ -449,7 +449,8 @@ namespace void naive_max_filter ( const image_type1& img, image_type2& out, - const rectangle& rect, + const long width, + const long height, typename image_type1::type thresh ) { @@ -460,11 +461,8 @@ namespace { for (long c = 0; c < img.nc(); ++c) { - const rectangle win = translate_rect(rect,point(c,r)).intersect(area); - if (!win.is_empty()) - out[r][c] += std::max(dlib::max(subm(array_to_matrix(img),win)), thresh); - else - out[r][c] += thresh; + const rectangle win = centered_rect(point(c,r),width,height).intersect(area); + out[r][c] += std::max(dlib::max(subm(array_to_matrix(img),win)), thresh); } } } @@ -491,7 +489,7 @@ namespace const int thresh = rnd.get_random_32bit_number(); - naive_max_filter(img, out2, rect, thresh); + naive_max_filter(img, out2, rect.width(), rect.height(), thresh); max_filter(img, out, rect.width(), rect.height(), thresh); DLIB_TEST_MSG(array_to_matrix(out) == array_to_matrix(out2), @@ -517,11 +515,19 @@ namespace test_max_filter(2,2,1,1,rnd); test_max_filter(3,3,1,1,rnd); test_max_filter(3,3,3,3,rnd); + test_max_filter(3,3,2,2,rnd); test_max_filter(3,3,3,5,rnd); + test_max_filter(3,3,6,8,rnd); test_max_filter(20,20,901,901,rnd); test_max_filter(5,5,1,5,rnd); test_max_filter(50,50,9,9,rnd); test_max_filter(50,50,9,9,rnd); + test_max_filter(50,50,10,10,rnd); + test_max_filter(50,50,11,10,rnd); + test_max_filter(50,50,10,11,rnd); + test_max_filter(50,50,10,21,rnd); + test_max_filter(50,50,20,10,rnd); + test_max_filter(50,50,20,10,rnd); test_max_filter(50,50,9,9,rnd); test_max_filter(20,20,1,901,rnd); test_max_filter(20,20,3,901,rnd); @@ -533,8 +539,8 @@ namespace print_spinner(); test_max_filter((int)rnd.get_random_8bit_number()%100+1, (int)rnd.get_random_8bit_number()%100+1, - (int)rnd.get_random_8bit_number()*2+1, - (int)rnd.get_random_8bit_number()*2+1, + (int)rnd.get_random_8bit_number()%150+1, + (int)rnd.get_random_8bit_number()%150+1, rnd); } }