Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #pragma once
00022
00023 #include <algorithm>
00024
00025 #include "image.h"
00026 #include "imconv.h"
00027
00028 namespace distance_transform
00029 {
00030 const double INF = 1E20;
00031
00032
00033 static float *dt(float *f, int n) {
00034 float *d = new float[n];
00035 int *v = new int[n];
00036 float *z = new float[n+1];
00037 int k = 0;
00038 v[0] = 0;
00039 z[0] = -INF;
00040 z[1] = +INF;
00041 for (int q = 1; q <= n-1; q++) {
00042 float s = ((f[q]+square(q))-(f[v[k]]+square(v[k])))/(2*q-2*v[k]);
00043 while (s <= z[k]) {
00044 k--;
00045 s = ((f[q]+square(q))-(f[v[k]]+square(v[k])))/(2*q-2*v[k]);
00046 }
00047 k++;
00048 v[k] = q;
00049 z[k] = s;
00050 z[k+1] = +INF;
00051 }
00052
00053 k = 0;
00054 for (int q = 0; q <= n-1; q++) {
00055 while (z[k+1] < q)
00056 k++;
00057 d[q] = square(q-v[k]) + f[v[k]];
00058 }
00059
00060 delete [] v;
00061 delete [] z;
00062 return d;
00063 }
00064
00065
00066 static void dt(image<float> *im) {
00067 int width = im->width();
00068 int height = im->height();
00069 float *f = new float[std::max(width,height)];
00070
00071
00072 for (int x = 0; x < width; x++) {
00073 for (int y = 0; y < height; y++) {
00074 f[y] = imRef(im, x, y);
00075 }
00076 float *d = dt(f, height);
00077 for (int y = 0; y < height; y++) {
00078 imRef(im, x, y) = d[y];
00079 }
00080 delete [] d;
00081 }
00082
00083
00084 for (int y = 0; y < height; y++) {
00085 for (int x = 0; x < width; x++) {
00086 f[x] = imRef(im, x, y);
00087 }
00088 float *d = dt(f, width);
00089 for (int x = 0; x < width; x++) {
00090 imRef(im, x, y) = d[x];
00091 }
00092 delete [] d;
00093 }
00094
00095 delete f;
00096 }
00097
00098
00099 static image<float> *dt(image<uchar> *im, uchar on = 1) {
00100 int width = im->width();
00101 int height = im->height();
00102
00103 image<float> *out = new image<float>(width, height, false);
00104 for (int y = 0; y < height; y++) {
00105 for (int x = 0; x < width; x++) {
00106 if (imRef(im, x, y) == on)
00107 imRef(out, x, y) = 0;
00108 else
00109 imRef(out, x, y) = INF;
00110 }
00111 }
00112
00113 dt(out);
00114 return out;
00115 }
00116
00117 }