% première partie:

% utiliser une des deux images proposées (N&B ou couleur), et l'un des masques:

% image 1
I=double(imread('cameraman.tif'));
figure, imshow(uint8(I)); 

% image 2
I=double(imread('couple.tiff'));
figure, imshow(uint8(I)); 

% masque 1 
M=ones(size(I,1),size(I,2));
M(140:150,50:200)=0;

% masque 2 
M=zeros(size(I,1),size(I,2));
M(1:4:end,1:4:end)=1;
M(1:end,1)=1;
M(1:end,end)=1;
M(end,1:end)=1;
M(1,1:end)=1;

% masque 3 
M=zeros(size(I,1),size(I,2));
M(10:10:250,10:10:250)=1;
M(1:end,1)=1;
M(1:end,end)=1;
M(end,1:end)=1;
M(1,1:end)=1;

% masque 4
M=zeros(size(I,1),size(I,2));
M(10:10:end,:)=1;
M(:,10:10:end)=1;
M(1:end,1)=1;
M(1:end,end)=1;
M(end,1:end)=1;
M(1,1:end)=1;

% masque 5
M=double(imread('masque_rand.png')==255);
M=M(:,:,1);
M(1:end,1)=1;
M(1:end,end)=1;
M(end,1:end)=1;
M(1,1:end)=1;


% image niveaux de gris
Ima=I.*M;
figure, imshow(uint8(Ima)); 
tic
Ima2=Poisson_solve(Ima,M);
toc
figure, imshow(uint8(Ima2)); 


% pour une image couleur:
Ima=I.*repmat(M,[1 1 3]);
figure, imshow(uint8(Ima));
tic
Ima2R=Poisson_solve(Ima(:,:,1),M);
toc
tic
Ima2G=Poisson_solve(Ima(:,:,2),M);
toc
tic
Ima2B=Poisson_solve(Ima(:,:,3),M);
toc
Ima2=zeros(size(Ima));
Ima2(:,:,1)=Ima2R;
Ima2(:,:,2)=Ima2G;
Ima2(:,:,3)=Ima2B;
figure, imshow(uint8(Ima2));


% Sample (mystère)
clear all, close all
Ima=double(imread('sample.png'));
%M=not(Ima(:,:,1)==0);
M=boolean(Ima(:,:,1));
M(1:end,end)=1;
M(1:end,1)=1;
M(1,1:end)=1;
M(end,1:end)=1;
figure, imshow(uint8(Ima));
tic
Ima2R=Poisson_solve(Ima(:,:,1),M);
toc
tic
Ima2G=Poisson_solve(Ima(:,:,2),M);
toc
tic
Ima2B=Poisson_solve(Ima(:,:,3),M);
toc
Ima2=zeros(size(Ima));
Ima2(:,:,1)=Ima2R;
Ima2(:,:,2)=Ima2G;
Ima2(:,:,3)=Ima2B;
figure, imshow(uint8(Ima2));




% deuxième partie:
% seamless cloning

clear all, close all


% exemple moon+tedx
%%%%%%%%%%%%%%%%%%%

clear all, close all

I1=double(imresize(imread('The_Earth_seen_from_Apollo_17.jpg'),.55));
I2=double(imread('tedx.jpg'));

M=(I1(:,:,1)<6);
M(1:end,1)=1;
M(1:end,end)=1;
M(end,1:end)=1;
M(1,1:end)=1;

figure, imshow(uint8(I1));
figure, imshow(uint8(I2));
figure, imagesc(M);

MM=ones(size(I2,1),size(I2,2));
MM(21:size(M,1)+20,421:size(M,2)+420)=M;

% copy / paste
Ima2cp=I2;
MMb=repmat(MM,1,1,3);
Mb=repmat(M,1,1,3);
Ima2cp(find(~MMb))=I1(find(~Mb));
figure, imshow(uint8(Ima2cp))


% seamless cloning
[Gx,Gy]=gradient(I1*.6);
GGx=zeros(size(I2));
GGy=zeros(size(I2));
GGx(21:size(Gx,1)+20,421:size(Gx,2)+420,:)=Gx;
GGy(21:size(Gy,1)+20,421:size(Gy,2)+420,:)=Gy;

Ima2b=zeros(size(I2));
Ima2b(:,:,1)=Poisson_solve_guided(I2(:,:,1),MM,GGx(:,:,1),GGy(:,:,1));
Ima2b(:,:,2)=Poisson_solve_guided(I2(:,:,2),MM,GGx(:,:,2),GGy(:,:,2));
Ima2b(:,:,3)=Poisson_solve_guided(I2(:,:,3),MM,GGx(:,:,3),GGy(:,:,3));

figure, imshow(uint8(Ima2b));


% à comparer à:
% mélange de gradients 
[G2x,G2y]=gradient(I2);
NGG=GGx.^2+GGy.^2;
NG2=G2x.^2+G2y.^2;
GGx=GGx.*(NGG>=NG2)+G2x.*(NGG<NG2);
GGy=GGy.*(NGG>=NG2)+G2y.*(NGG<NG2);

Ima2=zeros(size(I2));
Ima2(:,:,1)=Poisson_solve_guided(I2(:,:,1),MM,GGx(:,:,1),GGy(:,:,1));
Ima2(:,:,2)=Poisson_solve_guided(I2(:,:,2),MM,GGx(:,:,2),GGy(:,:,2));
Ima2(:,:,3)=Poisson_solve_guided(I2(:,:,3),MM,GGx(:,:,3),GGy(:,:,3));

figure, imshow(uint8(Ima2));

