1 #ifndef CVD_INC_DISTANCE_TRANSFORM_HPP 2 #define CVD_INC_DISTANCE_TRANSFORM_HPP 5 #include <cvd/vision_exceptions.h> 16 template <
class Precision =
double>
26 , big_number(1
'000'000
'000) //Hmm, why doesn't HUGE_VAL work?
32 inline void transform_row(
const int n)
38 for(
int q = 1; q < n; q++)
40 Precision s = ((f[q] + (q * q)) - (f[v[k]] + (v[k] * v[k]))) / (2 * q - 2 * v[k]);
44 s = ((f[q] + (q * q)) - (f[v[k]] + (v[k] * v[k]))) / (2 * q - 2 * v[k]);
49 z[k + 1] = +big_number;
52 for(
int q = 0; q < n; q++)
58 d[q] = ((q - v[k]) * (q - v[k])) + f[v[k]];
59 pos[q] = q > v[k] ? (q - v[k]) : (v[k] - q);
67 for(
int x = 0; x < img_sz.x; x++)
69 for(
int y = 0; y < img_sz.y; y++)
73 transform_row(img_sz.y);
74 for(
int y = 0; y < img_sz.y; y++)
80 for(
int y = 0; y < img_sz.y; y++)
82 for(
int x = 0; x < img_sz.x; x++)
86 transform_row(img_sz.x);
87 for(
int x = 0; x < img_sz.x; x++)
95 template <
class Functor>
101 const double maxdist = img_sz.
x * img_sz.y;
102 for(
int x = 0; x < img_sz.x; x++)
104 for(
int y = 0; y < img_sz.y; y++)
108 transform_row(img_sz.y);
109 for(
int y = 0; y < img_sz.y; y++)
114 for(
int y = 0; y < img_sz.y; y++)
116 for(
int x = 0; x < img_sz.x; x++)
120 transform_row(img_sz.x);
121 for(
int x = 0; x < img_sz.x; x++)
124 const double hyp = d[x];
130 const double dx = pos[x];
131 const double dy = sqrt(hyp - dx * dx);
132 const int ddy =
static_cast<int>(dy);
133 const ImageRef candA(static_cast<int>(x - dx), static_cast<int>(y - ddy));
134 const ImageRef candB(static_cast<int>(x - dx), static_cast<int>(y + ddy));
135 const ImageRef candC(static_cast<int>(x + dx), static_cast<int>(y - ddy));
136 const ImageRef candD(static_cast<int>(x + dx), static_cast<int>(y + ddy));
139 if(DT.in_image(candA) && func(candA))
143 else if(DT.in_image(candB) && func(candB))
147 else if(DT.in_image(candC) && func(candC))
151 else if(DT.in_image(candD) && func(candD))
165 void resize(
const ImageRef& new_size)
170 int m(std::max(new_size.
x, new_size.
y));
189 resize(feature.
size());
193 transform_image_with_ADT(DT, ADT,
NotZero<T>(feature));
199 transform_image(out);
211 bool operator()(
const ImageRef& i)
const 217 template <
class Out,
class Functor>
220 for(
int y = 0; y < out.
size().y; y++)
221 for(
int x = 0; x < out.
size().x; x++)
225 out[y][x] = big_number;
231 std::vector<Precision> d;
233 std::vector<Precision> z;
234 std::vector<Precision> f;
235 std::vector<Precision> pos;
244 template <
class T,
class Q>
261 template <
class T,
class Q>
267 dt.transform_ADT(in, out, lookup_DT);
276 template <
class T,
class Q>
280 for(
int y = 0; y < out.
size().y; y++)
281 for(
int x = 0; x < out.
size().x; x++)
282 out[y][x] = sqrt(out[y][x]);
292 template <
class T,
class Q>
296 for(
int y = 0; y < out.
size().y; y++)
297 for(
int x = 0; x < out.
size().x; x++)
298 out[y][x] = sqrt(out[y][x]);
301 #ifndef DOXYGEN_IGNORE_INTERNAL 331 using namespace Internal;
Input images have incompatible dimensions.
Definition: vision_exceptions.h:26
void euclidean_distance_transform_sq(const BasicImage< T > &in, BasicImage< Q > &out)
Compute squared Euclidean distance transform using the Felzenszwalb & Huttenlocher algorithm...
Definition: distance_transform.h:245
All classes and functions are within the CVD namespace.
Definition: argb.h:6
ImageRef size() const
What is the size of this image?
Definition: image.h:557
void euclidean_distance_transform(const BasicImage< T > &in, BasicImage< Q > &out)
Compute Euclidean distance transform using the Felzenszwalb & Huttenlocher algorithm.
Definition: distance_transform.h:277
void resize(const ImageRef &size)
Resize the image (destroying the data).
Definition: image.h:731
int x
The x co-ordinate.
Definition: image_ref.h:172
Definition: image_ref.h:29
A generic image class to manage a block of arbitrarily padded data as an image.
Definition: image.h:273
int y
The y co-ordinate.
Definition: image_ref.h:173
A full image which manages its own data.
Definition: image.h:623