Spaces:
Runtime error
Runtime error
import numpy as np | |
import torch | |
import cv2 | |
def np_batched_radon(image_batch): | |
#image_batch: torch tensor, batch_size x 1 x img_size x img_size | |
# squeeze order #1 and transform to numpy | |
image_batch = image_batch.squeeze(1).cpu().numpy() | |
batch_size, img_size = image_batch.shape[:2] | |
if batch_size > 512: # limit batch size to 512 because cv2.warpAffine fails for batch> 512 | |
return np.concatenate([np_batched_radon(image_batch[i:i+512]) for i in range(0,batch_size,512)], axis=0) | |
theta = np.arange(180) | |
radon_image = np.zeros((image_batch.shape[0], img_size, len(theta)), | |
dtype='float32') | |
for i, angle in enumerate(theta): | |
M = cv2.getRotationMatrix2D(((img_size-1)/2.0,(img_size-1)/2.0),angle,1) | |
rotated = cv2.warpAffine(np.transpose(image_batch, (1, 2, 0)),M,(img_size,img_size)) | |
#plt.imshow(rotated[:,:,0]) | |
#plt.show() | |
if batch_size == 1: # cv2.warpAffine cancels batch dimension if equal to 1 | |
rotated = rotated[:,:, np.newaxis] | |
rotated = np.transpose(rotated, (2, 0, 1)) / 224.0 | |
#rotated = rotated / np.array(255, dtype='float32') | |
radon_image[:, :, i] = rotated.sum(axis=1) | |
#plot the image | |
# plt.imshow(radon_image[0]) | |
# plt.show() | |
return radon_image | |
def torch_batched_radon(image_batch, neutral_value): | |
#image_batch: batch_size x 1 x img_size x img_size | |
#np_batched_radon(image_batch - neutral_value) | |
image_batch = image_batch - neutral_value # so the 0 value is neutral | |
batch_size = image_batch.shape[0] | |
img_size = image_batch.shape[2] | |
theta = np.arange(180) # we don't need torch here, we will evaluate individual angles below | |
radon_image = torch.zeros((batch_size, 1, img_size, len(theta)), dtype=torch.float, device=image_batch.device) | |
for i, angle in enumerate(theta): | |
#M = cv2.getRotationMatrix2D(((img_size-1)/2.0,(img_size-1)/2.0),angle,1) | |
#calculate the same rotation matrix but with torch: | |
M = torch.tensor(cv2.getRotationMatrix2D(((img_size-1)/2.0,(img_size-1)/2.0),angle,1)).to(image_batch.device, dtype=torch.float32) | |
angle = torch.tensor((angle+90)/180.0*np.pi) | |
M1 = torch.tensor([[torch.sin(angle), torch.cos(angle), 0], | |
[torch.cos(angle), -torch.sin(angle), 0]]).to(image_batch.device, dtype=torch.float32) | |
# we need to add a batch dimension to the rotation matrix | |
M1 = M1.repeat(batch_size, 1, 1) | |
grid = torch.nn.functional.affine_grid(M1, image_batch.shape, align_corners=False) | |
rotated = torch.nn.functional.grid_sample(image_batch, grid, mode='bilinear', padding_mode='zeros', align_corners=False) | |
rotated = rotated.squeeze(1) | |
#plt.imshow(rotated[0].cpu().numpy()) | |
#plt.show() | |
radon_image[:, 0, :, i] = rotated.sum(axis=1) / 224.0 + neutral_value | |
#plt.imshow(radon_image[0, 0].cpu().numpy()) | |
#plt.show() | |
return radon_image | |