72 const int &iterations,
74 const DT *inputLabels,
76 TT *triangulation)
const {
81 grayscale, inputLabels, pivotLabel,
84 std::array<int, 2> ops{};
88 }
else if(mode == 3) {
92 this->
printErr(
"Invalid morphological operation requested");
96 std::vector<DT> tmp(triangulation->getNumberOfVertices());
98 tmp.data(), ops[0], iterations, grayscale, inputLabels, pivotLabel,
104 grayscale, tmp.data(), pivotLabel,
116 const int &iterations,
117 const bool grayscale,
118 const DT *inputLabels,
119 const DT &pivotLabel,
120 TT *triangulation)
const {
122 SimplexId const nVertices = triangulation->getNumberOfVertices();
124 std::vector<DT> temp;
127 this->
printMsg(
"Allocating temporary memory", 0, 0, this->threadNumber_,
129 temp.resize(nVertices);
131 this->threadNumber_);
134 std::string
const msg = std::string(mode == 0 ?
"Dilating " :
"Eroding ")
135 + std::to_string(iterations) +
"x value "
136 + std::to_string(pivotLabel);
141 for(
int it = 0; it < iterations; it++) {
143 const DT *source = it == 0 ? inputLabels
144 : (iterations + it) % 2 == 0 ? outputLabels
146 DT *target = (iterations + it) % 2 == 0 ? temp.data() : outputLabels;
153#ifdef TTK_ENABLE_OPENMP
154#pragma omp parallel for num_threads(this->threadNumber_)
156 for(
SimplexId i = 0; i < nVertices; i++) {
158 target[i] = source[i];
161 if(source[i] != pivotLabel) {
164 = triangulation->getVertexNeighborNumber(i);
166 for(
SimplexId n = 0; n < nNeighbors; n++) {
167 triangulation->getVertexNeighbor(i, n, nIndex);
168 if(source[nIndex] == pivotLabel) {
169 target[i] = source[nIndex];
176 const DT minLabel = std::numeric_limits<DT>::min();
178#ifdef TTK_ENABLE_OPENMP
179#pragma omp parallel for num_threads(this->threadNumber_)
181 for(
SimplexId i = 0; i < nVertices; i++) {
183 target[i] = source[i];
186 if(source[i] == pivotLabel) {
189 = triangulation->getVertexNeighborNumber(i);
191 DT maxNeighborLabel = minLabel;
192 for(
SimplexId n = 0; n < nNeighbors; n++) {
193 triangulation->getVertexNeighbor(i, n, nIndex);
194 if(source[nIndex] != pivotLabel
195 && maxNeighborLabel < source[nIndex]) {
196 maxNeighborLabel = source[nIndex];
199 if(maxNeighborLabel != minLabel)
200 target[i] = maxNeighborLabel;
207#ifdef TTK_ENABLE_OPENMP
208#pragma omp parallel for num_threads(this->threadNumber_)
210 for(
SimplexId i = 0; i < nVertices; i++) {
212 target[i] = source[i];
213 const auto nNeighs = triangulation->getVertexNeighborNumber(i);
216 triangulation->getVertexNeighbor(i, n, neigh);
217 target[i] = std::max(target[i], source[neigh]);
221#ifdef TTK_ENABLE_OPENMP
222#pragma omp parallel for num_threads(this->threadNumber_)
224 for(
SimplexId i = 0; i < nVertices; i++) {
226 target[i] = source[i];
227 const auto nNeighs = triangulation->getVertexNeighborNumber(i);
230 triangulation->getVertexNeighbor(i, n, neigh);
231 target[i] = std::min(target[i], source[neigh]);