c++ - 3D 图像中的连通分量及其索引

标签 c++ c matlab image-processing

<分区>

我已经以这种方式在 3D 图像中实现了连接组件。

int isSafe(unsigned char *M, int row, int col, int idz, bool *visited, int *size)
{
   return (row >= 0) && (row < size[0]) && (col >= 0) && (col < size[1]) && (idz >= 0) && (idz < size[2]) &&
       (M[idz * size[0]*size[1] + row*size[0] + col] && !visited[idz*size[0]*size[1] + row*size[0] + col]); 
}

void DFS3D(unsigned char *M, bool *visited, stack<int> &s1, stack<int> &s2, stack<int> &s3, vector < vector <int>> &index, int *size)
{
   int count_components_elements = 0;
   vector <int> indexes;

   while(!s1.empty() && !s2.empty() && !s3.empty())
   {
      int row, col, idz;
      row = s1.top();
      s1.pop();
      col = s2.top();
      s2.pop();
      idz = s3.top();
      s3.pop();

      //add index positions to array or vector
      indexes.push_back(count_components_elements);
      indexes.at(count_components_elements)= (idz*size[0]*size[1] + (row)*size[0] + col);
      ++count_components_elements;

      static int rowNbr[] = {-1, 0, 1,  0, 0,  0};
      static int colNbr[] = { 0, 1, 0, -1, 0,  0};
      static int zNbr[] = { 0, 0, 0,  0, 1, -1};

      visited[idz*size[0]*size[1] + row*size[0] + col ] = true;

      for   (int k = 0; k < 6; ++k)
      {         
         if (isSafe(M, row + rowNbr[k], col + colNbr[k], idz + zNbr[k], visited, size) )
         {              
             {
                s1.push(row + rowNbr[k]);
                s2.push(col + colNbr[k]);
                s3.push(idz + zNbr[k]);
                visited[(idz + zNbr[k])*size[0]*size[1] + (row + rowNbr[k])*size[0] + col + colNbr[k]] = true;
             }
         }
     }
 }
 index.push_back(indexes);
}


void FindLargestComponent_3D(unsigned char *M, vector < vector <int>> &index, int *size)
{
   stack <int> s1;
   stack <int> s2;
   stack <int> s3;
   bool *visited = new bool[size[0]*size[1]*size[2]];   
   memset(visited, 0, sizeof(bool)*size[0]*size[1]*size[2]);    

   for (int k = 0; k < 1; ++k)
   {
      for (int i = 0; i < size[0]; ++i)
      {
         for (int j = 0; j < size[1]; ++j)
         {
            if (M[k*size[0]*size[1] + i*size[0] + j ] && !visited[k*size[0]*size[1] + i*size[0] + j ]) 
            {                   
                s1.push(i);
                s2.push(j);
                s3.push(k);
                DFS3D(M, visited, s1, s2, s3, index, size);                             
            }
         }
    }
 }  
 delete [] visited;
}

其中“M”是图像,“索引” vector 存储各个组件中点的索引。此代码可以很好地找到最大的连通分量,但无法正确找到所有其他分量。我正在将它的输出与 matlab 函数“bwlabeln”的输出进行比较。

请检查此代码,如果我遗漏了什么请告诉我。

最佳答案

在您的 FindLargestComponent_3D 函数中,您迭代 kij 变量:

for (int k = 0; k < 1; ++k) // Pay attention to this line!!
{
    for (int i = 0; i < size[0]; ++i)
    {
        for (int j = 0; j < size[1]; ++j)
        {

这将搜索限制为接触平面 k=1 的连通分量。较小的连通分量不太可能在 k=1 平面中包含元素,因此它们也不太可能被发现。

要遍历 k 维中的所有平面,请将这些行中的第一行替换为:

for (int k = 0; k < size[2]; ++k)

将来,您可能希望使用“迭代器模式”来避免这种错误。

关于c++ - 3D 图像中的连通分量及其索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23797754/

相关文章:

matlab - 如何将绘图保存到 PDF 文件中而没有大的边距

Matlab - 将向量与 setdiff 进行比较,同时忽略低于 eps 的精度

c++ - 在旧版本的 boost 中使用 recursive_directory_iterator ?

c++ - 使用自己的继承类初始化 vtkSmartPointer

c++ - 维吉尼亚密码

c - fputs 与 fprintf 和 double

c - 增加指向结构的指针

c++ - vector 未正确填充

c++ - 表示纪元之前的日期

matlab - MATLAB 中 imfreehand 工具的采样率?