def compute_determinant_of_jacobian_forward_differences(phi, spacing): fdt = FD.FD_torch(spacing) dim = len(spacing) if dim == 1: p0x = fdt.dXf(phi[0:1, 0, ...]) det = p0x elif dim == 2: p0x = fdt.dXf(phi[0:1, 0, ...]) p0y = fdt.dYf(phi[0:1, 0, ...]) p1x = fdt.dXf(phi[0:1, 1, ...]) p1y = fdt.dYf(phi[0:1, 1, ...]) det = p0x * p1y - p0y * p1x elif dim == 3: p0x = fdt.dXf(phi[0:1, 0, ...]) p0y = fdt.dYf(phi[0:1, 0, ...]) p0z = fdt.dZf(phi[0:1, 0, ...]) p1x = fdt.dXf(phi[0:1, 1, ...]) p1y = fdt.dYf(phi[0:1, 1, ...]) p1z = fdt.dZf(phi[0:1, 1, ...]) p2x = fdt.dXf(phi[0:1, 2, ...]) p2y = fdt.dYf(phi[0:1, 2, ...]) p2z = fdt.dZf(phi[0:1, 2, ...]) det = p0x * p1y * p2z + p0y * p1z * p2x + p0z * p1x * p2y - p0z * p1y * p2x - p0y * p1x * p2z - p0x * p1z * p2y else: raise ValueError( 'Can only compute the determinant of Jacobian for dimensions 1, 2 and 3' ) det = det.data[0, ...].detach().cpu().numpy() return det
def scale_reg_loss(self, sched='l2'): disp = self.disp_field fd = fdt.FD_torch(self.spacing * 2) dfx = fd.dXc(disp[:, 0, ...]) dfy = fd.dYc(disp[:, 1, ...]) dfz = fd.dZc(disp[:, 2, ...]) l2 = dfx**2 + dfy**2 + dfz**2 reg = l2.mean() return reg
def compute_jacobi(phi,spacing): spacing = spacing # the disp coorindate is [-1,1] fd = fdt.FD_torch(spacing) dfx = fd.dXc(phi[:, 0, ...]) dfy = fd.dYc(phi[:, 1, ...]) jacobi_det = dfx * dfy jacobi_abs = - torch.sum(jacobi_det[jacobi_det < 0.]) print("the current sum of neg determinant of the jacobi is {}".format(jacobi_abs)) return jacobi_abs.item()
def setUp(self): self.spacing = np.array([0.1, 0.2, 0.5]) self.fd_torch = FD.FD_torch(self.spacing) self.inArray = torch.FloatTensor([[[[0., 1., 2.], [3., 4., 5.], [6., 7., 8.]], [[9., 10., 11.], [12., 13., 14.], [15., 16., 17.]], [[18., 19., 20.], [21., 22., 23.], [24., 25., 26.]]]])
def prec_loss(self, disp): ##!!!!!!!! """ a more manual implementation of the precision matrix term mu * P * mu where P = D - A where D is the degree matrix and A is the adjacency matrix mu * P * mu = 0.5 * sum_i mu_i sum_j (mu_i - mu_j) = 0.5 * sum_i,j (mu_i - mu_j) ^ 2 where j are neighbors of i Note: could probably do with a difference filter, but the edges would be complicated unless tensorflow allowed for edge copying """ fd = fdt.FD_torch(np.array([1., 1., 1.])) dfx = fd.dXc(disp[:, 0, ...]) dfy = fd.dYc(disp[:, 1, ...]) dfz = fd.dZc(disp[:, 2, ...]) l2 = dfx**2 + dfy**2 + dfz**2 reg = l2.mean() return reg * 0.5
def scale_reg_loss(self): def __compute_contour(seg_data): contours = pynd_segutils.seg2contour(seg_data, exclude_zero=True, contour_type='both')[None] contours[contours > 0] = 1 return torch.Tensor(contours).cuda() if self.mask is None: import SimpleITK as sitk atlas_path = '/playpen-raid/zyshen/data/oai_seg/atlas_label.nii.gz' seg = sitk.GetArrayFromImage(sitk.ReadImage(atlas_path)) contour = __compute_contour(seg) self.mask = 1.0 - contour delta = self.delta fd = fdt.FD_torch(self.spacing * 2) dfx = fd.dXc(delta[:, 0, ...]) dfy = fd.dYc(delta[:, 0, ...]) dfz = fd.dZc(delta[:, 0, ...]) dabs = dfx.abs() + dfy.abs() + dfz.abs() l2 = self.mask * dabs reg = l2.mean() return reg
def setUp(self): self.spacing = np.array([0.1, 0.2]) self.fd_torch = FD.FD_torch(self.spacing)
def setUp(self): self.spacing = np.array([0.1, 0.2]) self.fd_torch = FD.FD_torch(self.spacing, mode='neumann_zero')