Download data_process.py from AIGeeksGroup/HMCLIP: direct link, hf CLI and curl.
- Browser
- Download file 4.66 kB
-
https://huggingface.co/AIGeeksGroup/HMCLIP/resolve/main/data_process.py
- Command line
-
hf download hf://AIGeeksGroup/HMCLIP/data_process.py
-
curl -L -o data_process.py https://huggingface.co/AIGeeksGroup/HMCLIP/resolve/main/data_process.py
4.66 kB
| import nibabel as nib | |
| import torch | |
| import numpy as np | |
| import torch.nn.functional as F | |
| from PIL import Image | |
| import random | |
| def resize_array(array, current_spacing, target_spacing): | |
| """ | |
| Resize the array to match the target spacing. | |
| Args: | |
| array (torch.Tensor): Input array to be resized. | |
| current_spacing (tuple): Current voxel spacing (z_spacing, xy_spacing, xy_spacing). | |
| target_spacing (tuple): Target voxel spacing (target_z_spacing, target_x_spacing, target_y_spacing). | |
| Returns: | |
| np.ndarray: Resized array. | |
| """ | |
| # Calculate new dimensions | |
| original_shape = array.shape[2:] | |
| scaling_factors = [ | |
| current_spacing[i] / target_spacing[i] for i in range(len(original_shape)) | |
| ] | |
| new_shape = [ | |
| int(original_shape[i] * scaling_factors[i]) for i in range(len(original_shape)) | |
| ] | |
| # Resize the array | |
| resized_array = F.interpolate(array, size=new_shape, mode='trilinear', align_corners=False).cpu().numpy() | |
| return resized_array | |
| def load_3d_image_to_tensor(path): | |
| nii_img = nib.load(str(path)) | |
| img_data = nii_img.get_fdata() | |
| img_data = np.flip(img_data, axis=0) | |
| img_data = np.flip(img_data, axis=1) | |
| # WARNING Respacing | |
| img_data = img_data.transpose(2, 0, 1) | |
| img_data = np.copy(img_data) | |
| tensor = torch.tensor(img_data) | |
| tensor = tensor.unsqueeze(0).unsqueeze(0) | |
| target_x_spacing = 0.75 | |
| target_y_spacing = 0.75 | |
| target_z_spacing = 1.5 | |
| current = (3, 1, 1) # this is all set to 3 1 1 | |
| target = (target_z_spacing, target_x_spacing, target_y_spacing) | |
| img_data = resize_array(tensor, current, target) | |
| img_data = img_data[0][0] | |
| img_data= np.transpose(img_data, (1, 2, 0)) | |
| # WARNING Normalization 2 | |
| hu_min, hu_max = -1000, 1000 | |
| img_data = np.clip(img_data, hu_min, hu_max) | |
| img_data = (((img_data ) / 1000)).astype(np.float32) | |
| tensor = torch.tensor(img_data) | |
| # WARNING Padding or Crop | |
| # Get the dimensions of the input tensor | |
| target_shape = (480,480,240) # h w d | |
| # Extract dimensions | |
| h, w, d = tensor.shape | |
| # Calculate cropping/padding values for height, width, and depth | |
| dh, dw, dd = target_shape | |
| h_start = max((h - dh) // 2, 0) | |
| h_end = min(h_start + dh, h) | |
| w_start = max((w - dw) // 2, 0) | |
| w_end = min(w_start + dw, w) | |
| d_start = max((d - dd) // 2, 0) | |
| d_end = min(d_start + dd, d) | |
| # Crop or pad the tensor | |
| tensor = tensor[h_start:h_end, w_start:w_end, d_start:d_end] | |
| pad_h_before = (dh - tensor.size(0)) // 2 | |
| pad_h_after = dh - tensor.size(0) - pad_h_before | |
| pad_w_before = (dw - tensor.size(1)) // 2 | |
| pad_w_after = dw - tensor.size(1) - pad_w_before | |
| pad_d_before = (dd - tensor.size(2)) // 2 | |
| pad_d_after = dd - tensor.size(2) - pad_d_before | |
| tensor = torch.nn.functional.pad(tensor, (pad_d_before, pad_d_after, pad_w_before, pad_w_after, pad_h_before, pad_h_after), value=-1) | |
| tensor = tensor.permute(2, 0, 1) # d h w | |
| tensor = tensor.unsqueeze(0) # 1 d h w | |
| return tensor | |
| def load_2d_image_to_tensor(image_path,resize=False): | |
| """ | |
| Load a 2D grayscale image and convert it to a tensor with dimensions [1, 1, 480, 480]. | |
| Args: | |
| image_path (str): Path to the image file. | |
| Returns: | |
| tensor (torch.Tensor): Tensor with shape [1, 1, 480, 480]. | |
| """ | |
| # Load the image as grayscale | |
| image = Image.open(image_path).convert('L') | |
| # Resize to 480x480 if needed | |
| if resize: | |
| if image.size != (480, 480): | |
| image = image.resize((480, 480), Image.BILINEAR) | |
| else: | |
| if image.size != (480, 480): | |
| # 计算可以开始裁剪的最大左上角坐标 | |
| width, height = image.size | |
| crop_size = 480 | |
| if width < crop_size or height < crop_size: | |
| raise ValueError(f"Image size {image.size} is smaller than the crop size {crop_size}.") | |
| max_left = width - crop_size | |
| max_top = height - crop_size | |
| # 随机选择裁剪的左上角坐标 | |
| left = random.randint(0, max(0, max_left)) | |
| top = random.randint(0, max(0, max_top)) | |
| # 裁剪图像 | |
| image = image.crop((left, top, left + crop_size, top + crop_size)) | |
| # Convert to numpy array and normalize to [0, 1] | |
| img_array = (np.array(image, dtype=np.float32) / 255.0) * 2 -1 | |
| # Convert to tensor | |
| tensor = torch.from_numpy(img_array) | |
| # Add batch and channel dimensions | |
| tensor = tensor.unsqueeze(0).unsqueeze(0) # [1, 1, 480, 480] | |
| return tensor |