# Documentation

## Translation Invariant Denoising with Cycle Spinning

Cycle spinning compensates for the lack of shift invariance in the critically-sampled wavelet transform by averaging over denoised cyclically-shifted versions of the signal or image. The appropriate inverse circulant shift operator is applied to the denoised signal/image and the results are averaged together to obtain the final denoised signal/image.

There are N unique cyclically-shifted versions of a signal of length, N. For an M-by-N image, there are MN versions. This makes using all possible shifted versions computationally prohibitive. However, in practice, good results can be obtained by using a small subset of the possible circular shifts.

### 1-D Cycle Spinning

This example shows how to denoise a 1-D signal using cycle spinning and the shift-variant orthogonal nonredundant wavelet transform. The example compares the results of the two denoising methods.

Create a noisy 1-D bumps signal with a signal-to-noise ratio of 6. The signal-to-noise ratio is defined as

$\frac{N||X|{|}_{2}^{2}}{{\sigma }^{2}}$

where N is the length of the signal, ||X||22 is the squared 2 norm, and σ2 is the variance of the noise.

rng default;
[X,XN] = wnoise('bumps',10,sqrt(6));
subplot(211)
plot(X); title('Original Signal');
subplot(212)
plot(XN); title('Noisy Signal');

Denoise the signal using cycle spinning with 15 shifts, 7 to the left and 7 to the right, including the zero-shifted signal. Use Daubechies' least-asymmetric wavelet with 4 vanishing moments (sym4) and denoise the signal down to level 4 using soft thresholding and the universal threshold estimated from the level-1 detail coefficients.

ydenoise = zeros(length(XN),15);
for nn = -7:7
yshift = circshift(XN,[0 nn]);
[yd,cyd] = wden(yshift,'sqtwolog' ,'s','sln',4,'sym4');
ydenoise(:,nn+8) = circshift(yd,[0, -nn]);
end
ydenoise = mean(ydenoise,2);

Denoise the signal using the orthogonal nonredundant discrete wavelet transform (DWT) with the same parameters. Compare the orthogonal DWT with cycle spinning.

xd = wden(XN,'sqtwolog','s','sln',4,'sym4');
subplot(211)
plot(ydenoise,'b','linewidth',2);
hold on;
plot(X,'r')
axis([1 1024 -10 10]);
legend('Denoised Signal','Original Signal','Location','SouthEast');
ylabel('Amplitude');
title('Cycle Spinning Denoising');
subplot(212)
plot(xd,'b','linewidth',2);
hold on;
plot(X,'r');
axis([1 1024 -10 10]);
legend('Denoised Signal','Original Signal','Location','SouthEast');
xlabel('Sample'); ylabel('Amplitude');
title('Standard Orthogonal Denoising');
absDiffDWT = norm(X-xd,2)
absDiffCycleSpin = norm(X-ydenoise',2)
absDiffDWT =

18.0428

absDiffCycleSpin =

15.4778

Cycle spinning with only 15 shifts has reduced the approximation error.

### 2-D Cycle Spinning

This example shows how to denoise an image using cycle spinning with 82 = 64 shifts.

Load the sine image and add zero-mean white Gaussian noise with a variance of 5.

rng default;
Xnoisy = X+sqrt(5)*randn(size(X));
subplot(211)
imagesc(X); colormap(jet);
title('Original Image');
subplot(212)
imagesc(Xnoisy); title('Noisy Image');

Determine the universal threshold from the level-1 detail coefficients. Use the B-spline biorthogonal wavelet with 3 vanishing moments in the reconstruction wavelet and 5 vanishing moments in the decomposition wavelet.

wname = 'bior3.5';
[C,S] = wavedec2(Xnoisy,1,wname);
Cdet = C(4097:end);
THR = thselect(Cdet,'sqtwolog');

Create a grid of 8 shifts in both the X and Y directions. This results in a total of 64 shifts.

N = 8;
[deltaX, deltaY] = ndgrid(0:N-1,0:N-1);

Allocate a matrix of zeros the size of the image for the cycle spinning result. Specify soft thresholding and set the level to 3.

Xspin = zeros(size(X));
sorh = 's';
level = 3;

Use cycle spinning denoising and display the result.

for nn =1:N^2

Xshift = circshift(Xnoisy, [deltaX(nn) deltaY(nn)]);
[coefs,sizes] = wavedec2(Xshift,level,wname);
[XDEN,cfsDEN,dimCFS] = wdencmp('gbl',coefs,sizes, ...
wname,level,THR,sorh,1);
XDEN = circshift(XDEN, -[deltaX(nn) deltaY(nn)]);
Xspin = Xspin*(nn-1)/nn+XDEN/nn;

end

subplot(211)
imagesc(X); colormap(jet);
title('Original Image');
subplot(212)
imagesc(Xspin); title('Cycle Spinning');

Denoise the image using the identical parameters with the nonredundant DWT. Compare the peak signal-to-noise (PSNR), mean square error, and energy ratios obtained with cycle spinning and the nonredundant DWT.

[coefs,sizes] = wavedec2(Xnoisy,level,wname);
[XDEN,cfsDEN,dimCFS] = wdencmp('gbl',coefs,sizes,wname,3,THR,'s',1);
[PSNRcs,MSEcs,~,L2RATcs] = measerr(X,Xspin)
[PSNR,MSE,~,L2RAT] = measerr(X,XDEN)

The error measures show that cycle spinning has improved the image approximation. The PSNR, mean square error, and energy ratio are all better in the image denoised with cycle spinning.