SMIL  1.0.4
FastIncompletePathOpening.hpp
1 /*
2  * __HEAD__
3  * Copyright (c) 2011-2016, Matthieu FAESSEL and ARMINES
4  * Copyright (c) 2017-2023, Centre de Morphologie Mathematique
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * * Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  * * Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  * * Neither the name of Matthieu FAESSEL, or ARMINES nor the
16  * names of its contributors may be used to endorse or promote products
17  * derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
29  * THE POSSIBILITY OF SUCH DAMAGE.
30  *
31  * Description :
32  * Parsimonious incomplete-path openings
33  * Author : Petr Dokladal (based on V. Morard's code)
34  * implements Parsimonious Incomplete-Path Openings using the Rank Opening
35  * (see Pierre Soille, On morphological operators based on rank filters,
36  * Pattern Recognition 35 (2002) 527-535)
37  * the rank opening is implemented as a rank filter followed by a dilation.
38  * It uses histograms.
39  * TO DOS : 1) make it isotropic.
40  * 2) extend the border mirroring to SE>n. Will be useful for short
41  * diagonal paths in the corners of the image
42  * (see how this extension can be done)
43  * This file does... some very complex morphological operation...
44  *
45  * History :
46  * - 08/06/2020 - by Jose-Marcio Martins da Cruz
47  * Porting from Petr Dokladal code in Morph-M
48  *
49  * __HEAD__ - Stop here !
50  */
51 
52 #ifndef __FAST_PIPATH_OPENING_HPP__
53 #define __FAST_PIPATH_OPENING_HPP__
54 
55 #include <queue>
56 #include "Morpho/include/DMorpho.h"
57 
58 namespace smil
59 {
60  /*
61  *
62  *
63  *
64  */
65  template <class T> class ParsimoniousPathOpeningClass
66  {
67  // better to define this as a boolean
68  bool MIRROR_BORDERS = true;
69 
70  public:
72  {
73  MIRROR_BORDERS = true;
74  }
76  {
77  }
78 
79  private:
80 
81  /*
82  *
83  */
84  T rank(T *H, int r)
85  {
86  int cnt = 0;
87  T ii;
88  /*
89  * size of HWidth shall be bigger than size of T
90  * this loop may take really long when T is of type UINT32
91  */
92  off_t HWidth = numeric_limits<T>::max();
93 
94  for (ii = 0; ii < HWidth; ii++) {
95  cnt += H[ii];
96  if (cnt > r)
97  break;
98  }
99  return ii;
100  }
101 
102  /*
103  *
104  */
105  RES_T rank_filter_indx(T *x, off_t *indx, int n, int SE, int r, T *y)
106  {
107  // cout << "rank_filter_indx " << n << " " << SE << " " << r << endl;
108  uint64_t HWidth = numeric_limits<T>::max();
109 
110  T *H = new T[HWidth]();
111 
112  // pad border
113  off_t *indx_pad = new off_t[n + 2 * SE]();
114  memcpy(indx_pad + SE, indx, n * sizeof(off_t));
115 
116  if (!MIRROR_BORDERS) {
117  // pad border by replicating
118  for (off_t ii = 0; ii < SE; ii++) {
119  indx_pad[ii] = indx[0];
120  indx_pad[n + SE + ii] = indx[n - 1];
121  }
122  } else {
123  // pad border by mirroring
124  for (off_t ii = 0; ii < SE; ii++) {
125  off_t ix, iy;
126  ix = ii;
127  iy = (SE - ii) % n;
128  indx_pad[ix] = indx[iy];
129  ix = SE + n + ii;
130  iy = n - 2 - ii;
131  while (iy < 0)
132  iy += n;
133  iy = iy % n;
134  indx_pad[ix] = indx[iy];
135  }
136  }
137 
138  // init histogram
139  for (off_t ii = 0; ii < SE; ii++) {
140  // no weight is used
141  H[x[indx_pad[ii + SE - SE / 2]]] += 1;
142  }
143  y[0] = rank(H, r);
144 
145  for (off_t ii = 0; ii < n - 1; ii++) {
146  // no weight is used
147  H[x[indx_pad[ii + SE - SE / 2]]] -= 1;
148  H[x[indx_pad[ii + 2 * SE - SE / 2]]] += 1;
149  y[ii + 1] = rank(H, r);
150  }
151 
152  delete[] indx_pad;
153  delete[] H;
154 
155  return RES_OK;
156  }
157 
158  /*
159  *
160  */
161  RES_T conj_dilation(T *x, int n, int SE, T *y)
162  {
163  uint64_t HWidth = numeric_limits<T>::max();
164  T *H = new T[HWidth]();
165  // pad border by replicating
166  T *x_pad = new T[n + 2 * SE]();
167  memcpy(x_pad + SE, x, n * sizeof(T));
168  for (off_t i = 0; i < SE; i++) {
169  x_pad[i] = x[0];
170  x_pad[n + SE + i] = x[n - 1];
171  }
172 
173  // init histogram
174  for (off_t ii = 0; ii < SE; ii++)
175  H[x_pad[ii + SE - SE / 2 + (SE + 1) % 2]] += 1;
176  y[0] = rank(H, SE - 1);
177 
178  for (off_t ii = 0; ii < n - 1; ii++) {
179  H[x_pad[ii + SE - SE / 2 + (SE + 1) % 2]] -= 1;
180  H[x_pad[ii + 2 * SE - SE / 2 + (SE + 1) % 2]] += 1;
181  y[ii + 1] = rank(H, SE - 1);
182  }
183 
184  delete[] x_pad;
185  delete[] H;
186 
187  return RES_OK;
188  }
189 
190  /*
191  *
192  */
193  RES_T rank_open(T *x, off_t *indx, int n, int SE, int r, T *y)
194  {
195  T *xi = new T[n]();
196  T *dxi = new T[n]();
197 
198  (void ) rank_filter_indx(x, indx, n, SE, r, xi);
199  (void ) conj_dilation(xi, n, SE, dxi);
200 
201  for (off_t ii = 0; ii < n; ii++)
202  y[indx[ii]] = max(y[indx[ii]], min(x[indx[ii]], dxi[ii]));
203 
204  delete[] xi;
205  delete[] dxi;
206 
207  return RES_OK;
208  }
209 
210  public:
211  /*
212  *
213  *
214  */
215  RES_T doIt(Image<T> &imIn, int size, int tolerance, int step,
216  Image<T> &imOut)
217  {
218  ASSERT_ALLOCATED(&imIn, &imOut);
219  ASSERT_SAME_SIZE(&imIn, &imOut);
220  ASSERT(imIn.getDepth() == 1);
221  ASSERT(tolerance >= 0);
222  ASSERT(step > 0);
223 
224  int Dir, DirH, DirV;
225  int i, j, whichLine;
226 
227  off_t W = (off_t) imIn.getWidth();
228  off_t H = (off_t) imIn.getHeight();
229  T F = 0;
230 
231  typename ImDtTypes<T>::lineType bufferIn = imIn.getPixels();
232  typename ImDtTypes<T>::lineType bufferOut = imOut.getPixels();
233 
234  // Initialisation
235  fill(imOut, T(0));
236  off_t *indx = new off_t[W + H]();
237 
238  // First direction Left to right
239  // printf ("direction 1: left-to-right\n");
240  for (j = 0; j < H; j += step) {
241  // JOE wp = 0;
242  // JOE Length = 0;
243  // JOE stackSize = 0;
244  indx[0] = j * W;
245  whichLine = j;
246 
247  for (i = 1; i < W; i++) {
248  F = bufferIn[i + whichLine * W];
249  indx[i] = i + whichLine * W;
250  Dir = 0;
251  // JOE lengthDir = 1;
252  if (whichLine - 1 >= 0 && F < bufferIn[i + (whichLine - 1) * W]) {
253  F = bufferIn[i + (whichLine - 1) * W];
254  indx[i] = i + (whichLine - 1) * W;
255  Dir = -1;
256  // JOE lengthDir = SQRT_2;
257  }
258  if (whichLine + 1 < H && F < bufferIn[i + (whichLine + 1) * W]) {
259  indx[i] = i + (whichLine + 1) * W;
260  Dir = 1;
261  // JOE lengthDir = SQRT_2;
262  }
263  whichLine += Dir;
264  }
265  rank_open(bufferIn, indx, W, size, tolerance, bufferOut);
266  }
267 
268  // Second direction Right to left
269  // printf ("direction 2: right-to-left\n");
270  for (j = 0; j < H; j += step) {
271  // JOE wp = 0;
272  // JOE Length = 0;
273  // JOE stackSize = 0;
274  indx[W - 1] = W - 1 + j * W;
275  whichLine = j;
276  for (i = W - 2; i >= 0; i--) {
277  F = bufferIn[i + whichLine * W];
278  indx[i] = i + whichLine * W;
279  Dir = 0;
280  // JOE lengthDir = 1;
281  if (whichLine - 1 >= 0 && F < bufferIn[i + (whichLine - 1) * W]) {
282  F = bufferIn[i + (whichLine - 1) * W];
283  indx[i] = i + (whichLine - 1) * W;
284  Dir = -1;
285  // JOE lengthDir = SQRT_2;
286  }
287  if (whichLine + 1 < H && F < bufferIn[i + (whichLine + 1) * W]) {
288  indx[i] = i + (whichLine + 1) * W;
289  Dir = 1;
290  // JOE lengthDir = SQRT_2;
291  }
292  whichLine += Dir;
293  }
294  rank_open(bufferIn, indx, W, size, tolerance, bufferOut);
295  }
296 
297  // Third direction Top to bottom
298  // printf ("direction 3: Top to bottom\n");
299  for (i = 0; i < W; i += step) {
300  // JOE wp = 0;
301  // JOE Length = 0;
302  // JOE stackSize = 0;
303  indx[0] = i;
304  whichLine = i;
305  for (j = 1; j < H; j++) {
306  F = bufferIn[whichLine + j * W];
307  indx[j] = whichLine + j * W;
308  Dir = 0;
309  // JOE lengthDir = 1;
310  if (whichLine - 1 >= 0 && F < bufferIn[whichLine - 1 + j * W]) {
311  F = bufferIn[whichLine - 1 + j * W];
312  indx[j] = whichLine - 1 + j * W;
313  Dir = -1;
314  // JOE lengthDir = SQRT_2;
315  }
316  if (whichLine + 1 < W && F < bufferIn[whichLine + 1 + j * W]) {
317  indx[j] = whichLine + 1 + j * W;
318  Dir = 1;
319  // JOE lengthDir = SQRT_2;
320  }
321  whichLine += Dir;
322  }
323  rank_open(bufferIn, indx, H, size, tolerance, bufferOut);
324  }
325 
326  // Fourth direction bottom to top
327  // printf ("direction 4: bottom to top\n");
328  for (i = 0; i < W; i += step) {
329  // JOE wp = 0;
330  // JOE Length = 0;
331  // JOE stackSize = 0;
332  indx[H - 1] = i + (H - 1) * W;
333  whichLine = i;
334  for (j = H - 2; j >= 0; j--) {
335  F = bufferIn[whichLine + j * W];
336  indx[j] = whichLine + j * W;
337  Dir = 0;
338  // JOE lengthDir = 1;
339  if (whichLine - 1 >= 0 && F < bufferIn[whichLine - 1 + j * W]) {
340  F = bufferIn[whichLine - 1 + j * W];
341  indx[j] = whichLine - 1 + j * W;
342  Dir = -1;
343  // JOE lengthDir = SQRT_2;
344  }
345  if (whichLine + 1 < W && F < bufferIn[whichLine + 1 + j * W]) {
346  indx[j] = whichLine + 1 + j * W;
347  Dir = 1;
348  // JOE lengthDir = SQRT_2;
349  }
350  whichLine += Dir;
351  }
352  rank_open(bufferIn, indx, H, size, tolerance, bufferOut);
353  }
354 
355  // Fifth direction bottom left, top right
356  // printf ("direction 5: bottom left, top right\n");
357  for (j = 1; j < H; j += step) {
358  // JOE wp = 0;
359  // JOE Length = 0;
360  // JOE stackSize = 0;
361  indx[0] = j * W;
362  whichLine = j;
363  i = 0;
364  int cnt = 1;
365 
366  do {
367  F = bufferIn[i + 1 + (whichLine - 1) * W];
368  indx[cnt] = i + 1 + (whichLine - 1) * W;
369  DirV = -1;
370  DirH = 1;
371  // JOE lengthDir = SQRT_2;
372  if (whichLine - 1 >= 0 && F < bufferIn[i + (whichLine - 1) * W]) {
373  F = bufferIn[i + (whichLine - 1) * W];
374  indx[cnt] = i + (whichLine - 1) * W;
375  DirH = 0;
376  DirV = -1;
377  // JOE lengthDir = 1;
378  }
379  if (i + 1 < W && F < bufferIn[i + 1 + (whichLine) *W]) {
380  F = bufferIn[i + 1 + (whichLine) *W];
381  indx[cnt] = i + 1 + (whichLine) *W;
382  DirH = 1;
383  DirV = 0;
384  // JOE lengthDir = 1;
385  }
386  i += DirH;
387  whichLine += DirV;
388  cnt++;
389  } while (i <= W - 2 && whichLine >= 1);
390  // cout << "Cinq" << endl;
391  rank_open(bufferIn, indx, cnt, size, tolerance, bufferOut);
392  }
393 
394  for (i = 0; i < W - 1; i += step) {
395  // JOE wp = 0;
396  // JOE Length = 0;
397  // JOE stackSize = 0;
398  indx[0] = i + (H - 1) * W;
399  whichLine = i;
400  j = H - 1;
401  int cnt = 1;
402 
403  do {
404  F = bufferIn[whichLine + 1 + (j - 1) * W];
405  indx[cnt] = whichLine + 1 + (j - 1) * W;
406  DirV = -1;
407  DirH = 1;
408  // JOE lengthDir = SQRT_2;
409  if (j - 1 >= 0 && F < bufferIn[whichLine + (j - 1) * W]) {
410  F = bufferIn[whichLine + (j - 1) * W];
411  indx[cnt] = whichLine + (j - 1) * W;
412  DirH = 0;
413  DirV = -1;
414  // JOE lengthDir = 1;
415  }
416  if (whichLine + 1 < W && F < bufferIn[whichLine + 1 + (j) *W]) {
417  F = bufferIn[whichLine + 1 + (j) *W];
418  indx[cnt] = whichLine + 1 + (j) *W;
419  DirH = 1;
420  DirV = 0;
421  // JOE lengthDir = 1;
422  }
423  whichLine += DirH;
424  j += DirV;
425  cnt++;
426  } while (whichLine <= W - 2 && j >= 1);
427  rank_open(bufferIn, indx, cnt, size, tolerance, bufferOut);
428  }
429 
430  // Sixth direction top right to bottom left
431  // printf ("direction 6: top right to bottom left\n");
432  for (j = 0; j < H - 1; j += step) {
433  // JOE wp = 0;
434  // JOE Length = 0;
435  // JOE stackSize = 0;
436  indx[0] = W - 1 + j * W;
437  whichLine = j;
438  i = W - 1;
439  int cnt = 1;
440  do {
441  F = bufferIn[i - 1 + (whichLine + 1) * W];
442  indx[cnt] = i - 1 + (whichLine + 1) * W;
443  DirV = 1;
444  DirH = -1;
445  // JOE lengthDir = SQRT_2;
446  if (whichLine + 1 < H && F < bufferIn[i + (whichLine + 1) * W]) {
447  F = bufferIn[i + (whichLine + 1) * W];
448  indx[cnt] = i + (whichLine + 1) * W;
449  DirH = 0;
450  DirV = 1;
451  // JOE lengthDir = 1;
452  }
453  if (i - 1 >= 0 && F < bufferIn[i - 1 + (whichLine) *W]) {
454  F = bufferIn[i - 1 + (whichLine) *W];
455  indx[cnt] = i - 1 + (whichLine) *W;
456  DirH = -1;
457  DirV = 0;
458  // JOE lengthDir = 1;
459  }
460  i += DirH;
461  whichLine += DirV;
462  cnt++;
463  } while (i >= 1 && whichLine <= H - 2);
464  rank_open(bufferIn, indx, cnt, size, tolerance, bufferOut);
465  }
466 
467  for (i = 1; i < W; i += step) {
468  // JOE wp = 0;
469  // JOE Length = 0;
470  // JOE stackSize = 0;
471  indx[0] = i;
472  whichLine = i;
473  j = 0;
474  int cnt = 1;
475 
476  do {
477  F = bufferIn[whichLine - 1 + (j + 1) * W];
478  indx[cnt] = whichLine - 1 + (j + 1) * W;
479  DirV = 1;
480  DirH = -1;
481  // JOE lengthDir = SQRT_2;
482  if (j + 1 < H && F < bufferIn[whichLine + (j + 1) * W]) {
483  F = bufferIn[whichLine + (j + 1) * W];
484  indx[cnt] = whichLine + (j + 1) * W;
485  DirH = 0;
486  DirV = 1;
487  // JOE lengthDir = 1;
488  }
489  if (whichLine - 1 >= 0 && F < bufferIn[whichLine - 1 + (j) *W]) {
490  F = bufferIn[whichLine - 1 + (j) *W];
491  indx[cnt] = whichLine - 1 + (j) *W;
492  DirH = -1;
493  DirV = 0;
494  // JOE lengthDir = 1;
495  }
496  whichLine += DirH;
497  j += DirV;
498  cnt++;
499  } while (whichLine >= 1 && j <= H - 2);
500  rank_open(bufferIn, indx, cnt, size, tolerance, bufferOut);
501  }
502 
503  // Seventh direction top left, bottom right
504  // printf ("direction 7: top left, bottom right\n");
505  for (j = 0; j < H - 1; j += step) {
506  // JOE wp = 0;
507  // JOE Length = 0;
508  // JOE stackSize = 0;
509  indx[0] = j * W;
510  whichLine = j;
511  i = 0;
512  int cnt = 1;
513 
514  do {
515  F = bufferIn[i + 1 + (whichLine + 1) * W];
516  indx[cnt] = i + 1 + (whichLine + 1) * W;
517  DirV = 1;
518  DirH = 1;
519  // JOE lengthDir = SQRT_2;
520  if (whichLine + 1 < H && F < bufferIn[i + (whichLine + 1) * W]) {
521  F = bufferIn[i + (whichLine + 1) * W];
522  indx[cnt] = i + (whichLine + 1) * W;
523  DirH = 0;
524  DirV = 1;
525  // JOE lengthDir = 1;
526  }
527  if (i + 1 < W && F < bufferIn[i + 1 + (whichLine) *W]) {
528  F = bufferIn[i + 1 + (whichLine) *W];
529  indx[cnt] = i + 1 + (whichLine) *W;
530  DirH = 1;
531  DirV = 0;
532  // JOE lengthDir = 1;
533  }
534  i += DirH;
535  whichLine += DirV;
536  cnt++;
537  } while (i <= W - 2 && whichLine <= H - 2);
538  rank_open(bufferIn, indx, cnt, size, tolerance, bufferOut);
539  }
540 
541  for (i = 0; i < W - 1; i += step) {
542  // JOE wp = 0;
543  // JOE Length = 0;
544  // JOE stackSize = 0;
545  indx[0] = i;
546  whichLine = i;
547  j = 0;
548  int cnt = 1;
549 
550  do {
551  F = bufferIn[whichLine + 1 + (j + 1) * W];
552  indx[cnt] = whichLine + 1 + (j + 1) * W;
553  DirV = 1;
554  DirH = 1;
555  // JOE lengthDir = SQRT_2;
556  if (j + 1 < H && F < bufferIn[whichLine + (j + 1) * W]) {
557  F = bufferIn[whichLine + (j + 1) * W];
558  indx[cnt] = whichLine + (j + 1) * W;
559  DirH = 0;
560  DirV = 1;
561  // JOE lengthDir = 1;
562  }
563  if (whichLine + 1 < W && F < bufferIn[whichLine + 1 + (j) *W]) {
564  F = bufferIn[whichLine + 1 + (j) *W];
565  indx[cnt] = whichLine + 1 + (j) *W;
566  DirH = 1;
567  DirV = 0;
568  // JOE lengthDir = 1;
569  }
570  whichLine += DirH;
571  j += DirV;
572  cnt++;
573  } while (whichLine <= W - 2 && j <= H - 2);
574  rank_open(bufferIn, indx, cnt, size, tolerance, bufferOut);
575  }
576 
577  // 8 : direction bottom right to top left
578  // printf ("direction 8: bottom right to top left\n");
579  for (j = 1; j < H; j += step) {
580  // JOE wp = 0;
581  // JOE Length = 0;
582  // JOE stackSize = 0;
583  indx[0] = W - 1 + j * W;
584  whichLine = j;
585  i = W - 1;
586  int cnt = 1;
587 
588  do {
589  F = bufferIn[i - 1 + (whichLine - 1) * W];
590  indx[cnt] = i - 1 + (whichLine - 1) * W;
591  DirV = -1;
592  DirH = -1;
593  // JOE lengthDir = SQRT_2;
594  if (whichLine - 1 >= 0 && F < bufferIn[i + (whichLine - 1) * W]) {
595  F = bufferIn[i + (whichLine - 1) * W];
596  indx[cnt] = i + (whichLine - 1) * W;
597  DirH = 0;
598  DirV = -1;
599  // JOE lengthDir = 1;
600  }
601  if (i - 1 >= 0 && F < bufferIn[i - 1 + (whichLine) *W]) {
602  F = bufferIn[i - 1 + (whichLine) *W];
603  indx[cnt] = i - 1 + (whichLine) *W;
604  DirH = -1;
605  DirV = 0;
606  // JOE lengthDir = 1;
607  }
608  i += DirH;
609  whichLine += DirV;
610  cnt++;
611  } while (i >= 1 && whichLine >= 1);
612  rank_open(bufferIn, indx, cnt, size, tolerance, bufferOut);
613  }
614 
615  for (i = 1; i < W; i += step) {
616  // JOE wp = 0;
617  // JOE Length = 0;
618  // JOE stackSize = 0;
619  indx[0] = i + (H - 1) * W;
620  whichLine = i;
621  j = H - 1;
622  int cnt = 1;
623 
624  do {
625  F = bufferIn[whichLine - 1 + (j - 1) * W];
626  indx[cnt] = whichLine - 1 + (j - 1) * W;
627  DirV = -1;
628  DirH = -1;
629  // JOE lengthDir = SQRT_2;
630  if (j - 1 >= 0 && F < bufferIn[whichLine + (j - 1) * W]) {
631  F = bufferIn[whichLine + (j - 1) * W];
632  indx[cnt] = whichLine + (j - 1) * W;
633  DirH = 0;
634  DirV = -1;
635  // JOE lengthDir = 1;
636  }
637  if (whichLine - 1 >= 0 && F < bufferIn[whichLine - 1 + (j) *W]) {
638  F = bufferIn[whichLine - 1 + (j) *W];
639  indx[cnt] = whichLine - 1 + (j) *W;
640  DirH = -1;
641  DirV = 0;
642  // JOE lengthDir = 1;
643  }
644  whichLine += DirH;
645  j += DirV;
646  cnt++;
647  } while (whichLine >= 1 && j >= 1);
648  rank_open(bufferIn, indx, cnt, size, tolerance, bufferOut);
649  }
650 
651  // JOE delete[] LineIdx;
652  delete[] indx;
653 
654  return RES_OK;
655  }
656  };
657 
658  /*
659  *
660  *
661  *
662  */
663  template <class T>
664  RES_T parsimoniousPathOpening(Image<T> &imIn, int Size,
665  int tolerance, int step,
666  bool rebuild, Image<T> &imOut)
667  {
669 
670  RES_T res;
671 
672  res = pOpen.doIt(imIn, Size, tolerance, step, imOut);
673  if (res != RES_OK) {
674  ERR_MSG("Error doint path opening");
675  return res;
676  }
677 
678  /* Do rebuild */
679  if (rebuild) {
680  res = geoBuild(imOut, imIn, imOut);
681  if (res != RES_OK)
682  ERR_MSG("Error while rebuilding after Path Opening");
683  }
684 
685  return res;
686  }
687 
688 
689 } // namespace smil
690 
691 #endif // __FAST_PIPATH_OPENING_HPP__
size_t getDepth() const
Get image depth (Z)
Definition: DBaseImage.h:90
size_t getWidth() const
Get image width.
Definition: DBaseImage.h:80
size_t getHeight() const
Get image height.
Definition: DBaseImage.h:85
Main Image class.
Definition: DImage.hpp:57
lineType getPixels() const
Get the pixels as a 1D array.
Definition: DImage.hpp:105
Definition: FastIncompletePathOpening.hpp:66
RES_T parsimoniousPathOpening(Image< T > &imIn, int Size, int tolerance, int step, bool rebuild, Image< T > &imOut)
parsimoniousPathOpening
Definition: FastIncompletePathOpening.hpp:664
RES_T fill(Image< T > &imOut, const T &value)
fill() - Fill an image with a given value.
Definition: DImageArith.hpp:1456
RES_T geoBuild(const Image< T > &imIn, const Image< T > &imMask, Image< T > &imOut, const StrElt &se=DEFAULT_SE)
geoBuild() - Geodesic Reconstruction
Definition: DMorphoGeodesic.hpp:144