def bernoulli_deformation(F, I, last_level=None, penalty=1.0, tol=0.001, rho=2.0, wavelet='db2', maxiter=50, start_level=1, means=None, variances=None, debug_plot=False): assert F.ndim == 3, "F must have 3 axes" assert F.shape == I.shape, "F and I shape mismatch {0} {1}".format( F.shape, I.shape) assert F.shape[ 0] == 8, "Currently only supports 8 features (not {0})".format( F.shape[0]) #from scipy.optimize import fmin_bfgs from amitgroup.stats.fmin_bfgs_tol import fmin_bfgs_tol as fmin_bfgs # This, or an assert X = I.astype(float) all_js = range(8) # We don't need more capacity for coefficients than the last_level level_capacity = last_level delFjs = [] for j in all_js: delF = np.gradient(F[j], 1 / F[j].shape[0], 1 / F[j].shape[1]) # Normalize since the image covers the square around [0, 1]. delFjs.append(delF) delFjs = np.rollaxis(np.asarray(delFjs), 1) settings = dict( penalty=penalty, wavelet=wavelet, rho=rho, level_capacity=level_capacity, means=means, variances=variances, ) imdef = ag.util.DisplacementFieldWavelet(F.shape[1:], **settings) x, y = imdef.meshgrid() if debug_plot: plw = ag.plot.PlottingWindow(figsize=(8, 8), subplots=(4, 4)) def cb(uk): if not plw.tick(1): raise ag.AbortException() for j in range(8): plw.imshow(imdef.deform(F[j]), subplot=j * 2) plw.imshow(I[j], subplot=j * 2 + 1) else: cb = None min_cost = np.inf for level in range(start_level, last_level + 1): ag.info("Running coarse-to-fine level", level) imdef.reset(level) u = imdef.u args = (imdef, F, X, 1 - X, delFjs, x, y, level, all_js) try: new_u, cost, min_deriv, Bopt, func_calls, grad_calls, warnflag = \ fmin_bfgs(_cost, u, _cost_deriv, args=args, callback=cb, tol=tol, maxiter=maxiter, full_output=True, disp=False) except ag.AbortException: return None, {} if cost < min_cost: # If the algorithm makes mistakes and returns a really high cost, don't use it. min_cost = cost #imdef.u[:,:u.shape[1],:u.shape[2]] = new_u.reshape(u.shape) imdef.u = new_u.reshape(imdef.u.shape) #if debug_plot: # plw.mainloop() return imdef, {'cost': min_cost}
def bernoulli_deformation(F, I, last_level=None, penalty=1.0, tol=0.001, rho=2.0, wavelet='db2', maxiter=50, start_level=1, means=None, variances=None, debug_plot=False): assert F.ndim == 3, "F must have 3 axes" assert F.shape == I.shape, "F and I shape mismatch {0} {1}".format(F.shape, I.shape) assert F.shape[0] == 8, "Currently only supports 8 features (not {0})".format(F.shape[0]) #from scipy.optimize import fmin_bfgs from amitgroup.stats.fmin_bfgs_tol import fmin_bfgs_tol as fmin_bfgs # This, or an assert X = I.astype(float) all_js = range(8) # We don't need more capacity for coefficients than the last_level level_capacity = last_level delFjs = [] for j in all_js: delF = np.gradient(F[j], 1/F[j].shape[0], 1/F[j].shape[1]) # Normalize since the image covers the square around [0, 1]. delFjs.append(delF) delFjs = np.rollaxis(np.asarray(delFjs), 1) settings = dict( penalty=penalty, wavelet=wavelet, rho=rho, level_capacity=level_capacity, means=means, variances=variances, ) imdef = ag.util.DisplacementFieldWavelet(F.shape[1:], **settings) x, y = imdef.meshgrid() if debug_plot: plw = ag.plot.PlottingWindow(figsize=(8, 8), subplots=(4,4)) def cb(uk): if not plw.tick(1): raise ag.AbortException() for j in range(8): plw.imshow(imdef.deform(F[j]), subplot=j*2) plw.imshow(I[j], subplot=j*2+1) else: cb = None min_cost = np.inf for level in range(start_level, last_level+1): ag.info("Running coarse-to-fine level", level) imdef.reset(level) u = imdef.u args = (imdef, F, X, 1-X, delFjs, x, y, level, all_js) try: new_u, cost, min_deriv, Bopt, func_calls, grad_calls, warnflag = \ fmin_bfgs(_cost, u, _cost_deriv, args=args, callback=cb, tol=tol, maxiter=maxiter, full_output=True, disp=False) except ag.AbortException: return None, {} if cost < min_cost: # If the algorithm makes mistakes and returns a really high cost, don't use it. min_cost = cost #imdef.u[:,:u.shape[1],:u.shape[2]] = new_u.reshape(u.shape) imdef.u = new_u.reshape(imdef.u.shape) #if debug_plot: # plw.mainloop() return imdef, {'cost': min_cost}
def image_deformation(F, I, last_level=3, penalty=1.0, rho=2.0, wavelet='db2', tol=1e-5, \ maxiter=5, start_level=1, means=None, variances=None, llh_variances=1.0, debug_plot=False): """ Deforms an a prototype image `F` into a data image `I` using a Daubechies wavelet basis and maximum a posteriori. Parameters ---------- F : ndarray Prototype image. Array of shape ``(W, H)`` with normalized intensitites. Both `W` and `H` must be powers of two. I : ndarray Data image that the prototype will try to deform into. Array of shape ``(W, H)``. last_level : int, optional Coefficient depth limit. If `None`, then naturally bounded by image size. A higher level will allow for finer deformations, but incur a computational overhead. penalty : float, optional Determines the weight of the prior as opposed to the likelihood. (arbitrarily proportional to the ratio of the inverse variance of the gaussian deformations of the prior and the likelihood). Reduce this value if you want more deformations. rho : float, optional Determines the penalty of more granular coefficients. Increase to smoothen. Must be strictly positive. wavelet : str Wavelet type. See :class:`DisplacementFieldWavelet` for more information. maxiter : int, optional Maximum number of iterations per level. tol : float, optional Cost change must be less than `tol` before succesful termination at each coarse-to-fine level. first_level : int, optional First coarse-to-fine coefficient level. means : ndarray or None, optional Manually specify the means of the prior coefficients. If this and `variances` are set, then `penalty` and `rho` are unused. Must be of size ``(2, C)``, where `C` is the number of coefficients for the wavelet. variances : ndarray or None, optional Analagous to `means`, for specifying variances of the prior coefficients. Size should be the same as for `means`. llh_variances : ndarray or scalar, optional Specify log-likelihood variances per-pixel as a ``(W, H)`` array, or overall as a scalar. Default is 1.0, which can be seen as the variance being absorbed by the variance of the prior. debug_plot : bool, optional Output deformation progress live using :class:`PlottingWindow`. Returns ------- imdef : DisplacementFieldWavelet The deformation in the form of a :class:`DisplacementField`. info : dict Dictionary with info: * `cost`: The final cost value. Examples -------- Deform an image into a prototype image: >>> import amitgroup as ag >>> import numpy as np >>> import matplotlib.pylab as plt Load two example faces and perform the deformation: >>> F, I = ag.io.load_example('two-faces') >>> imdef, info = ag.stats.image_deformation(F, I, penalty=0.1) >>> Fdef = imdef.deform(F) Output the results: >>> ag.plot.deformation(F, I, imdef) >>> plt.show() """ assert rho > 0, "Parameter rho must be strictly positive" assert len(F.shape) == 2 and len( I.shape) == 2, "Images must be 2D ndarrays" assert _powerof2(F.shape[0]) and _powerof2( I.shape[1]), "Image sides must be powers of 2" assert F.shape == I.shape, "Images must have the same shape" #from scipy.optimize import fmin_bfgs from amitgroup.stats.fmin_bfgs_tol import fmin_bfgs_tol as fmin_bfgs level_capacity = last_level delF = np.asarray(np.gradient(F, 1 / F.shape[0], 1 / F.shape[1])) dx = 1 / np.prod(F.shape) settings = dict( penalty=penalty, rho=rho, wavelet=wavelet, level_capacity=level_capacity, means=means, variances=variances, ) imdef = ag.util.DisplacementFieldWavelet(F.shape, **settings) x, y = imdef.meshgrid() if debug_plot: plw = ag.plot.PlottingWindow(figsize=(8, 4), subplots=(1, 2)) def cb(uk): if not plw.tick(1): raise ag.AbortException() plw.imshow(imdef.deform(F), subplot=0) plw.imshow(I, subplot=1) else: cb = None min_cost = np.inf for level in range(start_level, last_level + 1): ag.info("Running coarse-to-fine level", level) u = imdef.abridged_u(level) args = (imdef, F, I, delF, x, y, level, llh_variances) try: new_u, cost, min_deriv, Bopt, func_calls, grad_calls, warnflag = \ fmin_bfgs(_cost, u, _cost_deriv, args=args, callback=cb, tol=tol, maxiter=maxiter, full_output=True, disp=False) except ag.AbortException: return None, {} if cost < min_cost: # If the algorithm makes mistakes and returns a really high cost, don't use it. min_cost = cost imdef.u[:, :u.shape[1], :u.shape[2]] = new_u.reshape(u.shape) #if debug_plot: # plw.mainloop() return imdef, {'cost': min_cost}
def image_deformation(F, I, last_level=3, penalty=1.0, rho=2.0, wavelet='db2', tol=1e-5, \ maxiter=5, start_level=1, means=None, variances=None, llh_variances=1.0, debug_plot=False): """ Deforms an a prototype image `F` into a data image `I` using a Daubechies wavelet basis and maximum a posteriori. Parameters ---------- F : ndarray Prototype image. Array of shape ``(W, H)`` with normalized intensitites. Both `W` and `H` must be powers of two. I : ndarray Data image that the prototype will try to deform into. Array of shape ``(W, H)``. last_level : int, optional Coefficient depth limit. If `None`, then naturally bounded by image size. A higher level will allow for finer deformations, but incur a computational overhead. penalty : float, optional Determines the weight of the prior as opposed to the likelihood. (arbitrarily proportional to the ratio of the inverse variance of the gaussian deformations of the prior and the likelihood). Reduce this value if you want more deformations. rho : float, optional Determines the penalty of more granular coefficients. Increase to smoothen. Must be strictly positive. wavelet : str Wavelet type. See :class:`DisplacementFieldWavelet` for more information. maxiter : int, optional Maximum number of iterations per level. tol : float, optional Cost change must be less than `tol` before succesful termination at each coarse-to-fine level. first_level : int, optional First coarse-to-fine coefficient level. means : ndarray or None, optional Manually specify the means of the prior coefficients. If this and `variances` are set, then `penalty` and `rho` are unused. Must be of size ``(2, C)``, where `C` is the number of coefficients for the wavelet. variances : ndarray or None, optional Analagous to `means`, for specifying variances of the prior coefficients. Size should be the same as for `means`. llh_variances : ndarray or scalar, optional Specify log-likelihood variances per-pixel as a ``(W, H)`` array, or overall as a scalar. Default is 1.0, which can be seen as the variance being absorbed by the variance of the prior. debug_plot : bool, optional Output deformation progress live using :class:`PlottingWindow`. Returns ------- imdef : DisplacementFieldWavelet The deformation in the form of a :class:`DisplacementField`. info : dict Dictionary with info: * `cost`: The final cost value. Examples -------- Deform an image into a prototype image: >>> import amitgroup as ag >>> import numpy as np >>> import matplotlib.pylab as plt Load two example faces and perform the deformation: >>> F, I = ag.io.load_example('two-faces') >>> imdef, info = ag.stats.image_deformation(F, I, penalty=0.1) >>> Fdef = imdef.deform(F) Output the results: >>> ag.plot.deformation(F, I, imdef) >>> plt.show() """ assert rho > 0, "Parameter rho must be strictly positive" assert len(F.shape) == 2 and len(I.shape) == 2, "Images must be 2D ndarrays" assert _powerof2(F.shape[0]) and _powerof2(I.shape[1]), "Image sides must be powers of 2" assert F.shape == I.shape, "Images must have the same shape" #from scipy.optimize import fmin_bfgs from amitgroup.stats.fmin_bfgs_tol import fmin_bfgs_tol as fmin_bfgs level_capacity = last_level delF = np.asarray(np.gradient(F, 1/F.shape[0], 1/F.shape[1])) dx = 1/np.prod(F.shape) settings = dict( penalty=penalty, rho=rho, wavelet=wavelet, level_capacity=level_capacity, means=means, variances=variances, ) imdef = ag.util.DisplacementFieldWavelet(F.shape, **settings) x, y = imdef.meshgrid() if debug_plot: plw = ag.plot.PlottingWindow(figsize=(8, 4), subplots=(1,2)) def cb(uk): if not plw.tick(1): raise ag.AbortException() plw.imshow(imdef.deform(F), subplot=0) plw.imshow(I, subplot=1) else: cb = None min_cost = np.inf for level in range(start_level, last_level+1): ag.info("Running coarse-to-fine level", level) u = imdef.abridged_u(level) args = (imdef, F, I, delF, x, y, level, llh_variances) try: new_u, cost, min_deriv, Bopt, func_calls, grad_calls, warnflag = \ fmin_bfgs(_cost, u, _cost_deriv, args=args, callback=cb, tol=tol, maxiter=maxiter, full_output=True, disp=False) except ag.AbortException: return None, {} if cost < min_cost: # If the algorithm makes mistakes and returns a really high cost, don't use it. min_cost = cost imdef.u[:,:u.shape[1],:u.shape[2]] = new_u.reshape(u.shape) #if debug_plot: # plw.mainloop() return imdef, {'cost': min_cost}