SMIL  1.1
FastLineSoille.hpp
1 #ifndef __FAST_LINE_SOILLE_T_HPP__
2 #define __FAST_LINE_SOILLE_T_HPP__
3 
4 #include "Core/include/DCore.h"
5 
6 // Morph-M interface by Vincent Morard
7 // 1 september 2010
8 
9 // February 23, 2006 Erik R. Urbach
10 // Email: erik@cs.rug.nl
11 // Implementation of algorithm by Soille et al. [1] for erosions and
12 // dilations with linear structuring elements (S.E.) at arbitrary angles.
13 // S.E. line drawing using Bresenham's Line Algorithm [2].
14 // Compilation: gcc -ansi -pedantic -Wall -O3 -o polygonsoille polygonsoille.c
15 // -lm
16 //
17 // Related papers:
18 // [1] P. Soille and E. Breen and R. Jones.
19 // Recursive implementation of erosions and dilations along discrete
20 // lines at arbitrary angles.
21 // IEEE Transactions on Pattern Analysis and Machine Intelligence,
22 // Vol. 18, Number 5, Pages 562-567, May 1996.
23 // [2] Donald Hearn and M. Pauline Baker
24 // Computer Graphics, second edition
25 // Prentice Hall
26 
27 namespace smil
28 {
29 #ifndef PI
30 #define PI 3.14159265358979323846
31 #endif
32 
33  /*
34  * SoilleLineMorpho defines and hides methods to do Line Based Morphology
35  */
36  template <typename T> class SoilleLineMorpho
37  {
38  public:
40  {
41  }
42 
44  {
45  }
46 
47  private:
48  typedef struct SoilleImage {
49  ulong Width;
50  ulong Height;
51  void *Pixmap;
52  } SoilleImage;
53 
54  typedef unsigned char ubyte;
55  typedef unsigned int uint;
56  typedef unsigned long ulong;
57 
58  ulong ComputeLinePosDiag(long x, long y, ulong width, ulong height,
59  ulong *p)
60  {
61  ulong idx;
62  long x0;
63 
64  if (x < 0) {
65  y -= x;
66  x = 0;
67  }
68  if (y < 0) {
69  x -= y;
70  y = 0;
71  }
72  x0 = x;
73  idx = y * width + x;
74  for (; (x < (long) width) && (y < (long) height); x++) {
75  *p = idx;
76  idx += width + 1;
77  p++;
78  y++;
79  }
80  return (x - x0);
81  } /* ComputeLinePosDiag */
82 
83  ulong ComputeLineNegDiag(long x, long y, ulong width, ulong height,
84  ulong *p)
85  {
86  ulong idx;
87  long x0;
88 
89  if (y >= (long) height) {
90  x += y - height + 1;
91  y = height - 1;
92  }
93  if (x >= (long) width)
94  return (0);
95  x0 = x;
96  idx = y * width + x;
97  *p = idx;
98  while ((x < (long) (width - 1)) && (y > 0)) {
99  p++;
100  x++;
101  y--;
102  idx -= width - 1;
103  *p = idx;
104  }
105  return (x - x0 + 1);
106  } /* ComputeLineNegDiag */
107 
108  ulong ComputeBresenhamLinePX(long x, long y, long dx, long dy, ulong phase,
109  ulong width, ulong height, ulong *p)
110  /* Computes pixel coords along line with slope 0<m<1 */
111  /* Returns # of pixel coords (num) written to array p (num <= width) */
112  {
113  ulong idx;
114  long x0;
115  long dp = 2 * dy - 2 * phase, twody = 2 * dy, twodydx = 2 * dy - 2 * dx;
116 
117  while ((x < 0) || (y < 0)) {
118  if (dp >= 0) {
119  y++;
120  dp += twodydx;
121  } else
122  dp += twody;
123  x++;
124  }
125  x0 = x;
126  idx = y * width + x;
127  while ((x < (long) width) && (y < (long) height)) {
128  *p = idx;
129  p++;
130  if (dp >= 0) {
131  y++;
132  idx += width;
133  dp += twodydx;
134  } else
135  dp += twody;
136  x++;
137  idx++;
138  }
139  return (x - x0);
140  } /* ComputeBresenhamLinePX */
141 
142  ulong ComputeBresenhamLineNX(long x, long y, long dx, long dy, ulong phase,
143  ulong width, ulong height, ulong *p)
144  /* Computes pixel coords along line with slope -1<m<0 */
145  /* Returns # of pixel coords (num) written to array p (num <= width) */
146  {
147  ulong x0 = x, idx = y * width + x;
148  long dp = 2 * dy - 2 * phase, twody = 2 * dy, twodydx = 2 * dy - 2 * dx;
149 
150  while (y >= (long) height) {
151  if (dp >= 0) {
152  y--;
153  dp += twodydx;
154  } else
155  dp += twody;
156  x++;
157  }
158  if (x >= (long) width)
159  return (0);
160  x0 = x;
161  idx = y * width + x;
162  *p = idx;
163  p++;
164  while ((x < (long) width - 1) && (y > 0)) {
165  if (dp >= 0) {
166  y--;
167  idx -= width;
168  dp += twodydx;
169  } else
170  dp += twody;
171  x++;
172  idx++;
173  *p = idx;
174  p++;
175  }
176  return (x - x0 + 1);
177  } /* ComputeBresenhamLineNX */
178 
179  ulong ComputeBresenhamLinePY(long x, long y, long dx, long dy, ulong phase,
180  ulong width, ulong height, ulong *p)
181  /* Computes pixel coords along line with slope m>1 */
182  /* Returns # of pixel coords (num) written to array p (num <= height) */
183  {
184  ulong y0, idx;
185  long dp = 2 * dx - 2 * phase, twodx = 2 * dx, twodxdy = 2 * dx - 2 * dy;
186 
187  while ((x < 0) || (y < 0)) {
188  if (dp >= 0) {
189  x++;
190  dp += twodxdy;
191  } else
192  dp += twodx;
193  y++;
194  }
195  y0 = y;
196  idx = y * width + x;
197  while ((y < (long) height) && (x < (long) width)) {
198  *p = idx;
199  p++;
200  if (dp >= 0) {
201  x++;
202  idx++;
203  dp += twodxdy;
204  } else
205  dp += twodx;
206  y++;
207  idx += width;
208  }
209  return (y - y0);
210  } /* ComputeBresenhamLinePY */
211 
212  ulong ComputeBresenhamLineNY(long x, long y, long dx, long dy, ulong phase,
213  ulong width, ulong height, ulong *p)
214  /* Computes pixel coords along line with slope m<-1 */
215  /* Returns # of pixel coords (num) written to array p (num <= height) */
216  {
217  ulong y0, idx;
218  long dp = 2 * dx - 2 * phase, twodx = 2 * dx, twodxdy = 2 * dx - 2 * dy;
219 
220  while (x >= (long) width) {
221  if (dp >= 0) {
222  x--;
223  dp += twodxdy;
224  } else
225  dp += twodx;
226  y++;
227  }
228  if (y >= (long) height)
229  return (0);
230  y0 = y;
231  idx = y * width + x;
232  *p = idx;
233  p++;
234  while ((y < (long) height - 1) && (x > 0) && (x < (long) width)) {
235  if (dp >= 0) {
236  x--;
237  idx--;
238  dp += twodxdy;
239  } else
240  dp += twodx;
241  y++;
242  idx += width;
243  *p = idx;
244  p++;
245  }
246  return (y - y0 + 1);
247  } /* ComputeBresenhamLineNY */
248 
249  void DilateHorLine(T *f, ulong width, ulong k, T *g, T *h, T *h2, T *r)
250  /* k is length of SE in number of pixels */
251  /* width is length of g, h, h2, and r */
252  {
253  ulong x, x2;
254 
255  for (x = 0; x < width; x++) {
256  x2 = width - 1 - x;
257  if (x % k) {
258  g[x] = MAX(g[x - 1], f[x]);
259  } else {
260  g[x] = f[x];
261  }
262 
263  if (((x2 % k) == (k - 1)) || (x2 == (width - 1))) {
264  h[x2] = f[x2];
265  } else {
266  h[x2] = MAX(h[x2 + 1], f[x2]);
267  }
268  }
269  if ((k == 1) || (width == 1))
270  h[0] = f[0];
271  else
272  h[0] = MAX(h[1], f[0]);
273  h2[width - 1] = f[width - 1];
274  for (x = width - 2; x >= (width - k); x--)
275  h2[x] = MAX(h2[x + 1], f[x]);
276  h2[0] = MAX(h2[1], f[0]);
277 
278  if (width <= (k / 2)) {
279  for (x = 0; x < width; x++)
280  r[x] = g[width - 1];
281  } else if (width <= k) {
282  for (x = 0; x < (width - k / 2); x++)
283  r[x] = g[x + k / 2];
284  for (; x <= (k / 2); x++)
285  r[x] = g[width - 1];
286  for (; x < width; x++)
287  r[x] = h[x - k / 2];
288  } else /* width > k */
289  {
290  for (x = 0; x < (width - k / 2); x++) {
291  if (x < (k / 2))
292  r[x] = g[x + k / 2];
293  else
294  r[x] = MAX(g[x + k / 2], h[x - k / 2]);
295  }
296  for (x = width - k / 2; x < width; x++)
297  r[x] = h2[x - k / 2];
298  }
299  } /* DilateHorLine */
300 
301  void DilateVerLine(T *f, ulong width, ulong height, ulong k, T *g, T *h,
302  T *h2, T *r)
303  /* k is length of SE in number of pixels */
304  /* height is length of g, h, h2, and r */
305  {
306  ulong y, y2;
307 
308  for (y = 0; y < height; y++) {
309  y2 = height - 1 - y;
310  if (y % k) {
311  g[y] = MAX(g[y - 1], f[y * width]);
312  } else
313  g[y] = f[y * width];
314 
315  if (((y2 % k) == (k - 1)) || (y2 == (height - 1)))
316  h[y2] = f[y2 * width];
317  else
318  h[y2] = MAX(h[y2 + 1], f[y2 * width]);
319  }
320 
321  if ((k == 1) || (height == 1))
322  h[0] = f[0];
323  else
324  h[0] = MAX(h[1], f[0]);
325  h2[height - 1] = f[(height - 1) * width];
326  for (y = height - 2; y >= (height - k); y--)
327  h2[y] = MAX(h2[y + 1], f[y * width]);
328  h2[0] = MAX(h[1], f[0]);
329 
330  if (height <= (k / 2)) {
331  for (y = 0; y < height; y++)
332  r[y * width] = g[height - 1];
333  } else if (height <= k) {
334  for (y = 0; y < (height - k / 2); y++)
335  r[y * width] = g[y + k / 2];
336  for (; y <= (k / 2); y++)
337  r[y * width] = g[height - 1];
338  for (; y < height; y++)
339  r[y * width] = h[y - k / 2];
340  } else /* height > k */
341  {
342  for (y = 0; y < (height - k / 2); y++) {
343  if (y < (k / 2))
344  r[y * width] = g[y + k / 2];
345  else
346  r[y * width] = MAX(g[y + k / 2], h[y - k / 2]);
347  }
348  for (y = height - k / 2; y < height; y++)
349  r[y * width] = h2[y - k / 2];
350  }
351  } /* DilateVerLine */
352 
353  void DilateLine(T *f, SMIL_UNUSED ulong width, SMIL_UNUSED ulong height,
354  ulong k, ulong nx, ulong *p, T *g, T *h, T *h2, T *r)
355  /* k is length of SE in number of pixels */
356  /* nx is length of p, g, h, and r */
357  {
358  ulong x, x2;
359 
360  for (x = 0; x < nx; x++) {
361  x2 = nx - 1 - x;
362  if (x % k) {
363  g[x] = MAX(g[x - 1], f[p[x]]);
364  } else
365  g[x] = f[p[x]];
366 
367  if (((x2 % k) == (k - 1)) || (x2 == (nx - 1)))
368  h[x2] = f[p[x2]];
369  else
370  h[x2] = MAX(h[x2 + 1], f[p[x2]]);
371  }
372 
373  if ((k == 1) || (nx == 1))
374  h[0] = f[p[0]];
375  else
376  h[0] = MAX(h[1], f[p[0]]);
377  h2[nx - 1] = f[p[nx - 1]];
378  if (nx >= 2) {
379  for (x = nx - 2; (x > 0) && (x >= (nx - k)); x--)
380  h2[x] = MAX(h2[x + 1], f[p[x]]);
381  h2[0] = MAX(h2[1], f[p[0]]);
382  }
383 
384  if (nx <= (k / 2)) {
385  for (x = 0; x < nx; x++)
386  r[p[x]] = g[nx - 1];
387  } else if (nx <= k) {
388  for (x = 0; x < (nx - k / 2); x++)
389  r[p[x]] = g[x + k / 2];
390  for (; x <= (k / 2); x++)
391  r[p[x]] = g[nx - 1];
392  for (; x < nx; x++)
393  r[p[x]] = h[x - k / 2];
394  } else /* nx > k */
395  {
396  for (x = 0; x < (nx - k / 2); x++) {
397  if (x < (k / 2))
398  r[p[x]] = g[x + k / 2];
399  else
400  r[p[x]] = MAX(g[x + k / 2], h[x - k / 2]);
401  }
402  for (x = nx - k / 2; x < nx; x++)
403  r[p[x]] = h2[x - k / 2];
404  }
405  } /* DilateLine */
406 
407  void ImageGrayDilateHor(SoilleImage *img, ulong k, T *g, T *h, T *h2,
408  SoilleImage *out)
409  {
410  T *f = (T *) img->Pixmap;
411  T *r = (T *) out->Pixmap;
412  ulong width = img->Width;
413 
414  for (ulong y = 0; y < img->Height; y++) {
415  DilateHorLine(f, width, k, g, h, h2, r);
416  f += width;
417  r += width;
418  }
419  } /* ImageGrayDilateHor */
420 
421  void ImageGrayDilateVer(SoilleImage *img, ulong k, T *g, T *h, T *h2,
422  SoilleImage *out)
423  {
424  T *f = (T *) img->Pixmap;
425  T *r = (T *) out->Pixmap;
426  ulong width = img->Width;
427  ulong height = img->Height;
428 
429  for (ulong x = 0; x < width; x++) {
430  DilateVerLine(f, width, height, k, g, h, h2, r);
431  f++;
432  r++;
433  }
434  } /* ImageGrayDilateVer */
435 
436  void ImageGrayDilateLine(SoilleImage *img, ulong k, long dx, long dy,
437  ulong phase, ulong *p, T *g, T *h, T *h2,
438  SoilleImage *out)
439  {
440  T *f = (T *) img->Pixmap;
441  T *r = (T *) out->Pixmap;
442  ulong width = img->Width, height = img->Height, nx;
443  long x, y;
444 
445  if (dy == 0)
446  ImageGrayDilateHor(img, k, g, h, h2, out);
447  else if (dx == 0)
448  ImageGrayDilateVer(img, k, g, h, h2, out);
449  else if (abs(dx) == abs(dy)) {
450  if (dx == -dy) {
451  y = 0;
452  nx = ComputeLineNegDiag(0, y, width, height, p);
453  while (nx > 0) {
454  DilateLine(f, width, height, k, nx, p, g, h, h2, r);
455  y++;
456  nx = ComputeLineNegDiag(0, y, width, height, p);
457  }
458  } else {
459  y = height - 2;
460  nx = ComputeLinePosDiag(0, y, width, height, p);
461  while (nx > 0) {
462  DilateLine(f, width, height, k, nx, p, g, h, h2, r);
463  y--;
464  nx = ComputeLinePosDiag(0, y, width, height, p);
465  }
466  }
467  } else if (abs(dx) > abs(dy)) {
468  if (((dx > 0) && (dy > 0)) || ((dx < 0) && (dy < 0))) {
469  dx = abs(dx);
470  dy = abs(dy);
471  y = height - 1;
472  nx = ComputeBresenhamLinePX(0, y, dx, dy, phase, width, height, p);
473  while (nx > 0) {
474  DilateLine(f, width, height, k, nx, p, g, h, h2, r);
475  y--;
476  nx = ComputeBresenhamLinePX(0, y, dx, dy, phase, width, height, p);
477  }
478  } else {
479  dx = abs(dx);
480  dy = abs(dy);
481  y = 0;
482  nx = ComputeBresenhamLineNX(0, y, dx, dy, phase, width, height, p);
483  while (nx > 0) {
484  DilateLine(f, width, height, k, nx, p, g, h, h2, r);
485  y++;
486  nx = ComputeBresenhamLineNX(0, y, dx, dy, phase, width, height, p);
487  }
488  }
489  } else {
490  if (((dx > 0) && (dy > 0)) || ((dx < 0) && (dy < 0))) {
491  dx = abs(dx);
492  dy = abs(dy);
493  x = width - 1;
494  nx = ComputeBresenhamLinePY(x, 0, dx, dy, phase, width, height, p);
495  while (nx > 0) {
496  DilateLine(f, width, height, k, nx, p, g, h, h2, r);
497  x--;
498  nx = ComputeBresenhamLinePY(x, 0, dx, dy, phase, width, height, p);
499  }
500  } else {
501  dx = abs(dx);
502  dy = abs(dy);
503  x = 0;
504  nx = ComputeBresenhamLineNY(x, 0, dx, dy, phase, width, height, p);
505  while (nx > 0) {
506  DilateLine(f, width, height, k, nx, p, g, h, h2, r);
507  x++;
508  nx = ComputeBresenhamLineNY(x, 0, dx, dy, phase, width, height, p);
509  }
510  }
511  }
512  } /* ImageGrayDilateLine */
513 
514  public:
515  RES_T lineDilate(const Image<T> &imIn, const int angle, const int radius,
516  Image<T> &imOut)
517  {
518  // Check inputs
519  ASSERT_ALLOCATED(&imIn);
520  ASSERT_ALLOCATED(&imOut);
521  ASSERT_SAME_SIZE(&imIn, &imOut);
522 
523  int W, H;
524  W = imIn.getWidth();
525  H = imIn.getHeight();
526  if (imIn.getDepth() > 1) {
527  std::cerr << "This functions doesn't handle 3D images" << std::endl;
528  return RES_ERR;
529  }
530 
531  int maxnx = MAX(W, H);
532  T *g = new T[maxnx];
533  T *h = new T[maxnx];
534  T *h2 = new T[maxnx];
535  ulong *p = new ulong[maxnx];
536 
537  SoilleImage MyImgIn, MyImgOut;
538 
539  MyImgIn.Width = W;
540  MyImgIn.Height = H;
541  MyImgIn.Pixmap = (void *) imIn.getPixels();
542 
543  MyImgOut.Width = W;
544  MyImgOut.Height = H;
545  MyImgOut.Pixmap = (void *) imOut.getPixels();
546 
547  float rd = angle * PI / 180.;
548  int r = radius;
549  r = (int ) floor(r * std::max(fabs(cos(rd)), fabs(sin(rd))) + 0.5);
550 
551  int dx = (int) (cos(angle * PI / 180.0) * maxnx);
552  int dy = (int) (-sin(angle * PI / 180.0) * maxnx);
553 
554  ImageGrayDilateLine(&MyImgIn, r * 2 + 1, dx, dy, 1, p, g, h, h2,
555  &MyImgOut);
556 
557  delete[] g;
558  delete[] h;
559  delete[] h2;
560  delete[] p;
561 
562  return RES_OK;
563  }
564 
565  RES_T lineErode(const Image<T> &imIn, const int angle, const int radius,
566  Image<T> &imOut)
567  {
568  RES_T r = RES_OK;
569  Image<T> imTmp(imIn);
570 
571  r = inv(imIn, imTmp);
572  if (r == RES_OK)
573  r = lineDilate(imTmp, angle, radius, imOut);
574  if (r == RES_OK)
575  r = inv(imOut, imOut);
576  return r;
577  }
578 
579  RES_T lineOpen(const Image<T> &imIn, const int angle, const int radius,
580  Image<T> &imOut)
581  {
582  RES_T r = RES_OK;
583  Image<T> imTmp(imIn);
584 
585  r = lineErode(imIn, angle, radius, imTmp);
586  if (r == RES_OK)
587  r = lineDilate(imTmp, angle, radius, imOut);
588  return r;
589  }
590 
591  RES_T lineClose(const Image<T> &imIn, const int angle, const int radius,
592  Image<T> &imOut)
593  {
594  RES_T r = RES_OK;
595  Image<T> imTmp(imIn);
596 
597  r = lineDilate(imIn, angle, radius, imTmp);
598  if (r == RES_OK)
599  r = lineErode(imTmp, angle, radius, imOut);
600  return r;
601  }
602 
603  RES_T circleDilate(const Image<T> &imIn, const int radius,
604  Image<T> &imOut)
605  {
606  RES_T r;
607  int i, nbAngle = 8;
608  double alpha, kalpha, rd, k0;
609 
610  r = copy(imIn, imOut);
611  if (r != RES_OK)
612  return r;
613 
614  k0 = (radius * PI / nbAngle * 0.5);
615  for (i = 0; i < nbAngle; i++) {
616  alpha = i * 180. / nbAngle;
617  rd = alpha * PI / 180.;
618  kalpha = k0 * std::max(fabs(cos(rd)), fabs(sin(rd))) + 0.5;
619 
620  r = lineDilate(imOut, (int) alpha, (int) kalpha, imOut);
621  if (r != RES_OK)
622  break;
623  }
624  return r;
625  }
626 
627  RES_T circleErode(const Image<T> &imIn, const int radius, Image<T> &imOut)
628  {
629  RES_T r;
630  int i, nbAngle = 8;
631  double alpha, kalpha, rd, k0;
632 
633  r = copy(imIn, imOut);
634  if (r != RES_OK)
635  return r;
636 
637  k0 = (radius * PI / nbAngle * 0.5);
638  for (i = 0; i < nbAngle; i++) {
639  alpha = i * 180. / nbAngle;
640  rd = alpha * PI / 180.;
641  kalpha = k0 * std::max(fabs(cos(rd)), fabs(sin(rd))) + 0.5;
642 
643  r = lineErode(imOut, (int) alpha, (int) kalpha, imOut);
644  if (r != RES_OK)
645  break;
646  }
647  return r;
648  }
649 
650  RES_T circleOpen(const Image<T> &imIn, const int radius, Image<T> &imOut)
651  {
652  RES_T r;
653 
654  r = circleErode(imIn, radius, imOut);
655  if (r == RES_OK)
656  r = circleDilate(imOut, radius, imOut);
657  return r;
658  }
659 
660  RES_T circleClose(const Image<T> &imIn, const int radius, Image<T> &imOut)
661  {
662  RES_T r;
663  r = circleDilate(imIn, radius, imOut);
664  if (r == RES_OK)
665  r = circleErode(imOut, radius, imOut);
666  return r;
667  }
668 
669  RES_T squareDilate(const Image<T> &imIn, const int radius,
670  Image<T> &imOut)
671  {
672  Image<T> imTmp(imIn);
673 
674  RES_T res = lineDilate(imIn, 0, radius, imTmp);
675  if (res == RES_OK)
676  res = lineDilate(imTmp, 90, radius, imOut);
677  return res;
678  }
679 
680  RES_T squareErode(const Image<T> &imIn, const int radius, Image<T> &imOut)
681  {
682  Image<T> imTmp(imIn);
683 
684  RES_T res = lineErode(imIn, 0, radius, imTmp);
685  if (res == RES_OK)
686  res = lineErode(imTmp, 90, radius, imOut);
687  return res;
688  }
689 
690  RES_T squareOpen(const Image<T> &imIn, const int radius, Image<T> &imOut)
691  {
692  Image<T> imTmp(imIn);
693 
694  RES_T res = lineErode(imIn, 0, radius, imTmp);
695  if (res == RES_OK)
696  res = lineErode(imTmp, 90, radius, imOut);
697  if (res == RES_OK)
698  res = lineDilate(imOut, 0, radius, imTmp);
699  if (res == RES_OK)
700  res = lineDilate(imTmp, 90, radius, imOut);
701  return res;
702  }
703 
704  RES_T squareClose(const Image<T> &imIn, const int radius, Image<T> &imOut)
705  {
706  Image<T> imTmp(imIn);
707 
708  RES_T res = lineDilate(imIn, 0, radius, imTmp);
709  if (res == RES_OK)
710  res = lineDilate(imTmp, 90, radius, imOut);
711  if (res == RES_OK)
712  res = lineErode(imOut, 0, radius, imTmp);
713  if (res == RES_OK)
714  res = lineErode(imTmp, 90, radius, imOut);
715  return res;
716  }
717  };
718 
719  /*
720  *
721  * Interface to SoilleLineMorpho Functor
722  *
723  */
724 
725  /*
726  * Line Based Morphological operators
727  */
728  template <class T>
729  RES_T lineDilate_Soille(const Image<T> &imIn, const int angle,
730  const int radius, Image<T> &imOut)
731  {
732  SoilleLineMorpho<T> soille;
733  return soille.lineDilate(imIn, angle, radius, imOut);
734  }
735 
736  template <class T>
737  RES_T lineErode_Soille(const Image<T> &imIn, const int angle,
738  const int radius, Image<T> &imOut)
739  {
740  SoilleLineMorpho<T> soille;
741  return soille.lineErode(imIn, angle, radius, imOut);
742  }
743 
744  template <class T>
745  RES_T lineOpen_Soille(const Image<T> &imIn, const int angle,
746  const int radius, Image<T> &imOut)
747  {
748  SoilleLineMorpho<T> soille;
749  return soille.lineOpen(imIn, angle, radius, imOut);
750  }
751 
752  template <class T>
753  RES_T lineClose_Soille(const Image<T> &imIn, const int angle,
754  const int radius, Image<T> &imOut)
755  {
756  SoilleLineMorpho<T> soille;
757  return soille.lineClose(imIn, angle, radius, imOut);
758  }
759 
760  /*
761  * Line Based Morphological operators on circles
762  */
763  template <class T>
764  RES_T circleDilate_Soille(const Image<T> &imIn, const int radius,
765  Image<T> &imOut)
766  {
767  SoilleLineMorpho<T> soille;
768  return soille.circleDilate(imIn, radius, imOut);
769  }
770 
771  template <class T>
772  RES_T circleErode_Soille(const Image<T> &imIn, const int radius,
773  Image<T> &imOut)
774  {
775  SoilleLineMorpho<T> soille;
776  return soille.circleErode(imIn, radius, imOut);
777  }
778 
779  template <class T>
780  RES_T circleOpen_Soille(const Image<T> &imIn, const int radius,
781  Image<T> &imOut)
782  {
783  SoilleLineMorpho<T> soille;
784  return soille.circleOpen(imIn, radius, imOut);
785  }
786 
787  template <class T>
788  RES_T circleClose_Soille(const Image<T> &imIn, const int radius,
789  Image<T> &imOut)
790  {
791  SoilleLineMorpho<T> soille;
792  return soille.circleClose(imIn, radius, imOut);
793  }
794 
795  /*
796  * Line Based Morphological operators on squares
797  */
798  template <class T>
799  RES_T squareDilate_Soille(const Image<T> &imIn, const int radius,
800  Image<T> &imOut)
801  {
802  SoilleLineMorpho<T> soille;
803  return soille.squareDilate(imIn, radius, imOut);
804  }
805 
806  template <class T>
807  RES_T squareErode_Soille(const Image<T> &imIn, const int radius,
808  Image<T> &imOut)
809  {
810  SoilleLineMorpho<T> soille;
811  return soille.squareErode(imIn, radius, imOut);
812  }
813 
814  template <class T>
815  RES_T squareOpen_Soille(const Image<T> &imIn, const int radius,
816  Image<T> &imOut)
817  {
818  SoilleLineMorpho<T> soille;
819  return soille.squareOpen(imIn, radius, imOut);
820  }
821 
822  template <class T>
823  RES_T squareClose_Soille(const Image<T> &imIn, const int radius,
824  Image<T> &imOut)
825  {
826  SoilleLineMorpho<T> soille;
827  return soille.squareClose(imIn, radius, imOut);
828  }
829 
830 } // namespace smil
831 
832 #endif
Definition: FastLineSoille.hpp:37
RES_T inv(const Image< T > &imIn, Image< T > &imOut)
inv() - Invert an image.
Definition: DImageArith.hpp:70
RES_T copy(const Image< T1 > &imIn, size_t startX, size_t startY, size_t startZ, size_t sizeX, size_t sizeY, size_t sizeZ, Image< T2 > &imOut, size_t outStartX=0, size_t outStartY=0, size_t outStartZ=0)
copy() - Copy image (or a zone) into an output image
Definition: DImageTransform.hpp:84
Definition: FastLineSoille.hpp:48