File size: 2,504 Bytes
6ffe23f 84b28c9 6ffe23f 84b28c9 6ffe23f 84b28c9 6ffe23f 84b28c9 6ffe23f 84b28c9 6ffe23f 84b28c9 6ffe23f |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
from scipy.ndimage import label, find_objects
import numpy as np
import cv2
IMAGE_SPACING_X = 0.7031
IMAGE_SPACING_Y = 0.7031
IMAGE_SPACING_Z = 2.5
def compute_largest_diameter(binary_mask):
# Label connected components in the binary mask
labeled_array, num_features = label(binary_mask)
# Find the objects (tumors) in the labeled array
tumor_objects = find_objects(labeled_array)
# Initialize the largest diameter variable
largest_diameter = 0
# Iterate through each tumor object
for obj in tumor_objects:
# Calculate the dimensions of the tumor object
z_dim = obj[2].stop - obj[2].start
y_dim = obj[1].stop - obj[1].start
x_dim = obj[0].stop - obj[0].start
# Calculate the diameter using the longest dimension
diameter = max(z_dim * IMAGE_SPACING_Z, y_dim * IMAGE_SPACING_Y, x_dim * IMAGE_SPACING_X)
# Update the largest diameter if necessary
if diameter > largest_diameter:
largest_diameter = diameter
return largest_diameter / 10 # IN CM
def compute_shape(binary_mask):
contours, _ = cv2.findContours(binary_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
shape, margin = None, None
if contours:
tumor_contour_area = cv2.contourArea(contours[0])
tumor_contour_perimeter = cv2.arcLength(contours[0], True)
epsilon = 0.02 * tumor_contour_perimeter
approx = cv2.approxPolyDP(contours[0], epsilon, True)
num_sides = len(approx)
# determine the shape based on the number of sides
if num_sides < 5: shape = "Round"
else: shape = "Irregular"
# determine the margin characteristics based on solidity
hull = cv2.convexHull(contours[0])
hull_area = cv2.contourArea(hull)
tumor_solidity = tumor_contour_area / hull_area
if tumor_solidity > 0.95: margin = "Smooth"
elif tumor_solidity > 0.80: margin = "Irregular"
else: margin = "Spiculated"
return shape, margin
def generate_features(img, liver, tumor):
# shape, margin = compute_shape(tumor)
shape, margin = "irregular", "irregular"
features = {
"lesion size (cm)": compute_largest_diameter(tumor),
"lesion boundary": margin,
"lesion shape": shape,
"lesion density (HU)": np.mean(img[tumor==1]),
"involvement of adjacent organs:": "Yes" if np.sum(np.multiply(liver==0, tumor)) > 0 else "No"
}
return features
|