It looks like you can approximate the orientation of the patient: lying on back or side using the following code:
avg_image_orientations = np.array([
0.61659826, 0.77685789, -0.12766521,
-0.39722351, 0.16699159, -0.90234914])
image_orientation = np.array(d.ImageOrientationPatient)
y = np.dot(image_orientation[:3], avg_image_orientations[:3])
x = np.dot(image_orientation[:3], avg_image_orientations[3:])
angle = np.arctan2(y, x) / np.pi * 180 - 75
d
is a DICOM image.
If you plot a histogram of the values you can see that the studies divide into two groups and if you rotate the SAX images you see that indeed the LV appears to be in the same orientation in all images. I found that there are some variability inside a study.
Here are 120 studies after orientation
Here is the code to compute the magical avg_image_orientations
vector
In [ ]:
import numpy as np
image_directions = []
image_orientations = []
for study in range(700):
# read SAX slice=0 t=0 from every study
img_fname = dicom_filename(study=study, s=0, t=0)
d = dicom.read_file(img_fname)
if d.PatientPosition != 'HFS':
print study,d.PatientPosition
image_orientations.append(d.ImageOrientationPatient)
image_direction = np.cross(d.ImageOrientationPatient[:3],d.ImageOrientationPatient[3:])
image_directions.append(image_direction)
image_directions = np.array(image_directions)
avg_image_direction = image_directions.mean(axis=0)
image_orientations = np.array(image_orientations)
avg_image_orientations = image_orientations.mean(axis=0)
avg_image_orientations[:3] /= np.sqrt(np.dot(avg_image_orientations[:3],avg_image_orientations[:3]))
avg_image_orientations[3:] /= np.sqrt(np.dot(avg_image_orientations[3:],avg_image_orientations[3:]))
avg_image_orientations[3:] = np.cross(np.cross(avg_image_orientations[:3],avg_image_orientations[3:]),avg_image_orientations[:3])