连接3D图像中的组件及其索引

时间:2014-05-22 04:20:09

标签: 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”是图像,“索引”向量存储各个分量中的点的索引。此代码可以正常工作以查找最大的连接组件,但它没有正确找到所有其他组件。我将其输出与matlab函数“bwlabeln”的输出进行比较。

请检查此代码,如果我遗漏了某些内容,请告诉我。

1 个答案:

答案 0 :(得分:2)

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)

将来,您可能希望使用&#34;迭代器模式&#34;避免这个错误。