Spaces:
Running
Running
# -*- coding: utf-8 -*- | |
import numpy as np | |
import scipy | |
from scipy import fftpack | |
import torch | |
from math import cos, sin | |
from numpy import zeros, ones, prod, array, pi, log, min, mod, arange, sum, mgrid, exp, pad, round | |
from numpy.random import randn, rand | |
from scipy.signal import convolve2d | |
import cv2 | |
import random | |
# import utils_image as util | |
''' | |
modified by Kai Zhang (github: https://github.com/cszn) | |
03/03/2019 | |
''' | |
def get_uperleft_denominator(img, kernel): | |
''' | |
img: HxWxC | |
kernel: hxw | |
denominator: HxWx1 | |
upperleft: HxWxC | |
''' | |
V = psf2otf(kernel, img.shape[:2]) | |
denominator = np.expand_dims(np.abs(V)**2, axis=2) | |
upperleft = np.expand_dims(np.conj(V), axis=2) * np.fft.fft2(img, axes=[0, 1]) | |
return upperleft, denominator | |
def get_uperleft_denominator_pytorch(img, kernel): | |
''' | |
img: NxCxHxW | |
kernel: Nx1xhxw | |
denominator: Nx1xHxW | |
upperleft: NxCxHxWx2 | |
''' | |
V = p2o(kernel, img.shape[-2:]) # Nx1xHxWx2 | |
denominator = V[..., 0]**2+V[..., 1]**2 # Nx1xHxW | |
upperleft = cmul(cconj(V), rfft(img)) # Nx1xHxWx2 * NxCxHxWx2 | |
return upperleft, denominator | |
def c2c(x): | |
return torch.from_numpy(np.stack([np.float32(x.real), np.float32(x.imag)], axis=-1)) | |
def r2c(x): | |
return torch.stack([x, torch.zeros_like(x)], -1) | |
def cdiv(x, y): | |
a, b = x[..., 0], x[..., 1] | |
c, d = y[..., 0], y[..., 1] | |
cd2 = c**2 + d**2 | |
return torch.stack([(a*c+b*d)/cd2, (b*c-a*d)/cd2], -1) | |
def cabs(x): | |
return torch.pow(x[..., 0]**2+x[..., 1]**2, 0.5) | |
def cmul(t1, t2): | |
''' | |
complex multiplication | |
t1: NxCxHxWx2 | |
output: NxCxHxWx2 | |
''' | |
real1, imag1 = t1[..., 0], t1[..., 1] | |
real2, imag2 = t2[..., 0], t2[..., 1] | |
return torch.stack([real1 * real2 - imag1 * imag2, real1 * imag2 + imag1 * real2], dim=-1) | |
def cconj(t, inplace=False): | |
''' | |
# complex's conjugation | |
t: NxCxHxWx2 | |
output: NxCxHxWx2 | |
''' | |
c = t.clone() if not inplace else t | |
c[..., 1] *= -1 | |
return c | |
def rfft(t): | |
return torch.rfft(t, 2, onesided=False) | |
def irfft(t): | |
return torch.irfft(t, 2, onesided=False) | |
def fft(t): | |
return torch.fft(t, 2) | |
def ifft(t): | |
return torch.ifft(t, 2) | |
def p2o(psf, shape): | |
''' | |
# psf: NxCxhxw | |
# shape: [H,W] | |
# otf: NxCxHxWx2 | |
''' | |
otf = torch.zeros(psf.shape[:-2] + shape).type_as(psf) | |
otf[...,:psf.shape[2],:psf.shape[3]].copy_(psf) | |
for axis, axis_size in enumerate(psf.shape[2:]): | |
otf = torch.roll(otf, -int(axis_size / 2), dims=axis+2) | |
otf = torch.rfft(otf, 2, onesided=False) | |
n_ops = torch.sum(torch.tensor(psf.shape).type_as(psf) * torch.log2(torch.tensor(psf.shape).type_as(psf))) | |
otf[...,1][torch.abs(otf[...,1])<n_ops*2.22e-16] = torch.tensor(0).type_as(psf) | |
return otf | |
# otf2psf: not sure where I got this one from. Maybe translated from Octave source code or whatever. It's just math. | |
def otf2psf(otf, outsize=None): | |
insize = np.array(otf.shape) | |
psf = np.fft.ifftn(otf, axes=(0, 1)) | |
for axis, axis_size in enumerate(insize): | |
psf = np.roll(psf, np.floor(axis_size / 2).astype(int), axis=axis) | |
if type(outsize) != type(None): | |
insize = np.array(otf.shape) | |
outsize = np.array(outsize) | |
n = max(np.size(outsize), np.size(insize)) | |
# outsize = postpad(outsize(:), n, 1); | |
# insize = postpad(insize(:) , n, 1); | |
colvec_out = outsize.flatten().reshape((np.size(outsize), 1)) | |
colvec_in = insize.flatten().reshape((np.size(insize), 1)) | |
outsize = np.pad(colvec_out, ((0, max(0, n - np.size(colvec_out))), (0, 0)), mode="constant") | |
insize = np.pad(colvec_in, ((0, max(0, n - np.size(colvec_in))), (0, 0)), mode="constant") | |
pad = (insize - outsize) / 2 | |
if np.any(pad < 0): | |
print("otf2psf error: OUTSIZE must be smaller than or equal than OTF size") | |
prepad = np.floor(pad) | |
postpad = np.ceil(pad) | |
dims_start = prepad.astype(int) | |
dims_end = (insize - postpad).astype(int) | |
for i in range(len(dims_start.shape)): | |
psf = np.take(psf, range(dims_start[i][0], dims_end[i][0]), axis=i) | |
n_ops = np.sum(otf.size * np.log2(otf.shape)) | |
psf = np.real_if_close(psf, tol=n_ops) | |
return psf | |
# psf2otf copied/modified from https://github.com/aboucaud/pypher/blob/master/pypher/pypher.py | |
def psf2otf(psf, shape=None): | |
""" | |
Convert point-spread function to optical transfer function. | |
Compute the Fast Fourier Transform (FFT) of the point-spread | |
function (PSF) array and creates the optical transfer function (OTF) | |
array that is not influenced by the PSF off-centering. | |
By default, the OTF array is the same size as the PSF array. | |
To ensure that the OTF is not altered due to PSF off-centering, PSF2OTF | |
post-pads the PSF array (down or to the right) with zeros to match | |
dimensions specified in OUTSIZE, then circularly shifts the values of | |
the PSF array up (or to the left) until the central pixel reaches (1,1) | |
position. | |
Parameters | |
---------- | |
psf : `numpy.ndarray` | |
PSF array | |
shape : int | |
Output shape of the OTF array | |
Returns | |
------- | |
otf : `numpy.ndarray` | |
OTF array | |
Notes | |
----- | |
Adapted from MATLAB psf2otf function | |
""" | |
if type(shape) == type(None): | |
shape = psf.shape | |
shape = np.array(shape) | |
if np.all(psf == 0): | |
# return np.zeros_like(psf) | |
return np.zeros(shape) | |
if len(psf.shape) == 1: | |
psf = psf.reshape((1, psf.shape[0])) | |
inshape = psf.shape | |
psf = zero_pad(psf, shape, position='corner') | |
for axis, axis_size in enumerate(inshape): | |
psf = np.roll(psf, -int(axis_size / 2), axis=axis) | |
# Compute the OTF | |
otf = np.fft.fft2(psf, axes=(0, 1)) | |
# Estimate the rough number of operations involved in the FFT | |
# and discard the PSF imaginary part if within roundoff error | |
# roundoff error = machine epsilon = sys.float_info.epsilon | |
# or np.finfo().eps | |
n_ops = np.sum(psf.size * np.log2(psf.shape)) | |
otf = np.real_if_close(otf, tol=n_ops) | |
return otf | |
def zero_pad(image, shape, position='corner'): | |
""" | |
Extends image to a certain size with zeros | |
Parameters | |
---------- | |
image: real 2d `numpy.ndarray` | |
Input image | |
shape: tuple of int | |
Desired output shape of the image | |
position : str, optional | |
The position of the input image in the output one: | |
* 'corner' | |
top-left corner (default) | |
* 'center' | |
centered | |
Returns | |
------- | |
padded_img: real `numpy.ndarray` | |
The zero-padded image | |
""" | |
shape = np.asarray(shape, dtype=int) | |
imshape = np.asarray(image.shape, dtype=int) | |
if np.alltrue(imshape == shape): | |
return image | |
if np.any(shape <= 0): | |
raise ValueError("ZERO_PAD: null or negative shape given") | |
dshape = shape - imshape | |
if np.any(dshape < 0): | |
raise ValueError("ZERO_PAD: target size smaller than source one") | |
pad_img = np.zeros(shape, dtype=image.dtype) | |
idx, idy = np.indices(imshape) | |
if position == 'center': | |
if np.any(dshape % 2 != 0): | |
raise ValueError("ZERO_PAD: source and target shapes " | |
"have different parity.") | |
offx, offy = dshape // 2 | |
else: | |
offx, offy = (0, 0) | |
pad_img[idx + offx, idy + offy] = image | |
return pad_img | |
''' | |
Reducing boundary artifacts | |
''' | |
def opt_fft_size(n): | |
''' | |
Kai Zhang (github: https://github.com/cszn) | |
03/03/2019 | |
# opt_fft_size.m | |
# compute an optimal data length for Fourier transforms | |
# written by Sunghyun Cho ([email protected]) | |
# persistent opt_fft_size_LUT; | |
''' | |
LUT_size = 2048 | |
# print("generate opt_fft_size_LUT") | |
opt_fft_size_LUT = np.zeros(LUT_size) | |
e2 = 1 | |
while e2 <= LUT_size: | |
e3 = e2 | |
while e3 <= LUT_size: | |
e5 = e3 | |
while e5 <= LUT_size: | |
e7 = e5 | |
while e7 <= LUT_size: | |
if e7 <= LUT_size: | |
opt_fft_size_LUT[e7-1] = e7 | |
if e7*11 <= LUT_size: | |
opt_fft_size_LUT[e7*11-1] = e7*11 | |
if e7*13 <= LUT_size: | |
opt_fft_size_LUT[e7*13-1] = e7*13 | |
e7 = e7 * 7 | |
e5 = e5 * 5 | |
e3 = e3 * 3 | |
e2 = e2 * 2 | |
nn = 0 | |
for i in range(LUT_size, 0, -1): | |
if opt_fft_size_LUT[i-1] != 0: | |
nn = i-1 | |
else: | |
opt_fft_size_LUT[i-1] = nn+1 | |
m = np.zeros(len(n)) | |
for c in range(len(n)): | |
nn = n[c] | |
if nn <= LUT_size: | |
m[c] = opt_fft_size_LUT[nn-1] | |
else: | |
m[c] = -1 | |
return m | |
def wrap_boundary_liu(img, img_size): | |
""" | |
Reducing boundary artifacts in image deconvolution | |
Renting Liu, Jiaya Jia | |
ICIP 2008 | |
""" | |
if img.ndim == 2: | |
ret = wrap_boundary(img, img_size) | |
elif img.ndim == 3: | |
ret = [wrap_boundary(img[:, :, i], img_size) for i in range(3)] | |
ret = np.stack(ret, 2) | |
return ret | |
def wrap_boundary(img, img_size): | |
""" | |
python code from: | |
https://github.com/ys-koshelev/nla_deblur/blob/90fe0ab98c26c791dcbdf231fe6f938fca80e2a0/boundaries.py | |
Reducing boundary artifacts in image deconvolution | |
Renting Liu, Jiaya Jia | |
ICIP 2008 | |
""" | |
(H, W) = np.shape(img) | |
H_w = int(img_size[0]) - H | |
W_w = int(img_size[1]) - W | |
# ret = np.zeros((img_size[0], img_size[1])); | |
alpha = 1 | |
HG = img[:, :] | |
r_A = np.zeros((alpha*2+H_w, W)) | |
r_A[:alpha, :] = HG[-alpha:, :] | |
r_A[-alpha:, :] = HG[:alpha, :] | |
a = np.arange(H_w)/(H_w-1) | |
# r_A(alpha+1:end-alpha, 1) = (1-a)*r_A(alpha,1) + a*r_A(end-alpha+1,1) | |
r_A[alpha:-alpha, 0] = (1-a)*r_A[alpha-1, 0] + a*r_A[-alpha, 0] | |
# r_A(alpha+1:end-alpha, end) = (1-a)*r_A(alpha,end) + a*r_A(end-alpha+1,end) | |
r_A[alpha:-alpha, -1] = (1-a)*r_A[alpha-1, -1] + a*r_A[-alpha, -1] | |
r_B = np.zeros((H, alpha*2+W_w)) | |
r_B[:, :alpha] = HG[:, -alpha:] | |
r_B[:, -alpha:] = HG[:, :alpha] | |
a = np.arange(W_w)/(W_w-1) | |
r_B[0, alpha:-alpha] = (1-a)*r_B[0, alpha-1] + a*r_B[0, -alpha] | |
r_B[-1, alpha:-alpha] = (1-a)*r_B[-1, alpha-1] + a*r_B[-1, -alpha] | |
if alpha == 1: | |
A2 = solve_min_laplacian(r_A[alpha-1:, :]) | |
B2 = solve_min_laplacian(r_B[:, alpha-1:]) | |
r_A[alpha-1:, :] = A2 | |
r_B[:, alpha-1:] = B2 | |
else: | |
A2 = solve_min_laplacian(r_A[alpha-1:-alpha+1, :]) | |
r_A[alpha-1:-alpha+1, :] = A2 | |
B2 = solve_min_laplacian(r_B[:, alpha-1:-alpha+1]) | |
r_B[:, alpha-1:-alpha+1] = B2 | |
A = r_A | |
B = r_B | |
r_C = np.zeros((alpha*2+H_w, alpha*2+W_w)) | |
r_C[:alpha, :] = B[-alpha:, :] | |
r_C[-alpha:, :] = B[:alpha, :] | |
r_C[:, :alpha] = A[:, -alpha:] | |
r_C[:, -alpha:] = A[:, :alpha] | |
if alpha == 1: | |
C2 = C2 = solve_min_laplacian(r_C[alpha-1:, alpha-1:]) | |
r_C[alpha-1:, alpha-1:] = C2 | |
else: | |
C2 = solve_min_laplacian(r_C[alpha-1:-alpha+1, alpha-1:-alpha+1]) | |
r_C[alpha-1:-alpha+1, alpha-1:-alpha+1] = C2 | |
C = r_C | |
# return C | |
A = A[alpha-1:-alpha-1, :] | |
B = B[:, alpha:-alpha] | |
C = C[alpha:-alpha, alpha:-alpha] | |
ret = np.vstack((np.hstack((img, B)), np.hstack((A, C)))) | |
return ret | |
def solve_min_laplacian(boundary_image): | |
(H, W) = np.shape(boundary_image) | |
# Laplacian | |
f = np.zeros((H, W)) | |
# boundary image contains image intensities at boundaries | |
boundary_image[1:-1, 1:-1] = 0 | |
j = np.arange(2, H)-1 | |
k = np.arange(2, W)-1 | |
f_bp = np.zeros((H, W)) | |
f_bp[np.ix_(j, k)] = -4*boundary_image[np.ix_(j, k)] + boundary_image[np.ix_(j, k+1)] + boundary_image[np.ix_(j, k-1)] + boundary_image[np.ix_(j-1, k)] + boundary_image[np.ix_(j+1, k)] | |
del(j, k) | |
f1 = f - f_bp # subtract boundary points contribution | |
del(f_bp, f) | |
# DST Sine Transform algo starts here | |
f2 = f1[1:-1,1:-1] | |
del(f1) | |
# compute sine tranform | |
if f2.shape[1] == 1: | |
tt = fftpack.dst(f2, type=1, axis=0)/2 | |
else: | |
tt = fftpack.dst(f2, type=1)/2 | |
if tt.shape[0] == 1: | |
f2sin = np.transpose(fftpack.dst(np.transpose(tt), type=1, axis=0)/2) | |
else: | |
f2sin = np.transpose(fftpack.dst(np.transpose(tt), type=1)/2) | |
del(f2) | |
# compute Eigen Values | |
[x, y] = np.meshgrid(np.arange(1, W-1), np.arange(1, H-1)) | |
denom = (2*np.cos(np.pi*x/(W-1))-2) + (2*np.cos(np.pi*y/(H-1)) - 2) | |
# divide | |
f3 = f2sin/denom | |
del(f2sin, x, y) | |
# compute Inverse Sine Transform | |
if f3.shape[0] == 1: | |
tt = fftpack.idst(f3*2, type=1, axis=1)/(2*(f3.shape[1]+1)) | |
else: | |
tt = fftpack.idst(f3*2, type=1, axis=0)/(2*(f3.shape[0]+1)) | |
del(f3) | |
if tt.shape[1] == 1: | |
img_tt = np.transpose(fftpack.idst(np.transpose(tt)*2, type=1)/(2*(tt.shape[0]+1))) | |
else: | |
img_tt = np.transpose(fftpack.idst(np.transpose(tt)*2, type=1, axis=0)/(2*(tt.shape[1]+1))) | |
del(tt) | |
# put solution in inner points; outer points obtained from boundary image | |
img_direct = boundary_image | |
img_direct[1:-1, 1:-1] = 0 | |
img_direct[1:-1, 1:-1] = img_tt | |
return img_direct | |
""" | |
Created on Thu Jan 18 15:36:32 2018 | |
@author: italo | |
https://github.com/ronaldosena/imagens-medicas-2/blob/40171a6c259edec7827a6693a93955de2bd39e76/Aulas/aula_2_-_uniform_filter/matlab_fspecial.py | |
""" | |
""" | |
Syntax | |
h = fspecial(type) | |
h = fspecial('average',hsize) | |
h = fspecial('disk',radius) | |
h = fspecial('gaussian',hsize,sigma) | |
h = fspecial('laplacian',alpha) | |
h = fspecial('log',hsize,sigma) | |
h = fspecial('motion',len,theta) | |
h = fspecial('prewitt') | |
h = fspecial('sobel') | |
""" | |
def fspecial_average(hsize=3): | |
"""Smoothing filter""" | |
return np.ones((hsize, hsize))/hsize**2 | |
def fspecial_disk(radius): | |
"""Disk filter""" | |
raise(NotImplemented) | |
rad = 0.6 | |
crad = np.ceil(rad-0.5) | |
[x, y] = np.meshgrid(np.arange(-crad, crad+1), np.arange(-crad, crad+1)) | |
maxxy = np.zeros(x.shape) | |
maxxy[abs(x) >= abs(y)] = abs(x)[abs(x) >= abs(y)] | |
maxxy[abs(y) >= abs(x)] = abs(y)[abs(y) >= abs(x)] | |
minxy = np.zeros(x.shape) | |
minxy[abs(x) <= abs(y)] = abs(x)[abs(x) <= abs(y)] | |
minxy[abs(y) <= abs(x)] = abs(y)[abs(y) <= abs(x)] | |
m1 = (rad**2 < (maxxy+0.5)**2 + (minxy-0.5)**2)*(minxy-0.5) +\ | |
(rad**2 >= (maxxy+0.5)**2 + (minxy-0.5)**2)*\ | |
np.sqrt((rad**2 + 0j) - (maxxy + 0.5)**2) | |
m2 = (rad**2 > (maxxy-0.5)**2 + (minxy+0.5)**2)*(minxy+0.5) +\ | |
(rad**2 <= (maxxy-0.5)**2 + (minxy+0.5)**2)*\ | |
np.sqrt((rad**2 + 0j) - (maxxy - 0.5)**2) | |
h = None | |
return h | |
def fspecial_gaussian(hsize, sigma): | |
hsize = [hsize, hsize] | |
siz = [(hsize[0]-1.0)/2.0, (hsize[1]-1.0)/2.0] | |
std = sigma | |
[x, y] = np.meshgrid(np.arange(-siz[1], siz[1]+1), np.arange(-siz[0], siz[0]+1)) | |
arg = -(x*x + y*y)/(2*std*std) | |
h = np.exp(arg) | |
h[h < scipy.finfo(float).eps * h.max()] = 0 | |
sumh = h.sum() | |
if sumh != 0: | |
h = h/sumh | |
return h | |
def fspecial_laplacian(alpha): | |
alpha = max([0, min([alpha,1])]) | |
h1 = alpha/(alpha+1) | |
h2 = (1-alpha)/(alpha+1) | |
h = [[h1, h2, h1], [h2, -4/(alpha+1), h2], [h1, h2, h1]] | |
h = np.array(h) | |
return h | |
def fspecial_log(hsize, sigma): | |
raise(NotImplemented) | |
def fspecial_motion(motion_len, theta): | |
raise(NotImplemented) | |
def fspecial_prewitt(): | |
return np.array([[1, 1, 1], [0, 0, 0], [-1, -1, -1]]) | |
def fspecial_sobel(): | |
return np.array([[1, 2, 1], [0, 0, 0], [-1, -2, -1]]) | |
def fspecial(filter_type, *args, **kwargs): | |
''' | |
python code from: | |
https://github.com/ronaldosena/imagens-medicas-2/blob/40171a6c259edec7827a6693a93955de2bd39e76/Aulas/aula_2_-_uniform_filter/matlab_fspecial.py | |
''' | |
if filter_type == 'average': | |
return fspecial_average(*args, **kwargs) | |
if filter_type == 'disk': | |
return fspecial_disk(*args, **kwargs) | |
if filter_type == 'gaussian': | |
return fspecial_gaussian(*args, **kwargs) | |
if filter_type == 'laplacian': | |
return fspecial_laplacian(*args, **kwargs) | |
if filter_type == 'log': | |
return fspecial_log(*args, **kwargs) | |
if filter_type == 'motion': | |
return fspecial_motion(*args, **kwargs) | |
if filter_type == 'prewitt': | |
return fspecial_prewitt(*args, **kwargs) | |
if filter_type == 'sobel': | |
return fspecial_sobel(*args, **kwargs) | |
def fspecial_gauss(size, sigma): | |
x, y = mgrid[-size // 2 + 1 : size // 2 + 1, -size // 2 + 1 : size // 2 + 1] | |
g = exp(-((x ** 2 + y ** 2) / (2.0 * sigma ** 2))) | |
return g / g.sum() | |
def blurkernel_synthesis(h=37, w=None): | |
# https://github.com/tkkcc/prior/blob/879a0b6c117c810776d8cc6b63720bf29f7d0cc4/util/gen_kernel.py | |
w = h if w is None else w | |
kdims = [h, w] | |
x = randomTrajectory(250) | |
k = None | |
while k is None: | |
k = kernelFromTrajectory(x) | |
# center pad to kdims | |
pad_width = ((kdims[0] - k.shape[0]) // 2, (kdims[1] - k.shape[1]) // 2) | |
pad_width = [(pad_width[0],), (pad_width[1],)] | |
if pad_width[0][0]<0 or pad_width[1][0]<0: | |
k = k[0:h, 0:h] | |
else: | |
k = pad(k, pad_width, "constant") | |
x1,x2 = k.shape | |
if np.random.randint(0, 4) == 1: | |
k = cv2.resize(k, (random.randint(x1, 5*x1), random.randint(x2, 5*x2)), interpolation=cv2.INTER_LINEAR) | |
y1, y2 = k.shape | |
k = k[(y1-x1)//2: (y1-x1)//2+x1, (y2-x2)//2: (y2-x2)//2+x2] | |
if sum(k)<0.1: | |
k = fspecial_gaussian(h, 0.1+6*np.random.rand(1)) | |
k = k / sum(k) | |
# import matplotlib.pyplot as plt | |
# plt.imshow(k, interpolation="nearest", cmap="gray") | |
# plt.show() | |
return k | |
def kernelFromTrajectory(x): | |
h = 5 - log(rand()) / 0.15 | |
h = round(min([h, 27])).astype(int) | |
h = h + 1 - h % 2 | |
w = h | |
k = zeros((h, w)) | |
xmin = min(x[0]) | |
xmax = max(x[0]) | |
ymin = min(x[1]) | |
ymax = max(x[1]) | |
xthr = arange(xmin, xmax, (xmax - xmin) / w) | |
ythr = arange(ymin, ymax, (ymax - ymin) / h) | |
for i in range(1, xthr.size): | |
for j in range(1, ythr.size): | |
idx = ( | |
(x[0, :] >= xthr[i - 1]) | |
& (x[0, :] < xthr[i]) | |
& (x[1, :] >= ythr[j - 1]) | |
& (x[1, :] < ythr[j]) | |
) | |
k[i - 1, j - 1] = sum(idx) | |
if sum(k) == 0: | |
return | |
k = k / sum(k) | |
k = convolve2d(k, fspecial_gauss(3, 1), "same") | |
k = k / sum(k) | |
return k | |
def randomTrajectory(T): | |
x = zeros((3, T)) | |
v = randn(3, T) | |
r = zeros((3, T)) | |
trv = 1 / 1 | |
trr = 2 * pi / T | |
for t in range(1, T): | |
F_rot = randn(3) / (t + 1) + r[:, t - 1] | |
F_trans = randn(3) / (t + 1) | |
r[:, t] = r[:, t - 1] + trr * F_rot | |
v[:, t] = v[:, t - 1] + trv * F_trans | |
st = v[:, t] | |
st = rot3D(st, r[:, t]) | |
x[:, t] = x[:, t - 1] + st | |
return x | |
def rot3D(x, r): | |
Rx = array([[1, 0, 0], [0, cos(r[0]), -sin(r[0])], [0, sin(r[0]), cos(r[0])]]) | |
Ry = array([[cos(r[1]), 0, sin(r[1])], [0, 1, 0], [-sin(r[1]), 0, cos(r[1])]]) | |
Rz = array([[cos(r[2]), -sin(r[2]), 0], [sin(r[2]), cos(r[2]), 0], [0, 0, 1]]) | |
R = Rz @ Ry @ Rx | |
x = R @ x | |
return x | |
if __name__ == '__main__': | |
a = opt_fft_size([111]) | |
print(a) | |
print(fspecial('gaussian', 5, 1)) | |
print(p2o(torch.zeros(1,1,4,4).float(),(14,14)).shape) | |
k = blurkernel_synthesis(11) | |
import matplotlib.pyplot as plt | |
plt.imshow(k, interpolation="nearest", cmap="gray") | |
plt.show() | |