The denoise algorithm in programming computer vision with Python is wrong, and the available code is posted on the web for later use.
The wrong code in the book:
defDenoise (im,u_init,tolerance=0.1,tau=0.125,tv_weight=100): M,n=Im.shape U=U_init Px=im Py=im Error= 1 while(Error >tolerance): Uold=U Gradux= Roll (U,-1,axis=1)-U Graduy= Roll (u,-1,axis=0)-U pxnew= Px + (tau/tv_weight) *Gradux pynew= Py + (tau/tv_weight) *Graduy normnew= Maximum (1,sqrt (pxnew**2+pynew**2)) Px= pxnew/normnew py= pynew/normnew rxpx= Roll (Px,1,axis=1) Rypy= Roll (py,1,axis=0) DIVP= (PX-RXPX) + (Py-rypy) U= im + tv_weight*DIVP Error= Linalg.norm (u-uold)/sqrt (nm)returnU,im-u
Code available on the Web:
defDenoise (IM, U_init, tolerance=0.1, tau=0.125, tv_weight=100): """An implementation of the Rudin-osher-fatemi (ROF) denoising model using the numerical procedure presented in E Q. (one) of A. Chambolle (2005). Implemented using periodic boundary conditions (essentially turning the rectangular image domain into a torus!). Input:im-noisy input Image (grayscale) u_init-initial guess for U tv_weight-weight Of the tv-regularizing term tau-steplength in the Chambolle algorithm tolerance-tolerance for Determinin G The Stop criterion Output:u-denoised and detextured image (also the primal variable) T-tex ture residual""" #---initializationM,n = Im.shape#size of Noisy imageU=U_init Px= IM#X-component to the dual fieldPy = IM#Y-component of the dual fieldError = 1Iteration=0#---Main iteration while(Error >tolerance): Uold=U#Gradient of primal variableLyu = Vstack ((u[1:,:],u[0,:]))#Left translation w.r.t. The y-directionLxU = Hstack ((U[:,1:],u.take ([0],axis=1))#Left translation w.r.t. The x-directionGradux= Lxu-u#x-component of U ' s gradientGraduy = Lyu-u#y-component of U ' s gradient #First We update the dual variblePxnew = Px + (tau/tv_weight) *gradux#non-normalized update of x-component (dual)Pynew = Py + (tau/tv_weight) *graduy#non-normalized update of y-component (dual)Normnew = Maximum (1,sqrt (pxnew**2+pynew**2)) Px= Pxnew/normnew#Update of X-component (dual)Py = Pynew/normnew#Update of Y-component (dual) #Then we update the primal variableRxpx =hstack ((Px.take ([ -1],axis=1), px[:,0:-1])#Right x-translation of X-componentRypy = Vstack ((py[-1,:],py[0:-1,:]))#Right y-translation of Y-componentDIVP = (px-rxpx) + (Py-rypy)#divergence of the dual field.U = im + TV_WEIGHT*DIVP#Update of the primal variable #Update of Error-measureError = Linalg.norm (u-uold)/sqrt (nm); Iteration+ = 1; PrintIteration, Error#The texture residualT = im-UPrint 'Number of ROF iterations:', IterationreturnU,t
Test code:
fromNumPyImport* fromNumPyImportRandom fromScipy.ndimageImportFiltersImportROF fromScipy.miscImportImsaveim= Zeros ((500,500)) im[100:400,100:400] = 128im[200:300,200:300] = 255im= im + 30*random.standard_normal (500,500)) Imsave ('synth_ori.pdf', IM) U,t= Rof.denoise (im,im,0.07) G= Filters.gaussian_filter (im,10) Imsave ('synth_rof.pdf', U) Imsave ('synth_gaussian.pdf'G