-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPoissonImageEditing.m
More file actions
160 lines (104 loc) · 3.74 KB
/
PoissonImageEditing.m
File metadata and controls
160 lines (104 loc) · 3.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
function [seamless,A] = PoissonImageEditing
% read images
target= im2double(imread('target_3.jpg'));
source= im2double(imread('source_3.jpg'));
% mask image
mask=imread('mask_3.bmp');
% image offsets, para desplazar la masacara a diferentes posiciones
% de la imagen target, i.e. el background, en este ejemplo se desplaza
% el avion
row_offset=0;
col_offset=220;
% N: Number of pixels in the mask
N=sum(mask(:));
% enumerating pixels in the mask
mask_id = zeros(size(mask));
mask_id(mask) = 1:N;
% neighborhood size for each pixel in the mask
[ir,ic] = find(mask);
Np = zeros(N,1);
for ib=1:N
i = ir(ib);
j = ic(ib);
% No se utiliza en realidad
% Obtener el numero de vecinos de cada pixel de la mascara
% incluyendo el offset de columnas y filas
Np(ib)= double((row_offset+i> 1))+ ...
double((col_offset+j> 1))+ ...
double((row_offset+i< size(target,1))) + ...
double((col_offset+j< size(target,2)));
end
% compute matrix A
% your CODE begins here
% Inicializar matriz sparse cuadrada de longitd igual al numero de pixeles
% en la mascara e inicializar los valores de los kernel
A = 4*speye(N);
% Iterar por cada fila (cada pixel) para ir llenando la matriz sparse
% con los vecinos izquierdos y derechos
for p = 1:N
% Condicional para saber si se está fuera del boundarie
% de la mascara el pixel vecino izquierdo
if mask(ir(p),ic(p)-1)
% Colocar valor en la matriz sparse para el vecino izquierdo
A(p,mask_id(ir(p),ic(p)-1)) = -1;
end
% Para pixel derecho
if mask(ir(p),ic(p)+1)
% Colocar valor en la matriz sparse para el vecino derecho
A(p,mask_id(ir(p),ic(p)+1)) = -1;
end
% Pixel vecino superior
if mask(ir(p)-1,ic(p))
% Colocar valor en la matriz sparse para el vecino superior
A(p,p-1) = -1;
end
% Pixel vecino inferior
if mask(ir(p)+1,ic(p))
% Colocar valor en la matriz sparse para el vecino inferior
A(p,p+1) = -1;
end
end
% your CODE ends here
% output intialization
seamless = target;
for color=1:3 % solve for each colorchannel
% compute b for each color
b=zeros(N,1);
for ib=1:N
i = ir(ib);
j = ic(ib);
if (i>1)
% acumulador + boundarie condition + centro kernel + lado
% correspondiente del kernel, el (1-mask(i-1,j)) detecta
% automaticamente si se trata de un pixel en el boundarie,
% se suma el mismo pixel central unicamente las veces que hay pixeles
% vecinos del kernel para promediar adecuadamente
b(ib) = b(ib) + target(row_offset+i-1,col_offset+j,color)*(1-mask(i-1,j))+...
source(i,j,color)-source(i-1,j,color);
end
if (i<size(mask,1))
b(ib)=b(ib)+ target(row_offset+i+1,col_offset+j,color)*(1-mask(i+1,j))+ ...
source(i,j,color)-source(i+1,j,color);
end
if (j>1)
b(ib)= b(ib) + target(row_offset+i,col_offset+j-1,color)*(1-mask(i,j-1))+...
source(i,j,color)-source(i,j-1,color);
end
if (j<size(mask,2))
b(ib)= b(ib)+ target(row_offset+i,col_offset+j+1,color)*(1-mask(i,j+1))+...
source(i,j,color)-source(i,j+1,color);
end
end
% solve linear system A*x = b;
% your CODE begins here
x = A \ b;
% your CODE ends here
% impaint target image
% solamente se sobreponen los pixeles que se calcularon
for ib=1:N
seamless(row_offset+ir(ib),col_offset+ic(ib),color) = x(ib);
end
end
figure(1), imshow(target);
figure(2), imshow(seamless);
figure(3), imshow(source);