| 153 | // - DT is the destination type, the data type of the output tensor in dstVec |
| 154 | template<typename ST, typename DT> |
| 155 | void Label(RawBufferType &dstVec, const RawBufferType &srcVec, const long4_16a &dstStrides, const long4_16a &srcStrides, |
| 156 | const long4_16a &shape) |
| 157 | { |
| 158 | // Use a temporary NDHW tensor stored in tmpVec to set elements already labeled, initially zeroes (all unlabeled) |
| 159 | RawBufferType tmpVec(shape.x * shape.y * shape.z * shape.w, 0); |
| 160 | |
| 161 | // The temporary tensor is packed and each element is a single byte, thus: |
| 162 | long4_16a tmpStrides{shape.y * shape.z * shape.w, shape.z * shape.w, shape.w, 1}; |
| 163 | |
| 164 | // For all elements in input tensor |
| 165 | for (long x = 0; x < shape.x; ++x) |
| 166 | { |
| 167 | for (long y = 0; y < shape.y; ++y) |
| 168 | { |
| 169 | for (long z = 0; z < shape.z; ++z) |
| 170 | { |
| 171 | for (long w = 0; w < shape.w; ++w) |
| 172 | { |
| 173 | long4_16a curCoord{x, y, z, w}; |
| 174 | |
| 175 | if (util::ValueAt<U8>(tmpVec, tmpStrides, curCoord) == 1) |
| 176 | { |
| 177 | continue; // The element was already labeled, skip it |
| 178 | } |
| 179 | |
| 180 | // Get current value from input tensor and set label as a 1D flattened (global) position |
| 181 | ST value = util::ValueAt<ST>(srcVec, srcStrides, curCoord); |
| 182 | DT label = y * dstStrides.y / sizeof(DT) + z * dstStrides.z / sizeof(DT) + w; |
| 183 | |
| 184 | // Recursively call to label component |
| 185 | LabelComponent(tmpVec, dstVec, srcVec, tmpStrides, dstStrides, srcStrides, shape, curCoord, value, |
| 186 | label); |
| 187 | } |
| 188 | } |
| 189 | } |
| 190 | } |
| 191 | } |
| 192 | |
| 193 | // Replace labels assigned to regions marked as background in source, and fix a potential region labeled with |
| 194 | // background label in destination by another label (since background label is a reserved label) |
nothing calls this directly
no test coverage detected