Skip to content

Instantly share code, notes, and snippets.

@vikashg
Last active August 28, 2024 05:25
Show Gist options
  • Save vikashg/8cb1d79c8c56f6425acd73a4f76988ba to your computer and use it in GitHub Desktop.
Save vikashg/8cb1d79c8c56f6425acd73a4f76988ba to your computer and use it in GitHub Desktop.
This small self contained function is a sandbox to test Geometric Transforms
import json
import numpy as np
import matplotlib.pyplot as plt
from monai.transforms import LoadImage, ToNumpy
import cv2
def draw_points_on_image(image_2d, point_list):
"""
A small fn to plot the points on an extracted 2d slice
Args:
image_2d: numpy array of shape (H, W)
point_list: [[pt_x, pt_y, pt_z], ..., ]
Returns: image
"""
image = np.repeat(np.expand_dims(image_2d, axis=2), 3, axis=2)
pt_2d = []
for _pt in point_list:
image = cv2.circle(image, (int(_pt[1]), int(_pt[0])), radius=1, color=(0,0, 255), thickness=2)
pt_2d.append([int(_pt[1]), int(_pt[0])]) # assembling points for poltline
_pt_2d_np = np.array(pt_2d)
# Here I am converting the points to int only because open CV understands int for drawing for floating points it gives errors. I think even if I use int, the transformed points should be close enough to the original shape after rotation
image =cv2.polylines(image, np.int32([_pt_2d_np]), isClosed=True, color=(255, 255, 255), thickness=1)
return image
axial_path = "./spleen_60_axial.mrk.json"
coronal_path = "./spleen_60_coronal.mrk.json"
sagittal_path = "./spleen_60_sagittal.mrk.json"
# download_url("https://drive.google.com/uc?id=1zv57rnoPi0tP8w14KvX818XgaYuAJ6c3" , axial_path)
# download_url("https://drive.google.com/uc?id=1f_xRQ2qGfCeG4GgYjX2NlJpuAmo0NBNi" , coronal_path)
# download_url("https://drive.google.com/uc?id=1dQmKLw3IwyaSXwzxUqrNrx4o7vTqd22-" , sagittal_path)
with open(axial_path, "r") as file:
data_axial = json.load(file)
#print(data_axial)
coordinates_image_axial = np.array([
[198, 202, 78],
[187, 178, 78],
[157, 156, 78],
[138, 137, 78],
[81, 185, 78],
[75, 264, 78],
[94, 238, 78],
[115, 206, 78],
[150, 204, 78],
[192, 208, 78],
])
# download the image from: https://drive.google.com/file/d/1HV6bUMDXbzJEyhBRpHVsPD62LUn6W8V1/view?usp=sharing
image_path = "./spleen_60.nii.gz"
image_3d = LoadImage(image_only=True, reader="ITKReader")(image_path)
from monai.transforms import LoadImaged, EnsureChannelFirstd, Rotated, Compose
from monai.transforms import ApplyTransformToPointsd
# In the following transform chain I am loading the image and rotating along the z axis to ensure that all the points are contained with the same slice.
transform_chain = Compose([LoadImaged(keys=["image"]),
EnsureChannelFirstd(keys=["image"]), Rotated(keys=["image"], angle=(0, 0, 20)),
ApplyTransformToPointsd(keys=["points"], refer_key="image", affine_lps_to_ras=True)])
data = {"image": image_path, "points": coordinates_image_axial[None]}
data_out = transform_chain(data)
# Checking ouputs
print(type(data))
print(data.keys())
print(data_out['image'])
print(data_out['points'])
slice_id = 78 #where points are marked
image_2d = data_out['image'][:, :, :, slice_id]
_image_2d = ToNumpy()(image_2d[0,]) # Converting to numpy for opencv
out_pt = ToNumpy()(data_out['points'][0,])
rotated_image = draw_points_on_image(_image_2d, out_pt)
cv2.imwrite('./test_rot.png', rotated_image)
original_image_2d = ToNumpy()(image_3d[:,:, slice_id])
orig_image = draw_points_on_image(original_image_2d, coordinates_image_axial)
cv2.imwrite('./test_orig.png', orig_image)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment