The following is my implementation of a paper for cauchy noise removal.
The psnr value of the noisy image is 19 as the paper but when I compute the psnr value for the restored image un, it returns 17 which is even smaller than the psnr value of the noisy image. I guess there is something wrong in psnr computation with my code.
%%
clear memory;
clear all
close all
clc;
%% Initialization
refimg = im2double(imread('cameraman256.png')); % original image
img_height = size(refimg,1);
img_width = size(refimg,2);
refimg = refimg(1:img_height,1:img_width);
padNum = 5;
refimg = padarray(refimg,[padNum,padNum],'symmetric');
[mm,nn]=size(refimg);
img_height = size(refimg,1);
img_width = size(refimg,2);
%% Producing the degraded image
A = 1; % A =1 for image denoising
sz = size(refimg);
rng(0);
r1 = randn(sz); % (using randn because I don't have the statistics toolbox)
r2 = randn(sz);
n = 0.02; % the noise level
u0 = refimg + n.*(r1./r2);
u0 = min(u0,1); % clamp large values to 1
u0 = max(u0,0); % clamp small values to 0
figure(1); imshow(u0(padNum+1:mm-padNum,padNum+1:nn-padNum),'border','tight');
%% Initial values for the primal-dual algorithm
tol = 1e-3;
nIter = 1e3;
options.order = 1; options.bound = 'sym';
un = u0;
wn = u0;
bun = un;
bwn = wn;
pxn = zeros(ny,nx);
pyn = zeros(ny,nx);
q = zeros(ny,nx);
[gxn,gyn] = grad(u0,options);
bgxn = gxn;
bgyn = gyn;
gamma = sqrt(2)/10;
lambda = 0.7;
mu = 6.25;
tau = 0.3;
sigma = 0.3;
%% Primal-dual Algorithm
for j = 1:nIter
%%%%%%%%%%solve the subproblem p
[ux,uy]=grad(bun,options);
pxn = pxn+sigma*(bgxn-ux);
pyn = pyn+sigma*(bgyn-uy);
%%%%%%%%%%%solve the subproblem q
AUk = Au(bun);
q = q+sigma*(bwn-AUk);
%%%%%%%%%%solve the subproblem g
goldxn = gxn;
goldyn = gyn;
txn = gxn-tau*pxn;
tyn = gyn-tau*pyn;
sn = max(1e-6,sqrt(txn.^2+tyn.^2));
gxn = txn./sn.*max(0,sn-tau);
gyn = tyn./sn.*max(0,sn-tau);
%%%%%%%%%%%solve the subproblem wn
u_medfilter = medfilt2(u0);
wold = wn;
a = mu.*lambda.*tau+1;
b = -(mu.*lambda.*tau.*(2.*u0+u_medfilter)-tau.*q+2.*u0+wold);
c = tau.*lambda+mu.*lambda.*tau.*(gamma.^2+u0.^2+2.*u_medfilter.*u0)-2.*tau.*q.*u0+...
gamma.^2+u0.^2+2.*wold.*u0;
d = -tau.*lambda.*u0-mu.*lambda.*tau.*u_medfilter.*(gamma.^2+u0.^2)+tau.*q.*(gamma.^2+u0.^2)...
-wold.*(gamma.^2+u0.^2);
qval = (3.*a.*c-(b.^2))./(9.*(a.^2));
rval = (9.*a.*b.*c-27.*(a.^2).*d-2.*(b.^3))./(54.*(a.^3));
deltaval = qval.^3+rval.^2;
wn = nthroot(rval+real(sqrt(deltaval)),3)+nthroot(rval-real(sqrt(deltaval)),3)-((b)./(3.*a));
%%%%%%%%%%%solve the subproblem un
uold = un;
Asqk = Atu(q);
un = un+tau*(Asqk-div(pxn,pyn,options)); % the restored image
% un = min(1,max(0.01,un));
if (norm(un-uold, 'fro')/norm(uold,'fro')<tol)
break;
end
bun = 2*un-uold;
bwn = 2*wn-wold;
bgxn = 2*gxn-goldxn;
bgyn = 2*gyn-goldyn;
% PSNR_restoredimage = psnr(refimg(padNum+1:mm-padNum,padNum+1:nn-b
padNum),un(padNum+1:mm-padNum,padNum+1:nn-padNum))
end
%% Dispaly results
New_un = un;
refimg = refimg(padNum+1:mm-padNum,padNum+1:nn-padNum);
u0 = u0(padNum+1:mm-padNum,padNum+1:nn-padNum);
u_medfilter = u_medfilter(padNum+1:mm-padNum,padNum+1:nn-padNum);
New_un = New_un(padNum+1:mm-padNum,padNum+1:nn-padNum);
PSNR_noisy = psnr(refimg,u0)
PSNR_med = psnr(refimg,u_medfilter)
PSNR_restoredimage = psnr(New_un,refimg)
figure(2); imshow([refimg,u_medfilter,New_un],'border','tight');
%%
The problem was not in psnr computation. The problem with my code in this question was that I was considering the denoising case but I had forgotten to omit the blur kernel in primal-dual algorithm. Also, the initial parameters corresponding to the deblurring case must be zero. The following is the corrected code. Now the psnr value is 28 similar to the paper.
%%
clear;
%% Initialization
refimg = im2double(imread('cameraman256.png')); % original image
img_height = size(refimg,1);
img_width = size(refimg,2);
refimg = refimg(1:img_height,1:img_width);
%% Producing the noisy image
sz = size(refimg);
rng(0);
r1 = randn(sz); % (using randn because I don't have the statistics toolbox)
r2 = randn(sz);
n = 0.02; % the noise level
u0 = refimg + n.*(r1./r2);
u0 = min(u0,1); % clamp large values to 1
u0 = max(u0,0); % clamp small values to 0
figure(1); imshow(u0,'border','tight');
%% Initial values for the primal-dual algorithm
init = u0;
[ny,nx] = size(init);
tol = 1e-3;
nIter = 1e3;
options.order = 1; options.bound = 'sym';
un = u0;
wn = zeros(ny,nx);
bun = un;
bwn = zeros(ny,nx);
pxn = zeros(ny,nx);
pyn = zeros(ny,nx);
q = zeros(ny,nx);
[gxn,gyn] = grad(u0,options);
bgxn = gxn;
bgyn = gyn;
gamma = sqrt(2)/10;
lambda = 0.7;
mu = 6.25;
tau = 0.3;
sigma = 0.3;
%% Primal-dual Algorithm
for j = 1:nIter
%%%%%%%%%%solve the subproblem p
[ux,uy]=grad(bun,options);
pxn = pxn+sigma*(bgxn-ux);
pyn = pyn+sigma*(bgyn-uy);
%%%%%%%%%%%solve the subproblem q
AUk = bun;
q = q+sigma*(bwn-AUk);
%%%%%%%%%%solve the subproblem g
goldxn = gxn;
goldyn = gyn;
txn = gxn-tau*pxn;
tyn = gyn-tau*pyn;
sn = max(1e-6,sqrt(txn.^2+tyn.^2));
gxn = txn./sn.*max(0,sn-tau);
gyn = tyn./sn.*max(0,sn-tau);
%%%%%%%%%%%solve the subproblem wn
u_medfilter = medfilt2(u0);
wold = wn;
a = mu.*lambda.*tau+1;
b = -(mu.*lambda.*tau.*(2.*u0+u_medfilter)-tau.*q+2.*u0+wold);
c = tau.*lambda+mu.*lambda.*tau.*(gamma.^2+u0.^2+2.*u_medfilter.*u0)-2.*tau.*q.*u0+...
gamma.^2+u0.^2+2.*wold.*u0;
d = -tau.*lambda.*u0-mu.*lambda.*tau.*u_medfilter.*(gamma.^2+u0.^2)+tau.*q.*(gamma.^2+u0.^2)...
-wold.*(gamma.^2+u0.^2);
qval = (3.*a.*c-(b.^2))./(9.*(a.^2));
rval = (9.*a.*b.*c-27.*(a.^2).*d-2.*(b.^3))./(54.*(a.^3));
deltaval = qval.^3+rval.^2;
wn = nthroot(rval+real(sqrt(deltaval)),3)+nthroot(rval-real(sqrt(deltaval)),3)-((b)./(3.*a));
%%%%%%%%%%%solve the subproblem un
uold = un;
Asqk = q;
un = un+tau*(Asqk-div(pxn,pyn,options)); % the restored image
if (norm(un-uold, 'fro')/norm(uold,'fro')<tol)
break;
end
bun = 2*un-uold;
bwn = 2*wn-wold;
bgxn = 2*gxn-goldxn;
bgyn = 2*gyn-goldyn;
end
%% Dispaly results
PSNR_noisy = psnr(u0,refimg)
PSNR_med = psnr(u_medfilter,refimg)
PSNR_restoredimage = psnr(un,refimg)
figure(2); imshow([refimg,u_medfilter,un],'border','tight');
%%
I'm trying to covert this Matlab code to Scilab, but I have some problems.
N = 101;
L = 4*pi;
x = linspace(0,L,N);
% It has three data set; 1: past, 2: current, 3: future.
u = zeros(N,3);
s = 0.5;
% Gaussian Pulse
y = 2*exp(-(x-L/2).^2);
u(:,1) = y;
u(:,2) = y;
% Plot the initial condition.
handle_line = plot(x,u(:,2),'LineWidth',2);
axis([0,L,-2,2]);
xlabel('x'); ylabel('u');
title('Wave equation');
% Dirichet Boundary conditions
u(1,:) = 0;
u(end,:) = 0;
filename = 'wave.gif';
for ii=1:100
disp(['at ii= ', num2str(ii)]);
u(2:end-1,3) = s*(u(3:end,2)+u(1:end-2,2)) ...
+ 2*(1-s)*u(2:end-1,2) ...
- u(2:end-1,1);
u(:,1) = u(:,2);
u(:,2) = u(:,3);
handle_line.YData = u(:,2);
drawnow;
frame = getframe(gcf);
im = frame2im(frame);
[A,map] = rgb2ind(im,256);
if ii==1
imwrite(A,map,filename,'gif','LoopCount',Inf,'DelayTime',0.05);
else
imwrite(A,map,filename,'gif','WriteMode','append','DelayTime',0.05);
end
end
I get an error for this line:
handle_line = plot(x,u(:,2),'LineWidth',2);
Error states: Wrong number of output arguments
What should i change to fix it?
The line
axis([0,L,-2,2]);
has to be translated in Scilab to
set(gca(),"data_bounds",[0,L,-2,2]);
Try this out:
N = 101;
L = 4*pi;
x = linspace(0,L,N);
% It has three data set; 1: past, 2: current, 3: future.
u = zeros(N,3);
s = 0.5;
% Gaussian Pulse
y = 2*exp(-(x-L/2).^2);
u(:,1) = y;
u(:,2) = y;
% Define a standard plot range for x and y
x_range=[min(x) max(x)];
y_range=[-max(y) max(y)];
% Plot the initial condition.
plot(x,u(:,2),'LineWidth',2);
axis([0,L,-2,2]);
xlabel('x'); ylabel('u');
title('Wave equation');
% Dirichet Boundary conditions
u(1,:) = 0;
u(end,:) = 0;
filename = 'wave.gif';
for ii=1:100
disp(['at ii= ', num2str(ii)]);
u(2:end-1,3) = s*(u(3:end,2)+u(1:end-2,2)) ...
+ 2*(1-s)*u(2:end-1,2) ...
- u(2:end-1,1);
u(:,1) = u(:,2);
u(:,2) = u(:,3);
plot(x,u(:,2),'LineWidth',2);
axis([x_range y_range]);
frame = getframe(gcf);
im = frame2im(frame);
[A,map] = rgb2ind(im,256);
if ii==1
imwrite(A,map,filename,'gif','LoopCount',Inf,'DelayTime',0.05);
else
imwrite(A,map,filename,'gif','WriteMode','append','DelayTime',0.05);
end
end
I removed the output and added axis limit independently.
The below code is something that I am cooking up. I am plotting the orbits of the Sun, Mercury, Earth and the Moon. I have gotten this far into the project but the orbit of Mercury is terrifyingly wrong. This is seen by typing "SunEarthMoon(2,50)" at the command prompt and viewing the bottom left plot. The logic behind the project is utilizing Newton's Second Law toggled with the command "ode45" to find the positions of the bodies during a given time interval. I've been staring at this for far too long. Can anyone help to fix the orbit of Mercury?
function [] = SunEarthMoon(years,framerate)
%% Clean Up
close all
clc
%% Initializaion
x_earth = 147300000000; % [m]
x_mercury = 57.91e9; % [m]
v_earth = 30257; % [m/s]
v_mercury = 47362; % [m/s]
r_sat = 384748000; % earth surface [m]
r_earth = 6367000; % earth radius [m]
v_sat = 1023; % relative velocity from earth [m/s]
a = 5.145; % Angle to vertical (y) axis
b = 90; % Angle to horizontal (x) axis in xz plane
x_earth_o = [x_earth; 0; 0];
x_sun_o = [0; 0; 0];
x_mercury_o = [x_mercury; 0; 0];
x_sat_o = [x_earth+r_sat+r_earth; 0; 0];
v_earth_o = [0; v_earth; 0];
v_sun_o = [0; 0; 0];
v_mercury_o = [0; v_mercury; 0];
v_sat_o = v_sat*[cos(pi/180*b)*sin(pi/180*a); cos(pi/180*a); sin(pi/180*b)*sin(pi/180*a)] + v_earth_o;
interval = years*[0 31536000];
%% Error Control
h = [0.01 36000];
tol = 100000;
Options.AbsTol = tol;
Options.MaxStep = h(2);
Options.InitialStep = h(1);
%% Analysis
ao = [x_earth_o; v_earth_o; x_sun_o; v_sun_o; x_sat_o; v_sat_o; x_mercury_o; v_mercury_o];
[t, x] = ode45(#earthfinal,interval,ao,Options);
for i = 1:length(t)
R1(i) = (x(i,13)-x(i,1));
R2(i) = (x(i,14)-x(i,2));
R3(i) = (x(i,15)-x(i,3));
R(i) = sqrt(R1(i)^2+R2(i)^2+R3(i)^2);
end
T_index_earth = find([1; x(:,4)].*[x(:,4);1]<=0);
T_index_moon = find([1; R2(:)].*[R2(:); 1]<=0);
for i = 4:length(T_index_earth)
T_earth_semi(i-3) = (t(T_index_earth(i)-1)-t(T_index_earth(i-2)-1))/24/60/60;
end
T_earth = mean(T_earth_semi);
for i = 4:length(T_index_moon)
T_moon_semi(i-3) = (t(T_index_moon(i)-1)-t(T_index_moon(i-2)-1))/24/60/60;
end
T_moon = mean(T_moon_semi);
D_earth = 0;
for i = 2:(T_index_earth(4)-1)
D_earth = D_earth + sqrt((x(i,1)-x(i-1,1))^2+(x(i,2)-x(i-1,2))^2+(x(i,3)-x(i-1,3))^2);
end
D_moon = 0;
for i = 2:(T_index_moon(4)-1)
D_moon = D_moon + sqrt((R1(i)-R1(i-1))^2+(R2(i)-R2(i-1))^2+(R3(i)-R3(i-1))^2);
end
%% Plots
q = framerate;
scrsz = get(0,'ScreenSize');
figure('position', [0.05*scrsz(3) 0.05*scrsz(4) 0.75*scrsz(3) 0.85*scrsz(4)])
set(gcf,'name','Sun, Earth, and Moon Orbits')
for i = 1:length(t)/q
subplot(2,2,1)
plot3(x(1:i*q,1),x(1:i*q,2),x(1:i*q,3),'g',x(1:i*q,7),x(1:i*q,8),x(1:i*q,9),'r',x(1:i*q,13),x(1:i*q,14),x(1:i*q,15),'b',x(1:i*q,19),x(1:i*q,20),x(1:i*q,21),'black')
axis(1.1*[min(x(:,1)) max(x(:,1)) min(x(:,2)) max(x(:,2)) 2*min(x(:,15)) 2*max(x(:,15))])
xlabel('Universal X Coordinate (m)')
ylabel('Universal Y Coordinate (m)')
zlabel('Universal Z Coordinate (m)')
title('Relative Orbits')
legend('Earth','Sun','Moon')
hold on
plot3(x(i*q,1),x(i*q,2),x(i*q,3),'g-o',x(i*q,7),x(i*q,8),x(i*q,9),'r-o',x(i*q,13),x(i*q,14),x(i*q,15),'b-o',x(i*q,19),x(i*q,20),x(i*q,21),'black-o')
hold off
subplot(2,2,2)
plot3(R1(1:i*q),R2(1:i*q),R3(1:i*q),'b',zeros(1,i*q),zeros(1,i*q),zeros(1,i*q),'g')
axis(1.5*[min(R1) max(R1) min(R2) max(R2) min(R3) max(R3)])
xlabel('Universal X Coordinate (m)')
ylabel('Universal Y Coordinate (m)')
zlabel('Universal Z Coordinate (m)')
title('Relative Moon Orbit About Earth')
hold on
plot3(R1(i*q),R2(i*q),R3(i*q),'b-o',0,0,0,'g-o')
text(0,1.45*max(R2),1.40*max(R3),sprintf('Orbital Period, T = %3.5g days',T_moon))
text(0,1.45*max(R2),1.15*max(R3),sprintf('Orbital Circumference, D = %3.5g gigameters',D_moon*1e-9))
hold off
subplot(2,2,3)
plot(x(1:i*q,1),x(1:i*q,2),'g',x(1:i*q,7),x(1:i*q,8),'r', x(1:i*q,19),x(1:i*q,20),'black')
axis(1.5*[min(x(:,1)) max(x(:,1)) min(x(:,2)) max(x(:,2))])
xlabel('Universal X Coordinate (m)')
ylabel('Universal Y Coordinate (m)')
title('Relative Earth Orbit About Sun')
hold on
plot(x(i*q,1),x(i*q,2),'g-o',x(i*q,7),x(i*q,8),'r-o',x(i*q,19),x(i*q,20),'black-o')
text(1.45*min(x(:,1)),1.40*max(x(:,2)),sprintf('Orbital Period, T = %3.5g days',T_earth))
text(1.45*min(x(:,1)),1.25*max(x(:,2)),sprintf('Orbital Circumference, D = %3.5g gigameters',D_earth*1e-9))
text(1.45*min(x(:,1)),1.40*min(x(:,2)),sprintf('Time, t = %3.3g days',round(t(q*i)/24/60/60)))
hold off
subplot(2,2,4)
plot(t(1:i*q)/(60*60*24),R(1:i*q)/1000,'b')
axis([t(1)/24/60/60 t(end)/24/60/60 0.999*min(R)/1000 1.001*max(R)/1000])
xlabel('Time,t (days)')
ylabel('Orbit Radius, R (km)')
title('Moon-Earth Distance')
hold on
plot(t(i*q)/(60*60*24),R(i*q)/1000,'b-o')
hold off
drawnow
end
end
%% Differential Equation Function
function [udot]= earthfinal(t,u)
m_earth = 5.9742e24; % [kg]
m_mercury = 3.285e23; % [kg]
m_sun = 1.98892e30; % [kg]
m_sat = 11110; % [kg]
G = 6.67300e-11; %[(m)^3(kg)^-1(s)^-2];
d_earth_sun = sqrt((u( 7,1)-u(1,1))^2+(u( 8,1)-u(2,1))^2+(u( 9,1)-u(3,1))^2);
d_earth_sat = sqrt((u(13,1)-u(1,1))^2+(u(14,1)-u(2,1))^2+(u(15,1)-u(3,1))^2);
d_sun_sat = sqrt((u(13,1)-u(7,1))^2+(u(14,1)-u(8,1))^2+(u(15,1)-u(9,1))^2);
d_mercury_sun = sqrt((u(7,1) -u(19,1))^2 + (u(8,1) - u(20,1))^2 + (u(9,1)-u(21,1))^2);
d_mercury_earth = sqrt((u(1,1) -u(19,1))^2 + (u(2,1) - u(20,1))^2 + (u(3,1)-u(21,1))^2);
d_mercury_sat = sqrt((u(13,1) -u(19,1))^2 + (u(14,1) - u(20,1))^2 + (u(15,1)-u(21,1))^2);
% Earth motion
udot( 1,1) = u(4,1);
udot( 2,1) = u(5,1);
udot( 3,1) = u(6,1);
udot( 4,1) = m_sun*G*(u(7,1)-u(1,1))/d_earth_sun^3 + m_sat*G*(u(13,1)-u(1,1))/d_earth_sat^3 + m_mercury*G*(u(19,1)-u(1,1))/d_mercury_earth^3;
udot( 5,1) = m_sun*G*(u(8,1)-u(2,1))/d_earth_sun^3 + m_sat*G*(u(14,1)-u(2,1))/d_earth_sat^3 + m_mercury*G*(u(20,1)-u(2,1))/d_mercury_earth^3;
udot( 6,1) = m_sun*G*(u(9,1)-u(3,1))/d_earth_sun^3 + m_sat*G*(u(15,1)-u(3,1))/d_earth_sat^3 + m_mercury*G*(u(21,1)-u(3,1))/d_mercury_earth^3;
% Sun Motion
udot( 7,1) = u(10,1);
udot( 8,1) = u(11,1);
udot( 9,1) = u(12,1);
udot(10,1) = m_earth*G*(u(1,1)-u(7,1))/d_earth_sun^3 + m_sat*G*(u(13,1)-u(7,1))/d_sun_sat^3 + m_mercury*G*(u(19,1)-u(7,1))/d_mercury_sun^3;
udot(11,1) = m_earth*G*(u(2,1)-u(8,1))/d_earth_sun^3 + m_sat*G*(u(14,1)-u(8,1))/d_sun_sat^3 + m_mercury*G*(u(20,1)-u(8,1))/d_mercury_sun^3;
udot(12,1) = m_earth*G*(u(3,1)-u(9,1))/d_earth_sun^3 + m_sat*G*(u(15,1)-u(9,1))/d_sun_sat^3 + m_mercury*G*(u(21,1)-u(9,1))/d_mercury_sun^3;
% Satellite Motion
udot(13,1) = u(16,1);
udot(14,1) = u(17,1);
udot(15,1) = u(18,1);
udot(16,1) = m_earth*G*(u(1,1)-u(13,1))/d_earth_sat^3 + m_sun*G*(u(7,1)-u(13,1))/d_sun_sat^3 + m_mercury*G*(u(19,1)-u(13,1))/d_mercury_sat^3;
udot(17,1) = m_earth*G*(u(2,1)-u(14,1))/d_earth_sat^3 + m_sun*G*(u(8,1)-u(14,1))/d_sun_sat^3 + m_mercury*G*(u(20,1)-u(14,1))/d_mercury_sat^3;
udot(18,1) = m_earth*G*(u(3,1)-u(15,1))/d_earth_sat^3 + m_sun*G*(u(9,1)-u(15,1))/d_sun_sat^3 + m_mercury*G*(u(21,1)-u(15,1))/d_mercury_sat^3;
% Mercury Motion
udot(19,1) = u(22,1);
udot(20,1) = u(23,1);
udot(21,1) = u(24,1);
udot(22,1) = m_sun*G*(u(7,1)-u(19,1))/d_mercury_sun^3 + m_earth*G*(u(1,1)-u(19,1))/d_mercury_earth^3 + m_sat*G*(u(13,1)-u(19,1))/d_mercury_sat^3;
udot(23,1) = m_sun*G*(u(8,1)-u(20,1))/d_mercury_sun^3 + m_earth*G*(u(2,1)-u(20,1))/d_mercury_earth^3 + m_sat*G*(u(14,1)-u(20,1))/d_mercury_sat^3;
udot(24,1) = m_sun*G*(u(9,1)-u(21,1))/d_mercury_sun^3 + m_earth*G*(u(3,1)-u(21,1))/d_mercury_earth^3 + m_sat*G*(u(15,1)-u(21,1))/d_mercury_sat^3;
end