void ImageUtility3::ComputeCDConvex(Image3<int>& image) { int const dim0 = image.GetDimension(0); int const dim1 = image.GetDimension(1); int const dim2 = image.GetDimension(2); Image3<int> temp = image; int i0, i1, i2; for (i1 = 0; i1 < dim1; ++i1) { for (i0 = 0; i0 < dim0; ++i0) { int i2min; for (i2min = 0; i2min < dim2; ++i2min) { if ((temp(i0, i1, i2min) & 1) == 0) { temp(i0, i1, i2min) |= 2; } else { break; } } if (i2min < dim2) { int i2max; for (i2max = dim2 - 1; i2max >= i2min; --i2max) { if ((temp(i0, i1, i2max) & 1) == 0) { temp(i0, i1, i2max) |= 2; } else { break; } } } } } for (i2 = 0; i2 < dim2; ++i2) { for (i0 = 0; i0 < dim0; ++i0) { int i1min; for (i1min = 0; i1min < dim1; ++i1min) { if ((temp(i0, i1min, i2) & 1) == 0) { temp(i0, i1min, i2) |= 2; } else { break; } } if (i1min < dim1) { int i1max; for (i1max = dim1 - 1; i1max >= i1min; --i1max) { if ((temp(i0, i1max, i2) & 1) == 0) { temp(i0, i1max, i2) |= 2; } else { break; } } } } } for (i2 = 0; i2 < dim2; ++i2) { for (i1 = 0; i1 < dim1; ++i1) { int i0min; for (i0min = 0; i0min < dim0; ++i0min) { if ((temp(i0min, i1, i2) & 1) == 0) { temp(i0min, i1, i2) |= 2; } else { break; } } if (i0min < dim0) { int i0max; for (i0max = dim0 - 1; i0max >= i0min; --i0max) { if ((temp(i0max, i1, i2) & 1) == 0) { temp(i0max, i1, i2) |= 2; } else { break; } } } } } for (size_t i = 0; i < image.GetNumPixels(); ++i) { image[i] = (temp[i] & 2 ? 0 : 1); } }
void ImageUtility3::GetComponents(int numNeighbors, int const* delta, Image3<int>& image, std::vector<std::vector<size_t>>& components) { size_t const numVoxels = image.GetNumPixels(); int* numElements = new int[numVoxels]; size_t* vstack = new size_t[numVoxels]; size_t i, numComponents = 0; int label = 2; for (i = 0; i < numVoxels; ++i) { if (image[i] == 1) { int top = -1; vstack[++top] = i; int& count = numElements[numComponents + 1]; count = 0; while (top >= 0) { size_t v = vstack[top]; image[v] = -1; int j; for (j = 0; j < numNeighbors; ++j) { size_t adj = v + delta[j]; if (image[adj] == 1) { vstack[++top] = adj; break; } } if (j == numNeighbors) { image[v] = label; ++count; --top; } } ++numComponents; ++label; } } delete[] vstack; if (numComponents > 0) { components.resize(numComponents + 1); for (i = 1; i <= numComponents; ++i) { components[i].resize(numElements[i]); numElements[i] = 0; } for (i = 0; i < numVoxels; ++i) { int value = image[i]; if (value != 0) { // Labels started at 2 to support the depth-first search, // so they need to be decremented for the correct labels. image[i] = --value; components[value][numElements[value]] = i; ++numElements[value]; } } } delete[] numElements; }