Last active
August 28, 2024 05:25
-
-
Save vikashg/8cb1d79c8c56f6425acd73a4f76988ba to your computer and use it in GitHub Desktop.
This small self contained function is a sandbox to test Geometric Transforms
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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