# Measure diameter of curved 3d tube

Hello everyone,

I am working with a 3d curved tubular structure. I have extracted the centerline at various points and now I am trying to calculate the diameter of the tube at those points. At the curved regions, I am trying to use a 3D Euler rotation to align the tube with the z-axis so I can compute the diameter.

I am struggling to rotate the tube around the point so that I can extract the cross-section and the transformed point in the rotated space.

My current approach is to calculate the displacement between the two closest points in the centerline. From there, I compute the Euler rotation angles and apply the rotation to the data and a transformation to the center line point.

It appears that my rotation of the data is correct, however I am unable to verify this because the point transformation does not appear correct.

Here is the code I am using (please note the point is in numpy format so I have to change the axis)

``````def rotation3d(image, theta_x, theta_y, theta_z, point):
"""
This function rotates an image across each of the x, y, z axes by theta_x, theta_y, and theta_z degrees
respectively
:param image: An sitk MRI image
:param theta_x: The amount of degrees the user wants the image rotated around the x axis
:param theta_y: The amount of degrees the user wants the image rotated around the y axis
:param theta_z: The amount of degrees the user wants the image rotated around the z axis
:return: The rotated image
"""
point = (int(point), int(point), int(point))
euler_transform = sitk.Euler3DTransform(image.TransformContinuousIndexToPhysicalPoint([(sz-1)/2.0 for sz in image.GetSize()]), theta_x, theta_y, theta_z, (0, 0, 0))

#euler_transform.SetCenter(point)
euler_transform.SetRotation(theta_x, theta_y, theta_z)
euler_transform.SetComputeZYX(True)

max_indexes = [sz-1 for sz in image.GetSize()]
extreme_indexes = list(itertools.product(*(list(zip(*image.GetDimension(),max_indexes)))))
extreme_points_transformed = [euler_transform.TransformPoint(image.TransformContinuousIndexToPhysicalPoint(p)) for p in extreme_indexes]
output_min_coordinates = np.min(extreme_points_transformed, axis=0)
output_max_coordinates = np.max(extreme_points_transformed, axis=0)

output_spacing = image.GetSpacing()

output_origin = output_min_coordinates
output_size = [int(((omx-omn)/ospc)+0.5)  for ospc, omn, omx in zip(output_spacing, output_min_coordinates, output_max_coordinates)]
output_direction = [1,0,0,0,1,0,0,0,1]
output_pixeltype = image.GetPixelIDValue()

output = sitk.Resample(image,
output_size,
euler_transform,
sitk.sitkLinear,
output_origin,
output_spacing,
output_direction,
0,
output_pixeltype)
#resampled_image = resample(image, euler_transform)

point = euler_transform.TransformPoint(point)
point = (int(point), int(point), int(point))

return output, point
``````

This code is adapted from SimpleITK Euler3D transform, problem with output size/resampling - #2 by dzenanz

Thank you and any help is appreciated!

@Stephen_Aylward might have some suggestions. If he converts his tube to ITK tube, will he get `GetRadiusInObjectSpace` for free?
@cams2b Take a look at Demo-ManipulateTubes.