20.03.2021 Views

Deep-Learning-with-PyTorch

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Bridging CT segmentation and nodule candidate classification

411

This was easy enough, but now we need to invent the grouping.

14.3.2 Grouping voxels into nodule candidates

We are going to use a simple connected-components algorithm for grouping our suspected

nodule voxels into chunks to feed into classification. This grouping approach

labels connected components, which we will accomplish using scipy.ndimage

.measurements.label. The label function will take all nonzero pixels that share an

edge with another nonzero pixel and mark them as belonging to the same group.

Since our output from the segmentation model has mostly blobs of highly adjacent

pixels, this approach matches our data well.

Listing 14.3

nodule_analysis.py:401

Assigns each voxel the label

of the group it belongs to

def groupSegmentationOutput(self, series_uid, ct, clean_a):

candidateLabel_a, candidate_count = measurements.label(clean_a)

centerIrc_list = measurements.center_of_mass(

ct.hu_a.clip(-1000, 1000) + 1001,

Gets the center of mass for

labels=candidateLabel_a,

each group as index, row,

index=np.arange(1, candidate_count+1),

column coordinates

)

The output array candidateLabel_a is the same shape as clean_a, which we used for

input, but it has 0 where the background voxels are, and increasing integer labels 1, 2,

…, with one number for each of the connected blobs of voxels making up a nodule candidate.

Note that the labels here are not the same as labels in a classification sense! These

are just saying “This blob of voxels is blob 1, this blob over here is blob 2, and so on.”

SciPy also sports a function to get the centers of mass of the nodule candidates:

scipy.ndimage.measurements.center_of_mass. It takes an array with per-voxel densities,

the integer labels from the label function we just called, and a list of which of

those labels need to have a center calculated. To match the function’s expectation

that the mass is non-negative, we offset the (clipped) ct.hu_a by 1,001. Note that this

leads to all flagged voxels carrying some weight, since we clamped the lowest air value

to –1,000 HU in the native CT units.

Listing 14.4

nodule_analysis.py:409

candidateInfo_list = []

for i, center_irc in enumerate(centerIrc_list):

center_xyz = irc2xyz(

center_irc,

ct.origin_xyz,

ct.vxSize_xyz,

ct.direction_a,

)

Converts the voxel

coordinates to real

patient coordinates

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!