# Computer Tools to Analyze Lung CT Changes after Radiotherapy
## 5 System Implementation
### Segmentation  
#### 5.1.1 Watershed Segmentation  
The watershed lung segmentation algorithm was based on the solution described in [24], but in order to achieve a satisfying result, many additional operations were added. Finally, our watershed transform segmentation had the following structure:  
1. The first step was aimed at finding internal labels. The threshold filter at the level of \(-360\) HU was applied in order to distinguish lungs. Obviously, as presented in Figure 6(a), after thresholding, we obtained not only lungs, but also other elements, e.g., the background, pixel intensity of which was at the level of \(-1000\) HU. In order to remove the background, a clear_borderfunction from the skimage.segmentation module was used. Thanks to that, only lung pixels were left, as shown in Figure 6(b). Afterwards a labeling function from the scikit.measure package was used, in order to mark pixels that belonged to the same groups with unique labels. Unfortunately, this solution worked well only for the slices from the middle part of the series. The first ones contained organs like trachea or other significant airways, which were also detected using the threshold (due to the air inside them; a similar Hounsfield value), as shown in Figure 8. In further steps, these areas could be mistakenly treated as internal markers. To solve this problem for the first 9% of the slices (which very likely contained trachea), additional steps were implemented in order to properly detect only lungs. * All regions with areas smaller than \(0.00012\) of the whole image size were removed. This was necessary in order to get rid of noise and very small insignificant objects, but at the same time, this value cannot be too high, because it would reject regions  
Figure 8: First steps of segmentation with trachea. Figure 7: First steps of segmentation. with small sections of lungs (beginning slices). As a result of this step, we were able obtain two or three segmented regions. * If only two regions were left, that meant that one of them was lung, and the other was trachea. We could assume that due to the fact that in all images containing lungs, lungs were bigger than trachea. We found the minimum \(y\) value of pixels in both areas (located at the top of each area) and removed this region, which had the smaller value (trachea is above lungs on the first slices). This analysis is illustrated in Figure 9.
* If in one of the first slices, three regions were detected, that meant that two of them were lungs, and one was trachea. Unfortunately, we could not simply preserve the two largest ones, because we were not able to ensure that lungs were bigger than trachea (usually, it is the opposite). That is why for this purpose, we detected the centroids of each region (they had \(x\) and \(y\) coordinates). Next, we made a list of all possible pairs of centroids and calculated the Euclidean distance between each pair. As a result, we obtained a list of three distances, sorted them, and kept the two regions between which the distance was largest. A simple visualization is shown in Figure 10. 2. The next step was finding external labels. This was done by dilating the internal marker, creating two temporary matrices, and taking regions where they were different from each other (XOR operation). By changing the dilation iterations, we were able to control the distance between those two markers. The external marker looked like a wide border surrounding the internal one. The border had to be wide enough to cover all minima, which could be located in the neighborhood. The final watershed marker containing internal and external ones is presented in Figure 11. 3. Afterwards, the Sobel filter along both axes (\(x\) and \(y\)) was applied in order to detect edges on the input image (Figure 11). Figure 10: Distances between centroids calculations. Figure 9: Minimum \(y\) values of trachea and one lung. The watershed algorithm was executed with the sobel_gradient and watershed_markers as inputs.