1 /*=========================================================================
2  *
3  *  Copyright Insight Software Consortium
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at
8  *
9  *         http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  *=========================================================================*/
18 #ifndef itkConnectedComponentAlgorithm_h
19 #define itkConnectedComponentAlgorithm_h
20 
21 #include "itkImage.h"
22 #include "itkShapedNeighborhoodIterator.h"
23 
24 namespace itk
25 {
26 template< typename TIterator >
27 TIterator *
28 setConnectivity(TIterator *it, bool fullyConnected = false)
29 {
30   typename TIterator::OffsetType offset;
31   it->ClearActiveList();
32   if ( !fullyConnected )
33     {
34     // only activate the neighbors that are face connected
35     // to the current pixel. do not include the center pixel
36     offset.Fill(0);
37     for ( unsigned int d = 0; d < TIterator::Dimension; ++d )
38       {
39       offset[d] = -1;
40       it->ActivateOffset(offset);
41       offset[d] = 1;
42       it->ActivateOffset(offset);
43       offset[d] = 0;
44       }
45     }
46   else
47     {
48     // activate all neighbors that are face+edge+vertex
49     // connected to the current pixel. do not include the center pixel
50     unsigned int centerIndex = it->GetCenterNeighborhoodIndex();
51     for ( unsigned int d = 0; d < centerIndex * 2 + 1; d++ )
52       {
53       offset = it->GetOffset(d);
54       it->ActivateOffset(offset);
55       }
56     offset.Fill(0);
57     it->DeactivateOffset(offset);
58     }
59   return it;
60 }
61 
62 template< typename TIterator >
63 TIterator *
64 setConnectivityPrevious(TIterator *it, bool fullyConnected = false)
65 {
66   // activate the "previous" neighbours
67   typename TIterator::OffsetType offset;
68   it->ClearActiveList();
69   if ( !fullyConnected )
70     {
71     // only activate the neighbors that are face connected
72     // to the current pixel. do not include the center pixel
73     offset.Fill(0);
74     for ( unsigned int d = 0; d < TIterator::Dimension; ++d )
75       {
76       offset[d] = -1;
77       it->ActivateOffset(offset);
78       offset[d] = 0;
79       }
80     }
81   else
82     {
83     // activate all neighbors that are face+edge+vertex
84     // connected to the current pixel. do not include the center pixel
85     unsigned int centerIndex = it->GetCenterNeighborhoodIndex();
86     for ( unsigned int d = 0; d < centerIndex; d++ )
87       {
88       offset = it->GetOffset(d);
89       it->ActivateOffset(offset);
90       }
91     offset.Fill(0);
92     it->DeactivateOffset(offset);
93     }
94   return it;
95 }
96 
97 template< typename TIterator >
98 TIterator *
99 setConnectivityLater(TIterator *it, bool fullyConnected = false)
100 {
101   // activate the "later" neighbours
102   typename TIterator::OffsetType offset;
103   it->ClearActiveList();
104   if ( !fullyConnected )
105     {
106     // only activate the neighbors that are face connected
107     // to the current pixel. do not include the center pixel
108     offset.Fill(0);
109     for ( unsigned int d = 0; d < TIterator::Dimension; ++d )
110       {
111       offset[d] = 1;
112       it->ActivateOffset(offset);
113       offset[d] = 0;
114       }
115     }
116   else
117     {
118     // activate all neighbors that are face+edge+vertex
119     // connected to the current pixel. do not include the center pixel
120     unsigned int centerIndex = it->GetCenterNeighborhoodIndex();
121     for ( unsigned int d = centerIndex + 1; d < 2 * centerIndex + 1; d++ )
122       {
123       offset = it->GetOffset(d);
124       it->ActivateOffset(offset);
125       }
126     offset.Fill(0);
127     it->DeactivateOffset(offset);
128     }
129   return it;
130 }
131 }
132 
133 #endif
134