30 #ifndef _D_MORPHO_ARROW_HPP
31 #define _D_MORPHO_ARROW_HPP
33 #include "DMorphImageOperations.hpp"
34 #include "DMorphoHierarQ.hpp"
44 template <
class T_in,
class lineFunction_T,
class T_out = T_in>
57 typedef typename ImDtTypes<T_out>::lineType lineOutType;
58 typedef typename ImDtTypes<T_out>::sliceType sliceOutType;
59 typedef typename ImDtTypes<T_out>::volType volOutType;
62 T_in border = numeric_limits<T_in>::min(),
71 template <
class T_in,
class lineFunction_T,
class T_out>
73 const imageInType &imIn, imageOutType &imOut,
const StrElt &se)
75 ASSERT_ALLOCATED(&imIn);
76 ASSERT_SAME_SIZE(&imIn, &imOut);
78 if ((
void *) &imIn == (
void *) &imOut) {
80 return _exec_single(tmpIm, imOut, se);
83 if (!areAllocated(&imIn, &imOut, NULL))
84 return RES_ERR_BAD_ALLOCATION;
86 UINT sePtsNumber = se.points.size();
90 size_t nSlices = imIn.getSliceCount();
91 size_t nLines = imIn.getHeight();
93 this->lineLen = imIn.getWidth();
95 volInType srcSlices = imIn.getSlices();
96 volOutType destSlices = imOut.getSlices();
98 int nthreads = Core::getInstance()->getNumberOfThreads();
99 typename ImDtTypes<T_in>::vectorType vec(this->lineLen);
100 typename ImDtTypes<T_in>::matrixType bufsIn(
101 nthreads,
typename ImDtTypes<T_in>::vectorType(this->lineLen));
102 typename ImDtTypes<T_out>::matrixType bufsOut(
103 nthreads,
typename ImDtTypes<T_out>::vectorType(this->lineLen));
107 for (
size_t s = 0; s < nSlices; s++) {
108 lineInType * srcLines = srcSlices[s];
109 lineOutType *destLines = destSlices[s];
112 #pragma omp parallel num_threads(nthreads)
115 bool oddSe = se.odd, oddLine = 0;
118 lineFunction_T arrowLineFunction;
123 tid = omp_get_thread_num();
125 lineInType tmpBuf = bufsIn[tid].data();
126 lineOutType tmpBuf2 = bufsOut[tid].data();
131 for (l = 0; l < nLines; l++) {
132 lineInType lineIn = srcLines[l];
133 lineOutType lineOut = destLines[l];
135 oddLine = oddSe && l % 2;
137 fillLine<T_out>(tmpBuf2, this->lineLen, T_out(0));
139 for (UINT p = 0; p < sePtsNumber; p++) {
140 y = l + se.points[p].y;
141 x = -se.points[p].x - (oddLine && (y + 1) % 2);
142 z = s + se.points[p].z;
144 arrowLineFunction.trueVal = (1UL << p);
145 this->_extract_translated_line(&imIn, x, y, z, tmpBuf);
146 arrowLineFunction._exec(lineIn, tmpBuf, this->lineLen, tmpBuf2);
148 copyLine<T_out>(tmpBuf2, this->lineLen, lineOut);
158 template <
class T_in,
class T_out>
159 RES_T arrowLow(
const Image<T_in> &imIn, Image<T_out> &imOut,
160 const StrElt &se = DEFAULT_SE,
161 T_in borderValue = numeric_limits<T_in>::min())
163 unaryMorphArrowImageFunction<T_in, lowSupLine<T_in, T_out>, T_out> iFunc(
165 return iFunc(imIn, imOut, se);
168 template <
class T_in,
class T_out>
169 RES_T arrowLowOrEqu(
const Image<T_in> &imIn, Image<T_out> &imOut,
170 const StrElt &se = DEFAULT_SE,
171 T_in borderValue = numeric_limits<T_in>::min())
173 unaryMorphArrowImageFunction<T_in, lowOrEquSupLine<T_in, T_out>, T_out>
175 return iFunc(imIn, imOut, se);
178 template <
class T_in,
class T_out>
179 RES_T arrowGrt(
const Image<T_in> &imIn, Image<T_out> &imOut,
180 const StrElt &se = DEFAULT_SE,
181 T_in borderValue = numeric_limits<T_in>::min())
183 unaryMorphArrowImageFunction<T_in, grtSupLine<T_in, T_out>, T_out> iFunc(
185 return iFunc(imIn, imOut, se);
188 template <
class T_in,
class T_out>
189 RES_T arrowGrtOrEqu(
const Image<T_in> &imIn, Image<T_out> &imOut,
190 const StrElt &se = DEFAULT_SE,
191 T_in borderValue = numeric_limits<T_in>::min())
193 unaryMorphArrowImageFunction<T_in, grtOrEquSupLine<T_in, T_out>, T_out>
195 return iFunc(imIn, imOut, se);
198 template <
class T_in,
class T_out>
199 RES_T arrowEqu(
const Image<T_in> &imIn, Image<T_out> &imOut,
200 const StrElt &se = DEFAULT_SE,
201 T_in borderValue = numeric_limits<T_in>::min())
203 unaryMorphArrowImageFunction<T_in, equSupLine<T_in, T_out>, T_out> iFunc(
205 return iFunc(imIn, imOut, se);
217 template <
class T_in,
class T_out>
220 T_in borderValue = numeric_limits<T_in>::min())
222 if (strcmp(operation,
"==") == 0)
223 return arrowEqu(imIn, imOut, se, borderValue);
224 else if (strcmp(operation,
">") == 0)
225 return arrowGrt(imIn, imOut, se, borderValue);
226 else if (strcmp(operation,
">=") == 0)
227 return arrowGrtOrEqu(imIn, imOut, se, borderValue);
228 else if (strcmp(operation,
"<") == 0)
229 return arrowLow(imIn, imOut, se, borderValue);
230 else if (strcmp(operation,
"<=") == 0)
231 return arrowLowOrEqu(imIn, imOut, se, borderValue);
241 template <
class arrowT,
class statutT,
class outT,
242 class containerType = STD_Queue<size_t>>
248 virtual bool testAndAssign(statutT & , outT &pO)
250 if (pO != propagationValue) {
252 pO = propagationValue;
259 outT propagationValue;
264 typedef typename arrowIT::lineType arrowLT;
265 typedef typename statutIT::lineType statutLT;
266 typedef typename outIT::lineType outLT;
280 outLT outP = imOut.getPixels();
285 UINT sePtsNumber = se.points.size();
287 size_t x, x0, y, y0, z, z0;
296 z0 = o / (size[1] * size[0]);
297 y0 = (o % (size[1] * size[0])) / size[0];
299 oddLine = se.odd && y0 % 2;
301 for (UINT p = 0; p < sePtsNumber; ++p) {
303 if (arrowP[o] &
arrow) {
304 x = x0 + se.points[p].x;
305 y = y0 + se.points[p].y;
306 z = z0 + se.points[p].z;
309 nb_o = x + y * size[0] + z * size[1] * size[0];
310 if (x < size[0] && y < size[1] && z < size[2])
311 if (testAndAssign(statutP[nb_o], outP[nb_o]))
316 }
while (!q.empty());
321 const StrElt &se,
const size_t &offset)
323 return _exec(imArrow, imStatut, imOut, se, offset);
326 const StrElt &se,
const size_t &offset)
328 return _exec(imArrow, imOut, imOut, se, offset);
332 template <
class T1,
class T2,
class T_out = T2>
338 T_out trueVal, falseVal;
341 typedef typename parentClass::lineType1 lineType1;
342 typedef typename parentClass::lineType2 lineType2;
343 typedef typename parentClass::lineOutType lineOutType;
345 inline void operator()(
const lineType1 lIn1,
const lineType2 lIn2,
346 const size_t size, lineOutType lOut)
348 return _exec(lIn1, lIn2, size, lOut);
350 virtual void _exec(
const lineType1 lIn1,
const lineType2 lIn2,
351 const size_t size, lineOutType lOut)
353 T_out _trueVal(trueVal), _falseVal(falseVal);
355 for (
size_t i = 0; i < size; i++) {
356 lOut[i] += (lIn1[i] == lIn2[i]) ? _trueVal : _falseVal;
361 template <
class T,
class arrowT = UINT8>
368 typedef typename imageInType::lineType lineInType;
369 typedef typename imageInType::lineType sliceInType;
370 typedef typename imageInType::volType volInType;
373 typedef typename imageArrowType::lineType lineArrowType;
374 typedef typename imageArrowType::sliceType sliceArrowType;
375 typedef typename imageArrowType::volType volArrowType;
390 template <
class T,
class arrowT>
392 imageArrowType &
arrow,
395 ASSERT_ALLOCATED(&in, &
arrow);
396 ASSERT_SAME_SIZE(&in, &
arrow);
398 if (!areAllocated(&in, &
arrow, NULL))
399 return RES_ERR_BAD_ALLOCATION;
401 UINT sePtsNumber = se.points.size();
403 if (sePtsNumber == 0)
406 size_t nSlices = in.getSliceCount();
407 size_t nLines = in.getHeight();
409 lineLen = in.getWidth();
411 volInType srcSlices = in.getSlices();
412 volArrowType destSlices =
arrow.getSlices();
413 lineInType * srcLines;
414 lineArrowType *destLines;
416 bool oddSe = se.odd, oddLine = 0;
419 #pragma omp parallel private(oddLine)
429 testLine<T, arrowT>
test;
436 lineArrowType lineArrow;
439 for (
size_t s = 0; s < nSlices; ++s) {
440 srcLines = srcSlices[s];
441 destLines = destSlices[s];
446 for (
size_t l = 0; l < nLines; ++l) {
447 oddLine = oddSe && l % 2;
449 lineIn = srcLines[l];
450 lineArrow = destLines[l];
453 copyLine<T>(lineIn, lineLen, minBuf);
455 for (UINT p = 0; p < sePtsNumber; ++p) {
456 y = l + se.points[p].y;
457 x = -se.points[p].x - (oddLine && (y + 1) % 2);
458 z = s + se.points[p].z;
460 _equSup.trueVal = (1UL << p);
462 if (z >= nSlices || y >= nLines)
463 copyLine<T>(borderBuf, lineLen, cpBuf);
465 shiftLine<T>(srcLines[y], x, lineLen, cpBuf, borderValue);
467 low._exec(cpBuf, minBuf, lineLen, flagBuf);
468 inf._exec(cpBuf, minBuf, lineLen, minBuf);
469 test._exec(flagBuf, nullBuf, lineArrow, lineLen, lineArrow);
470 _equSup._exec(cpBuf, minBuf, lineLen, lineArrow);
479 template <
class T,
class arrowT>
480 RES_T arrowMin(
const Image<T> &im, Image<arrowT> &
arrow,
const StrElt &se,
481 T borderValue = numeric_limits<T>::max())
483 arrowMinFunction<T, arrowT> iFunc(borderValue);
484 return iFunc(im,
arrow, se);
487 template <
class T,
class arrowT = UINT8>
493 typedef typename imageInType::lineType lineInType;
494 typedef typename imageInType::lineType sliceInType;
495 typedef typename imageInType::volType volInType;
497 typedef typename imageArrowType::lineType lineArrowType;
498 typedef typename imageArrowType::sliceType sliceArrowType;
499 typedef typename imageArrowType::volType volArrowType;
504 borderValue = border;
515 template <
class T,
class arrowT>
517 imageArrowType &
arrow,
520 ASSERT_ALLOCATED(&in, &
arrow);
521 ASSERT_SAME_SIZE(&in, &
arrow);
523 if (!areAllocated(&in, &
arrow, NULL))
524 return RES_ERR_BAD_ALLOCATION;
526 StrElt cpSe = se.noCenter();
528 UINT sePtsNumber = cpSe.
points.size();
530 if (sePtsNumber == 0)
533 size_t nSlices = in.getSliceCount();
534 size_t nLines = in.getHeight();
535 lineLen = in.getWidth();
537 volInType srcSlices = in.getSlices();
538 volArrowType destSlices =
arrow.getSlices();
539 lineInType * srcLines;
540 lineArrowType *destLines;
542 bool oddSe = cpSe.odd, oddLine = 0;
545 #pragma omp parallel private(oddLine)
555 testLine<T, arrowT>
test;
562 equ.falseVal = numeric_limits<T>::max();
565 lineArrowType lineArrow;
568 for (
size_t s = 0; s < nSlices; ++s) {
569 srcLines = srcSlices[s];
570 destLines = destSlices[s];
575 for (
size_t l = 0; l < nLines; ++l) {
576 oddLine = oddSe && l % 2;
578 lineIn = srcLines[l];
579 lineArrow = destLines[l];
582 copyLine<T>(borderBuf, lineLen, minBuf);
584 for (UINT p = 0; p < sePtsNumber; ++p) {
586 x = -cpSe.
points[p].x - (oddLine && (y + 1) % 2);
589 _equSup.trueVal = (1UL << p);
591 if (z >= nSlices || y >= nLines)
592 copyLine<T>(borderBuf, lineLen, cpBuf);
594 shiftLine<T>(srcLines[y], x, lineLen, cpBuf, borderValue);
596 for (i = 0; i < lineLen; ++i)
597 flagBuf[i] = cpBuf[i] >= lineIn[i] ? 255 : 0;
598 for (i = 0; i < lineLen; ++i)
599 cpBuf[i] = flagBuf[i] ? cpBuf[i] : borderBuf[i];
601 low._exec(cpBuf, minBuf, lineLen, flagBuf);
602 inf._exec(cpBuf, minBuf, lineLen, minBuf);
603 test._exec(flagBuf, nullBuf, lineArrow, lineLen, lineArrow);
604 _equSup._exec(cpBuf, minBuf, lineLen, lineArrow);
614 RES_T arrowMinStep(
const Image<T> &im, Image<T> &
arrow,
const StrElt &se,
615 T borderValue = numeric_limits<T>::max())
617 arrowMinStepFunction<T, T> iFunc(borderValue);
618 return iFunc(im,
arrow, se);
void getSize(size_t *w, size_t *h, size_t *d) const
Get image size.
Definition: DBaseImage.h:118
lineType getPixels() const
Get the pixels as a 1D array.
Definition: DImage.hpp:105
Base morpho operator class.
Definition: DMorphImageOperations.hpp:58
Definition: DMorphImageOperations.hpp:145
Base structuring element.
Definition: DStructuringElement.h:68
vector< IntPoint > points
List of neighbor points.
Definition: DStructuringElement.h:201
Definition: DMorphoArrow.hpp:363
Definition: DMorphoArrow.hpp:489
Propagation Functor on a Arrow Image.
Definition: DMorphoArrow.hpp:244
Definition: DMorphoArrow.hpp:47
RES_T low(const Image< T > &imIn1, const Image< T > &imIn2, Image< T > &imOut)
low() - Lower operator
Definition: DImageArith.hpp:604
RES_T inf(const Image< T > &imIn1, const Image< T > &imIn2, Image< T > &imOut)
inf() - Inf of two images
Definition: DImageArith.hpp:305
RES_T equ(const Image< T > &imIn1, const Image< T > &imIn2, Image< T > &imOut)
equ() - Equality operator (pixel by pixel)
Definition: DImageArith.hpp:366
RES_T test(const Image< T1 > &imIn, const Image< T2 > &imInT, const Image< T2 > &imInF, Image< T2 > &imOut)
test() - Test
Definition: DImageArith.hpp:1109
RES_T arrow(const Image< T_in > &imIn, const char *operation, Image< T_out > &imOut, const StrElt &se=DEFAULT_SE, T_in borderValue=numeric_limits< T_in >::min())
Arrow operator.
Definition: DMorphoArrow.hpp:218
Definition: DTypes.hpp:88
Definition: DBaseLineOperations.hpp:110
Definition: DMorphoArrow.hpp:333
Definition: DBaseImageOperations.hxx:39