# Change ConnectedComponentImageFilter Mask Shape

**URL:** <https://discourse.itk.org/t/change-connectedcomponentimagefilter-mask-shape/498>\
**Category:** Beginner Questions\
**Created:** [December 11, 2017, 8:15am UTC](https://discourse.itk.org/t/change-connectedcomponentimagefilter-mask-shape/498 "2017-12-11T08:15:04Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![arwtyxouymz](https://discourse.itk.org/user_avatar/discourse.itk.org/arwtyxouymz/32/379_2.png) [@arwtyxouymz](https://discourse.itk.org/u/arwtyxouymz)\
**Post date:** [December 11, 2017, 8:15am UTC](https://discourse.itk.org/t/change-connectedcomponentimagefilter-mask-shape/498/1 "2017-12-11T08:15:05Z")

</div>

Hi,  
I’m a newer of itk.

I use ConnectedComponentImageFilter to label my image,  
Default mask shape is probably 4 neighborhood, but i want to change the shape to 8 or 16 neighborhood.

How should i do?  
Please help me!

---

<div class="post-metadata">

**Author:** ![dzenanz](https://discourse.itk.org/user_avatar/discourse.itk.org/dzenanz/32/1093_2.png) [@dzenanz](https://discourse.itk.org/u/dzenanz)\
**Post date:** [December 11, 2017, 2:00pm UTC](https://discourse.itk.org/t/change-connectedcomponentimagefilter-mask-shape/498/2 "2017-12-11T14:00:36Z")

</div>

[SetFullyConnected](https://itk.org/Doxygen/html/classitk_1_1ConnectedComponentImageFilter.html#a78d6bf6b78490a0e48554fbe89977d18) is probably what you want.

---

<div class="post-metadata">

**Author:** ![arwtyxouymz](https://discourse.itk.org/user_avatar/discourse.itk.org/arwtyxouymz/32/379_2.png) [@arwtyxouymz](https://discourse.itk.org/u/arwtyxouymz)\
**Post date:** [December 14, 2017, 3:17am UTC](https://discourse.itk.org/t/change-connectedcomponentimagefilter-mask-shape/498/3 "2017-12-14T03:17:22Z")

</div>

Thank you dzenanz!

[SetFullyConnected](https://itk.org/Doxygen/html/classitk_1_1ConnectedComponentImageFilter.html#a78d6bf6b78490a0e48554fbe89977d18) is 3x3 region shape.  
But i want to use 5x5 region shape.

How should i change?

---

<div class="post-metadata">

**Author:** ![tim-evain](https://discourse.itk.org/user_avatar/discourse.itk.org/tim-evain/32/220_2.png) [@tim-evain](https://discourse.itk.org/u/tim-evain)\
**Post date:** [December 14, 2017, 11:16am UTC](https://discourse.itk.org/t/change-connectedcomponentimagefilter-mask-shape/498/4 "2017-12-14T11:16:12Z")

</div>

Hi @arwtyxouymz,

The built-in methods for neighborhood in ITK usually consider only adjacent voxels, i.e. neighborhoods of size 3^ImageDimension on regular grids, which are the ones that are commonly used.  
If you want to use custom neighborhood, you will have to create your own filter.

You can make your own version of the ConnectedComponentImageFilter from the code on GitHub. As this filter uses now an experimental algorithm based on raster lines, I think most of the changes you need to make will be in the [ConnectedComponentAlgorithm.h](https://github.com/InsightSoftwareConsortium/ITK/blob/master/Modules/Core/Common/include/itkConnectedComponentAlgorithm.h) file.

HTH,

Tim

---

<div class="post-metadata">

**Author:** ![blowekamp](https://discourse.itk.org/user_avatar/discourse.itk.org/blowekamp/32/79_2.png) [@blowekamp](https://discourse.itk.org/u/blowekamp)\
**Post date:** [December 14, 2017, 1:45pm UTC](https://discourse.itk.org/t/change-connectedcomponentimagefilter-mask-shape/498/5 "2017-12-14T13:45:04Z")

</div>

If you run a [BinaryDilateImageFilter](https://itk.org/Doxygen/html/classitk_1_1BinaryDilateImageFilter.html) before the ConnectedComponentsImageFilter you can get the effect of the combined region/neighborhood.

---

<div class="post-metadata">

**Author:** ![arwtyxouymz](https://discourse.itk.org/user_avatar/discourse.itk.org/arwtyxouymz/32/379_2.png) [@arwtyxouymz](https://discourse.itk.org/u/arwtyxouymz)\
**Post date:** [December 17, 2017, 6:47am UTC](https://discourse.itk.org/t/change-connectedcomponentimagefilter-mask-shape/498/6 "2017-12-17T06:47:02Z")

</div>

Thank you, @blowekamp

If I use a [BinaryDilateImageFilter](https://itk.org/Doxygen/html/classitk_1_1BinaryDilateImageFilter.html) before the ConnectedComponentImageFilter, will some black pixels change to white pixel?

If so, it’s not what i want to do.  
I don’t want to change the number of white pixel  
The number is same, and I want to check if they are connected or not by larger region.

Do you have any idea?

---

<div class="post-metadata">

**Author:** ![arwtyxouymz](https://discourse.itk.org/user_avatar/discourse.itk.org/arwtyxouymz/32/379_2.png) [@arwtyxouymz](https://discourse.itk.org/u/arwtyxouymz)\
**Post date:** [December 17, 2017, 6:50am UTC](https://discourse.itk.org/t/change-connectedcomponentimagefilter-mask-shape/498/7 "2017-12-17T06:50:35Z")

</div>

Thank you @tim-evain

I’m very sorry to trouble you, but please tell me how should i change [ConnectedComponentAlgorighm.h](https://github.com/InsightSoftwareConsortium/ITK/blob/master/Modules/Core/Common/include/itkConnectedComponentAlgorithm.h).

I just want to change from 3x3 to 5x5.

I’m very sorry…  
please help me.

---

<div class="post-metadata">

**Author:** ![tim-evain](https://discourse.itk.org/user_avatar/discourse.itk.org/tim-evain/32/220_2.png) [@tim-evain](https://discourse.itk.org/u/tim-evain)\
**Post date:** [December 17, 2017, 10:39am UTC](https://discourse.itk.org/t/change-connectedcomponentimagefilter-mask-shape/498/8 "2017-12-17T10:39:36Z")

</div>

For the [algorithm](https://github.com/InsightSoftwareConsortium/ITK/blob/master/Modules/Core/Common/include/itkConnectedComponentAlgorithm.h) file as well as for the [filter](https://github.com/InsightSoftwareConsortium/ITK/blob/master/Modules/Segmentation/ConnectedComponents/include/itkConnectedComponentImageFilter.hxx) one, whenever neighborhood is involved, you should modify the values to get the one you are expecting.  
For example, this means changing the radius from 1 to 2 (i.e. switch from 3x3 to 5x5) in the SetupLineOffsets function, activating offsets with value 2 in setConnectivity\* functions, etc.  
Note that since run-length encoding is used along the first dimension, you may face some trouble if your neighborhood is discontinuous in this direction (i.e. kernels like 1 0 1 0 1).

HTH,

Tim

---

<div class="post-metadata">

**Author:** ![blowekamp](https://discourse.itk.org/user_avatar/discourse.itk.org/blowekamp/32/79_2.png) [@blowekamp](https://discourse.itk.org/u/blowekamp)\
**Post date:** [December 18, 2017, 3:48pm UTC](https://discourse.itk.org/t/change-connectedcomponentimagefilter-mask-shape/498/9 "2017-12-18T15:48:57Z")

</div>

You can just use the original image to mask the output of the combined Dilate/ConnectedComponents.

---

<div class="post-metadata">

**Author:** ![arwtyxouymz](https://discourse.itk.org/user_avatar/discourse.itk.org/arwtyxouymz/32/379_2.png) [@arwtyxouymz](https://discourse.itk.org/u/arwtyxouymz)\
**Post date:** [December 22, 2017, 5:51am UTC](https://discourse.itk.org/t/change-connectedcomponentimagefilter-mask-shape/498/10 "2017-12-22T05:51:23Z")

</div>

Thank you, @tim-evain

I edited SetupLineOffsets in itkConnectedComponentImageFilter.hxx and setConnectivity in itkConnectedComponentAlgorithm.h.

But it doesn’t work.  
I paste my edited code below, can you check it?  
Especially, in itkConnectedComponentAlgorithm.h, because I execute by fullyConnected = true, please check in else statement.

######## itkConnectedComponentImageFilter.hxx ##########

```auto
template< typename TInputImage, typename TOutputImage, typename TMaskImage >
void
ConnectedComponentImageFilter< TInputImage, TOutputImage, TMaskImage >
::SetupLineOffsets(OffsetVec & LineOffsets)
{
  // Create a neighborhood so that we can generate a table of offsets
  // to "previous" line indexes
  // We are going to mis-use the neighborhood iterators to compute the
  // offset for us. All this messing around produces an array of
  // offsets that will be used to index the map
  typename TOutputImage::Pointer output = this->GetOutput();
  typedef Image< OffsetValueType, TOutputImage::ImageDimension - 1 > PretendImageType;
  typedef typename PretendImageType::RegionType::SizeType PretendSizeType;
  typedef typename PretendImageType::RegionType::IndexType PretendIndexType;
  typedef ConstShapedNeighborhoodIterator< PretendImageType > LineNeighborhoodType;

  typename PretendImageType::Pointer fakeImage;
  fakeImage = PretendImageType::New();

  typename PretendImageType::RegionType LineRegion;
  //LineRegion = PretendImageType::RegionType::New();

  OutSizeType OutSize = output->GetRequestedRegion().GetSize();

  PretendSizeType PretendSize;
  // The first dimension has been collapsed
  for ( unsigned int i = 0; i < PretendSize.GetSizeDimension(); i++ )
    {
    // PretendSize[i] = OutSize[i + 1];
    PretendSize[i] = OutSize[i + 2];
    }

  LineRegion.SetSize(PretendSize);
  fakeImage->SetRegions(LineRegion);
  PretendSizeType kernelRadius;
  kernelRadius.Fill(1);
  LineNeighborhoodType lnit(kernelRadius, fakeImage, LineRegion);

  // only activate the indices that are "previous" to the current
  // pixel and face connected (exclude the center pixel from the
  // neighborhood)
  //
  setConnectivityPrevious(&lnit, m_FullyConnected);

  typename LineNeighborhoodType::IndexListType ActiveIndexes;
  ActiveIndexes = lnit.GetActiveIndexList();

  typename LineNeighborhoodType::IndexListType::const_iterator LI;

  PretendIndexType idx = LineRegion.GetIndex();
  OffsetValueType offset = fakeImage->ComputeOffset(idx);

  for ( LI = ActiveIndexes.begin(); LI != ActiveIndexes.end(); LI++ )
    {
    LineOffsets.push_back(fakeImage->ComputeOffset( idx + lnit.GetOffset(*LI) ) - offset);
    }

  // LineOffsets is the thing we wanted.
}

```

######## itkConnectedComponentAlgorithm.h ##########

```auto
template< typename TIterator >
TIterator *
setConnectivity(TIterator *it, bool fullyConnected = false)
{
  typename TIterator::OffsetType offset;
  it->ClearActiveList();
  if ( !fullyConnected )
    {
    // only activate the neighbors that are face connected
    // to the current pixel. do not include the center pixel
    offset.Fill(0);
    for ( unsigned int d = 0; d < TIterator::Dimension; ++d )
      {
      // offset[d] = -1;
      offset[d] = -2;
      it->ActivateOffset(offset);
      // offset[d] = 1;
      offset[d] = 2;
      it->ActivateOffset(offset);
      offset[d] = 0;
      }
    }
  else
    {
    // activate all neighbors that are face+edge+vertex
    // connected to the current pixel. do not include the center pixel
    unsigned int centerIndex = it->GetCenterNeighborhoodIndex();
    // for ( unsigned int d = 0; d < centerIndex * 2 + 1; d++ )
    for ( unsigned int d = 0; d < centerIndex * 4 + 1; d++ )
      {
      offset = it->GetOffset(d);
      it->ActivateOffset(offset);
      }
    offset.Fill(0);
    it->DeactivateOffset(offset);
    }
  return it;
}

```

What is wrong?  
Which part should i change?

please help me…

---

<div class="post-metadata">

**Author:** ![tim-evain](https://discourse.itk.org/user_avatar/discourse.itk.org/tim-evain/32/220_2.png) [@tim-evain](https://discourse.itk.org/u/tim-evain)\
**Post date:** [December 22, 2017, 5:17pm UTC](https://discourse.itk.org/t/change-connectedcomponentimagefilter-mask-shape/498/11 "2017-12-22T17:17:41Z")

</div>

Hi,

There are multiple incorrect modifications that I can see.

> [@arwtyxouymz](#):
>
> ######## itkConnectedComponentImageFilter.hxx ##########
> 
> // The first dimension has been collapsed  
> for ( unsigned int i = 0; i \< PretendSize.GetSizeDimension(); i++ )  
> {  
> // PretendSize[i] = OutSize[i + 1];  
> PretendSize[i] = OutSize[i + 2];  
> }

This doesn’t seem to be about neighborhood, I don’t think you should modify that.

> [@arwtyxouymz](#):
>
> ######## itkConnectedComponentAlgorithm.h ##########  
> setConnectivity(TIterator \*it, bool fullyConnected = false)

I’m not sure this function is called, but setConnectivityPrevious is, so you have to modify it also.

> [@arwtyxouymz](#):
>
> // for ( unsigned int d = 0; d \< centerIndex \* 2 + 1; d++ )  
> for ( unsigned int d = 0; d \< centerIndex \* 4 + 1; d++ )

As the centerIndex will automatically increase if kernel size was correctly set previously, you don’t have to change the loop extent.

Anyway, if modifying the code to get your desired behavior troubles you, you can go with the solution that @blowekamp gave you: dilate the image first (with a box structuring element of size 3x3), then run the filter on this dilated image, and finally mask the result with initial image.

HTH,

Tim

(P.S. for the next weeks, it’s likely that I will be away)
