52 #ifndef __FAST_PIPATH_OPENING_HPP__
53 #define __FAST_PIPATH_OPENING_HPP__
56 #include "Morpho/include/DMorpho.h"
68 bool MIRROR_BORDERS =
true;
73 MIRROR_BORDERS =
true;
92 off_t HWidth = numeric_limits<T>::max();
94 for (ii = 0; ii < HWidth; ii++) {
105 RES_T rank_filter_indx(T *x, off_t *indx,
int n,
int SE,
int r, T *y)
108 uint64_t HWidth = numeric_limits<T>::max();
110 T *H =
new T[HWidth]();
113 off_t *indx_pad =
new off_t[n + 2 * SE]();
114 memcpy(indx_pad + SE, indx, n *
sizeof(off_t));
116 if (!MIRROR_BORDERS) {
118 for (off_t ii = 0; ii < SE; ii++) {
119 indx_pad[ii] = indx[0];
120 indx_pad[n + SE + ii] = indx[n - 1];
124 for (off_t ii = 0; ii < SE; ii++) {
128 indx_pad[ix] = indx[iy];
134 indx_pad[ix] = indx[iy];
139 for (off_t ii = 0; ii < SE; ii++) {
141 H[x[indx_pad[ii + SE - SE / 2]]] += 1;
145 for (off_t ii = 0; ii < n - 1; ii++) {
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);
161 RES_T conj_dilation(T *x,
int n,
int SE, T *y)
163 uint64_t HWidth = numeric_limits<T>::max();
164 T *H =
new T[HWidth]();
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++) {
170 x_pad[n + SE + i] = x[n - 1];
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);
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);
193 RES_T rank_open(T *x, off_t *indx,
int n,
int SE,
int r, T *y)
198 (void ) rank_filter_indx(x, indx, n, SE, r, xi);
199 (void ) conj_dilation(xi, n, SE, dxi);
201 for (off_t ii = 0; ii < n; ii++)
202 y[indx[ii]] = max(y[indx[ii]], min(x[indx[ii]], dxi[ii]));
215 RES_T doIt(
Image<T> &imIn,
int size,
int tolerance,
int step,
218 ASSERT_ALLOCATED(&imIn, &imOut);
219 ASSERT_SAME_SIZE(&imIn, &imOut);
221 ASSERT(tolerance >= 0);
231 typename ImDtTypes<T>::lineType bufferIn = imIn.
getPixels();
232 typename ImDtTypes<T>::lineType bufferOut = imOut.getPixels();
236 off_t *indx =
new off_t[W + H]();
240 for (j = 0; j < H; j += step) {
247 for (i = 1; i < W; i++) {
248 F = bufferIn[i + whichLine * W];
249 indx[i] = i + whichLine * W;
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;
258 if (whichLine + 1 < H && F < bufferIn[i + (whichLine + 1) * W]) {
259 indx[i] = i + (whichLine + 1) * W;
265 rank_open(bufferIn, indx, W, size, tolerance, bufferOut);
270 for (j = 0; j < H; j += step) {
274 indx[W - 1] = W - 1 + j * W;
276 for (i = W - 2; i >= 0; i--) {
277 F = bufferIn[i + whichLine * W];
278 indx[i] = i + whichLine * W;
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;
287 if (whichLine + 1 < H && F < bufferIn[i + (whichLine + 1) * W]) {
288 indx[i] = i + (whichLine + 1) * W;
294 rank_open(bufferIn, indx, W, size, tolerance, bufferOut);
299 for (i = 0; i < W; i += step) {
305 for (j = 1; j < H; j++) {
306 F = bufferIn[whichLine + j * W];
307 indx[j] = whichLine + j * W;
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;
316 if (whichLine + 1 < W && F < bufferIn[whichLine + 1 + j * W]) {
317 indx[j] = whichLine + 1 + j * W;
323 rank_open(bufferIn, indx, H, size, tolerance, bufferOut);
328 for (i = 0; i < W; i += step) {
332 indx[H - 1] = i + (H - 1) * W;
334 for (j = H - 2; j >= 0; j--) {
335 F = bufferIn[whichLine + j * W];
336 indx[j] = whichLine + j * W;
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;
345 if (whichLine + 1 < W && F < bufferIn[whichLine + 1 + j * W]) {
346 indx[j] = whichLine + 1 + j * W;
352 rank_open(bufferIn, indx, H, size, tolerance, bufferOut);
357 for (j = 1; j < H; j += step) {
367 F = bufferIn[i + 1 + (whichLine - 1) * W];
368 indx[cnt] = i + 1 + (whichLine - 1) * W;
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;
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;
389 }
while (i <= W - 2 && whichLine >= 1);
391 rank_open(bufferIn, indx, cnt, size, tolerance, bufferOut);
394 for (i = 0; i < W - 1; i += step) {
398 indx[0] = i + (H - 1) * W;
404 F = bufferIn[whichLine + 1 + (j - 1) * W];
405 indx[cnt] = whichLine + 1 + (j - 1) * W;
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;
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;
426 }
while (whichLine <= W - 2 && j >= 1);
427 rank_open(bufferIn, indx, cnt, size, tolerance, bufferOut);
432 for (j = 0; j < H - 1; j += step) {
436 indx[0] = W - 1 + j * W;
441 F = bufferIn[i - 1 + (whichLine + 1) * W];
442 indx[cnt] = i - 1 + (whichLine + 1) * W;
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;
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;
463 }
while (i >= 1 && whichLine <= H - 2);
464 rank_open(bufferIn, indx, cnt, size, tolerance, bufferOut);
467 for (i = 1; i < W; i += step) {
477 F = bufferIn[whichLine - 1 + (j + 1) * W];
478 indx[cnt] = whichLine - 1 + (j + 1) * W;
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;
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;
499 }
while (whichLine >= 1 && j <= H - 2);
500 rank_open(bufferIn, indx, cnt, size, tolerance, bufferOut);
505 for (j = 0; j < H - 1; j += step) {
515 F = bufferIn[i + 1 + (whichLine + 1) * W];
516 indx[cnt] = i + 1 + (whichLine + 1) * W;
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;
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;
537 }
while (i <= W - 2 && whichLine <= H - 2);
538 rank_open(bufferIn, indx, cnt, size, tolerance, bufferOut);
541 for (i = 0; i < W - 1; i += step) {
551 F = bufferIn[whichLine + 1 + (j + 1) * W];
552 indx[cnt] = whichLine + 1 + (j + 1) * W;
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;
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;
573 }
while (whichLine <= W - 2 && j <= H - 2);
574 rank_open(bufferIn, indx, cnt, size, tolerance, bufferOut);
579 for (j = 1; j < H; j += step) {
583 indx[0] = W - 1 + j * W;
589 F = bufferIn[i - 1 + (whichLine - 1) * W];
590 indx[cnt] = i - 1 + (whichLine - 1) * W;
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;
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;
611 }
while (i >= 1 && whichLine >= 1);
612 rank_open(bufferIn, indx, cnt, size, tolerance, bufferOut);
615 for (i = 1; i < W; i += step) {
619 indx[0] = i + (H - 1) * W;
625 F = bufferIn[whichLine - 1 + (j - 1) * W];
626 indx[cnt] = whichLine - 1 + (j - 1) * W;
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;
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;
647 }
while (whichLine >= 1 && j >= 1);
648 rank_open(bufferIn, indx, cnt, size, tolerance, bufferOut);
665 int tolerance,
int step,
672 res = pOpen.doIt(imIn, Size, tolerance, step, imOut);
674 ERR_MSG(
"Error doint path opening");
682 ERR_MSG(
"Error while rebuilding after Path Opening");
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