|
| 1 | +# -*- coding: utf-8 -*- |
| 2 | +""" |
| 3 | +Created on Wed Aug 18 00:56:27 2021 |
| 4 | +
|
| 5 | +@author: cosmi |
| 6 | +""" |
| 7 | +import numpy as np |
| 8 | + |
| 9 | + |
| 10 | +def denoise(im,U_init,tolerance=0.1,tau=0.125,tv_weight=100): |
| 11 | + |
| 12 | + |
| 13 | + |
| 14 | + """ |
| 15 | + Removing noise from images is important for many applications, from making |
| 16 | +your personal photos look better to improving the quality of satellite and increasingly |
| 17 | +drone images. |
| 18 | +
|
| 19 | +In image processing denoising functionally looks like we are smoothing out the image. |
| 20 | +but just what is it we are smoothing out to remove the noise? |
| 21 | +
|
| 22 | +The ROF model has the interesting property that it finds a smoother version |
| 23 | +of the image while preserving edges and structures. |
| 24 | +
|
| 25 | +The underlying mathematics of the ROF model and the solution techniques are |
| 26 | +quite advanced and are showcased fully in the paper: |
| 27 | +
|
| 28 | +Nonlinear total variation based noise removal algorithms* |
| 29 | +Leonid I. Rudin 1, Stanley Osher and Emad Fatemi |
| 30 | +Cognitech Inc., 2800, 28th Street, Suite 101, Santa Monica, CA 90405, USA. circa 1992. |
| 31 | +
|
| 32 | +Its interesting to note that the authors base their work on work done previously |
| 33 | +by Geman and Reynolds in which they propse to minimisae the non-linear functionals |
| 34 | +asscoaited with noise in the total varience by use of simulated annealing, a |
| 35 | +metaheursitics technique, which would have been very slow to do using the computers |
| 36 | +available in the late 1980s something |
| 37 | +which drove the development of the ROF denoising model in the first place. |
| 38 | +The authors wanted a fast solver that could find a reasonably good local minima |
| 39 | +rather tha the ideal global minima. |
| 40 | +
|
| 41 | +Here I'll give a brief, |
| 42 | +simplified introduction before showing how to implement a ROF solver based |
| 43 | +on an algorithm by Chambolle. |
| 44 | +
|
| 45 | +The solver used in this code is a modified version that uses grdient descent/ |
| 46 | +reprojection method to achieve total variance (TV) minimization/regularization |
| 47 | +The integral of the gradient across an image, any image, will produce the total varience |
| 48 | +in tha image. now, for noisy images the total varience will be higher. knowing this, |
| 49 | +denoising techniques have been developed that essentially minimise the total varience |
| 50 | +in the matrix element of an image and then reproject that image onto the original by substracting |
| 51 | +the imaginary form of the original image matrix element which contains the residiual texture |
| 52 | +of the image. so textures are effectively removed when we want to do TV minimization/regularization. |
| 53 | +
|
| 54 | +
|
| 55 | +
|
| 56 | +To minimise the total varience in the matrix element different algorithms can be used |
| 57 | +but one of the most popular is gradient descent, which is simular to the simulated annealing |
| 58 | +technique originally proposed but more computationally tractable. |
| 59 | +
|
| 60 | +
|
| 61 | +in gradient descent the image matrix containing the greyscale pixel values are |
| 62 | +essentially represented as an energy surface, whereby |
| 63 | +we want to descend into the global minima. the different values in the matrix represent |
| 64 | +the interaction energies of the nearest neighbour in this 2D energy surface. |
| 65 | +different algorithms can use |
| 66 | +different equations to represent the interaction energies, depending on the rate at which |
| 67 | +the interaction energies converge to a global minima in a certain steplength of |
| 68 | +iteration of the algorithm. |
| 69 | +
|
| 70 | +
|
| 71 | +
|
| 72 | +Interesting Note: When implented using periodic boundary conditions the TV minimization using |
| 73 | +an iteractive gradient descent on an image performs 2 transformations on that |
| 74 | +images rectangular image domain where the greyscale pixel values exist. 2 transformations |
| 75 | +on a rectangle result in the formation of a torus in a transformation which |
| 76 | +preserves the images pixel data but changes the domain topology. |
| 77 | + |
| 78 | + |
| 79 | + |
| 80 | + |
| 81 | + An implementation of the Rudin-Osher-Fatemi (ROF) denoising model |
| 82 | + using the numerical procedure presented in equation 11 on pg 15 of |
| 83 | + A. Chambolle (2005) |
| 84 | + http://www.cmap.polytechnique.fr/preprint/repository/578.pdf |
| 85 | + |
| 86 | + |
| 87 | + Input: |
| 88 | + im - noisy input image (grayscale) |
| 89 | + U_init - initial guess for U |
| 90 | + tv_weight - weight of the TV-regularizing term |
| 91 | + tau - steplength in the Chambolle algorithm |
| 92 | + tolerance - tolerance for determining the stop criterion |
| 93 | + |
| 94 | + Output: |
| 95 | + U - denoised and detextured image (also the primal variable) |
| 96 | + T - texture residual |
| 97 | + |
| 98 | +
|
| 99 | +
|
| 100 | +
|
| 101 | +
|
| 102 | + Input: noisy input image (grayscale), initial guess for U, weight of |
| 103 | + the TV-regularizing term, steplength, tolerance for stop criterion. |
| 104 | +
|
| 105 | + Output: denoised and detextured image, texture residual. """ |
| 106 | + |
| 107 | + m,n = im.shape # size of noisy image |
| 108 | + |
| 109 | + # initialize |
| 110 | + U = U_init |
| 111 | + Px = im # x-component to the dual field |
| 112 | + Py = im # y-component of the dual field |
| 113 | + error = 1 |
| 114 | + iteration = 0 |
| 115 | + |
| 116 | + |
| 117 | + |
| 118 | + while (error > tolerance): |
| 119 | + Uold = U |
| 120 | + |
| 121 | + # gradient of primal variable |
| 122 | + GradUx = np.roll(U,-1,axis=1)-U # x-component of U's gradient |
| 123 | + GradUy = np.roll(U,-1,axis=0)-U # y-component of U's gradient |
| 124 | + |
| 125 | + # update the dual varible |
| 126 | + PxNew = Px + (tau/tv_weight)*GradUx |
| 127 | + PyNew = Py + (tau/tv_weight)*GradUy |
| 128 | + NormNew = np.maximum(1,np.sqrt(PxNew**2+PyNew**2)) |
| 129 | + |
| 130 | + Px = PxNew/NormNew # update of x-component (dual) |
| 131 | + Py = PyNew/NormNew # update of y-component (dual) |
| 132 | + """ |
| 133 | + the function roll(), which, as the name suggests, “rolls” the values of an array |
| 134 | + cyclically around an axis. This is very convenient for computing neighbor differences, |
| 135 | + in this case for derivatives. We also used linalg.norm(), which measures the difference |
| 136 | + between two arrays (in this case, the image matrices U and Uold). |
| 137 | + """ |
| 138 | + # update the primal variable |
| 139 | + RxPx = np.roll(Px,1,axis=1) # right x-translation of x-component |
| 140 | + RyPy = np.roll(Py,1,axis=0) # right y-translation of y-component |
| 141 | + |
| 142 | + DivP = (Px-RxPx)+(Py-RyPy) # divergence of the dual field. |
| 143 | + U = im + tv_weight*DivP # update of the primal variable |
| 144 | + |
| 145 | + # update of error |
| 146 | + error = np.linalg.norm(U-Uold)/np.sqrt(n*m); |
| 147 | + |
| 148 | + iteration += 1; |
| 149 | + |
| 150 | + #The texture residual |
| 151 | + T = im - U |
| 152 | + #print: 'Number of ROF iterations: ', iteration |
| 153 | + |
| 154 | + return U,T # denoised image and texture residual |
| 155 | + |
| 156 | + |
| 157 | + |
| 158 | + |
0 commit comments