Commit f1b5fc97 authored by Davis King's avatar Davis King

Changed the suppress_non_maximum_edges() routine so that it is more robust

to a wider range of pixel types.
parent 0ae28101
...@@ -12,29 +12,38 @@ namespace dlib ...@@ -12,29 +12,38 @@ namespace dlib
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <
typename T
>
inline char edge_orientation ( inline char edge_orientation (
long x, const T& x_,
long y const T& y_
) )
{ {
// if this is a perfectly horizontal gradient then return right away // if this is a perfectly horizontal gradient then return right away
if (x == 0) if (x_ == 0)
{ {
return '|'; return '|';
} }
else if (y == 0) // if this is a perfectly vertical gradient then return right away else if (y_ == 0) // if this is a perfectly vertical gradient then return right away
{ {
return '-'; return '-';
} }
// Promote x so that when we multiply by 128 later we know overflow won't happen.
typedef typename promote<T>::type type;
type x = x_;
type y = y_;
if (x < 0) if (x < 0)
{ {
x = -x; x = -x;
if (y < 0) if (y < 0)
{ {
y = -y; y = -y;
x <<= 7; x *= 128;
const long temp = x/y; const type temp = x/y;
if (temp > 309) if (temp > 309)
return '-'; return '-';
else if (temp > 53) else if (temp > 53)
...@@ -44,8 +53,8 @@ namespace dlib ...@@ -44,8 +53,8 @@ namespace dlib
} }
else else
{ {
x <<= 7; x *= 128;
const long temp = x/y; const type temp = x/y;
if (temp > 309) if (temp > 309)
return '-'; return '-';
else if (temp > 53) else if (temp > 53)
...@@ -59,9 +68,9 @@ namespace dlib ...@@ -59,9 +68,9 @@ namespace dlib
if (y < 0) if (y < 0)
{ {
y = -y; y = -y;
x <<= 7; x *= 128;
const long temp = x/y; const type temp = x/y;
if (temp > 309) if (temp > 309)
return '-'; return '-';
else if (temp > 53) else if (temp > 53)
...@@ -71,9 +80,9 @@ namespace dlib ...@@ -71,9 +80,9 @@ namespace dlib
} }
else else
{ {
x <<= 7; x *= 128;
const long temp = x/y; const type temp = x/y;
if (temp > 309) if (temp > 309)
return '-'; return '-';
else if (temp > 53) else if (temp > 53)
...@@ -98,12 +107,13 @@ namespace dlib ...@@ -98,12 +107,13 @@ namespace dlib
) )
{ {
COMPILE_TIME_ASSERT(pixel_traits<typename out_image_type::type>::is_unsigned == false); COMPILE_TIME_ASSERT(pixel_traits<typename out_image_type::type>::is_unsigned == false);
DLIB_ASSERT( (((void*)&in_img != (void*)&horz) && ((void*)&in_img != (void*)&vert) && ((void*)&vert != (void*)&horz)), DLIB_ASSERT( !is_same_object(in_img,horz) && !is_same_object(in_img,vert) &&
!is_same_object(horz,vert),
"\tvoid sobel_edge_detector(in_img, horz, vert)" "\tvoid sobel_edge_detector(in_img, horz, vert)"
<< "\n\tYou can't give the same image as more than one argument" << "\n\t You can't give the same image as more than one argument"
<< "\n\t&in_img: " << &in_img << "\n\t is_same_object(in_img,horz): " << is_same_object(in_img,horz)
<< "\n\t&horz: " << &horz << "\n\t is_same_object(in_img,vert): " << is_same_object(in_img,vert)
<< "\n\t&vert: " << &vert << "\n\t is_same_object(horz,vert): " << is_same_object(horz,vert)
); );
...@@ -180,18 +190,16 @@ namespace dlib ...@@ -180,18 +190,16 @@ namespace dlib
<< "\n\tvert.nr(): " << vert.nr() << "\n\tvert.nr(): " << vert.nr()
<< "\n\tvert.nc(): " << vert.nc() << "\n\tvert.nc(): " << vert.nc()
); );
DLIB_ASSERT( ((void*)&out_img != (void*)&horz) && ((void*)&out_img != (void*)&vert), DLIB_ASSERT( !is_same_object(out_img,horz) && !is_same_object(out_img,vert),
"\tvoid suppress_non_maximum_edges(horz, vert, out_img)" "\tvoid suppress_non_maximum_edges(horz, vert, out_img)"
<< "\n\tYou can't give the same image as more than one argument" << "\n\t out_img can't be the same as one of the input images."
<< "\n\t&horz: " << &horz << "\n\t is_same_object(out_img,horz): " << is_same_object(out_img,horz)
<< "\n\t&vert: " << &vert << "\n\t is_same_object(out_img,vert): " << is_same_object(out_img,vert)
<< "\n\t&out_img: " << &out_img
); );
using std::min; using std::min;
using std::abs; using std::abs;
typedef typename out_image_type::type pixel_type;
// if there isn't any input image then don't do anything // if there isn't any input image then don't do anything
if (horz.size() == 0) if (horz.size() == 0)
...@@ -220,10 +228,11 @@ namespace dlib ...@@ -220,10 +228,11 @@ namespace dlib
{ {
for (long c = first_col; c < last_col; ++c) for (long c = first_col; c < last_col; ++c)
{ {
const long y = horz[r][c]; typedef typename in_image_type::type T;
const long x = vert[r][c]; const T y = horz[r][c];
const T x = vert[r][c];
const long val = abs(horz[r][c]) + abs(vert[r][c]); const T val = abs(horz[r][c]) + abs(vert[r][c]);
const char ori = edge_orientation(x,y); const char ori = edge_orientation(x,y);
const unsigned char zero = 0; const unsigned char zero = 0;
......
...@@ -10,9 +10,12 @@ namespace dlib ...@@ -10,9 +10,12 @@ namespace dlib
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <
typename T
>
inline char edge_orientation ( inline char edge_orientation (
long x, const T& x,
long y const T& y
); );
/*! /*!
ensures ensures
...@@ -46,8 +49,9 @@ namespace dlib ...@@ -46,8 +49,9 @@ namespace dlib
- out_image_type == is an implementation of array2d/array2d_kernel_abstract.h - out_image_type == is an implementation of array2d/array2d_kernel_abstract.h
- pixel_traits<typename in_image_type::type> must be defined - pixel_traits<typename in_image_type::type> must be defined
- pixel_traits<typename out_image_type::type>::is_unsigned == false - pixel_traits<typename out_image_type::type>::is_unsigned == false
- (&in_img != &horz) && (&in_img != &vert) && (&vert != &horz) - is_same_object(in_img,horz) == false
(i.e. all three images are different image objects) - is_same_object(in_img,vert) == false
- is_same_object(horz,vert) == false
ensures ensures
- Applies the sobel edge detector to the given input image and stores the resulting - Applies the sobel edge detector to the given input image and stores the resulting
edge detections in the horz and vert images edge detections in the horz and vert images
...@@ -80,8 +84,9 @@ namespace dlib ...@@ -80,8 +84,9 @@ namespace dlib
- pixel_traits<typename out_image_type::type> must be defined - pixel_traits<typename out_image_type::type> must be defined
- horz.nr() == vert.nr() - horz.nr() == vert.nr()
- horz.nc() == vert.nc() - horz.nc() == vert.nc()
- (&out_img != &horz) && (&out_img != &vert) - is_same_object(out_img, horz) == false
- in_image_type::type == a signed integral type - is_same_object(out_img, vert) == false
- in_image_type::type == A signed scalar type (e.g. int, double, etc.)
ensures ensures
- #out_img.nr() = horz.nr() - #out_img.nr() = horz.nr()
- #out_img.nc() = horz.nc() - #out_img.nc() = horz.nc()
......
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