0001 function B=inpaint_nans(A,method)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101 [n,m]=size(A);
0102 A=A(:);
0103 nm=n*m;
0104 k=isnan(A(:));
0105
0106
0107
0108 nan_list=find(k);
0109 known_list=find(~k);
0110
0111
0112 nan_count=length(nan_list);
0113
0114
0115
0116
0117 [nr,nc]=ind2sub([n,m],nan_list);
0118
0119
0120
0121
0122
0123 nan_list=[nan_list,nr,nc];
0124
0125
0126 if (nargin<2) || isempty(method)
0127 method = 0;
0128 elseif ~ismember(method,0:5)
0129 error 'If supplied, method must be one of: {0,1,2,3,4,5}.'
0130 end
0131
0132
0133 switch method
0134 case 0
0135
0136
0137
0138
0139 if (m == 1) || (n == 1)
0140
0141 work_list = nan_list(:,1);
0142 work_list = unique([work_list;work_list - 1;work_list + 1]);
0143 work_list(work_list <= 1) = [];
0144 work_list(work_list >= nm) = [];
0145 nw = numel(work_list);
0146
0147 u = (1:nw)';
0148 fda = sparse(repmat(u,1,3),bsxfun(@plus,work_list,-1:1), ...
0149 repmat([1 -2 1],nw,1),nw,nm);
0150 else
0151
0152
0153
0154 talks_to = [-1 0;0 -1;1 0;0 1];
0155 neighbors_list=identify_neighbors(n,m,nan_list,talks_to);
0156
0157
0158 all_list=[nan_list;neighbors_list];
0159
0160
0161
0162
0163 L = find((all_list(:,2) > 1) & (all_list(:,2) < n));
0164 nl=length(L);
0165 if nl>0
0166 fda=sparse(repmat(all_list(L,1),1,3), ...
0167 repmat(all_list(L,1),1,3)+repmat([-1 0 1],nl,1), ...
0168 repmat([1 -2 1],nl,1),nm,nm);
0169 else
0170 fda=spalloc(n*m,n*m,size(all_list,1)*5);
0171 end
0172
0173
0174 L = find((all_list(:,3) > 1) & (all_list(:,3) < m));
0175 nl=length(L);
0176 if nl>0
0177 fda=fda+sparse(repmat(all_list(L,1),1,3), ...
0178 repmat(all_list(L,1),1,3)+repmat([-n 0 n],nl,1), ...
0179 repmat([1 -2 1],nl,1),nm,nm);
0180 end
0181 end
0182
0183
0184 rhs=-fda(:,known_list)*A(known_list);
0185 k=find(any(fda(:,nan_list(:,1)),2));
0186
0187
0188 B=A;
0189 B(nan_list(:,1))=fda(k,nan_list(:,1))\rhs(k);
0190
0191 case 1
0192
0193
0194
0195
0196
0197
0198
0199
0200 if (m == 1) || (n == 1)
0201
0202 u = (1:(nm-2))';
0203 fda = sparse(repmat(u,1,3),bsxfun(@plus,u,0:2), ...
0204 repmat([1 -2 1],nm-2,1),nm-2,nm);
0205 else
0206
0207
0208
0209
0210 [i,j]=ndgrid(2:(n-1),1:m);
0211 ind=i(:)+(j(:)-1)*n;
0212 np=(n-2)*m;
0213 fda=sparse(repmat(ind,1,3),[ind-1,ind,ind+1], ...
0214 repmat([1 -2 1],np,1),n*m,n*m);
0215
0216
0217 [i,j]=ndgrid(1:n,2:(m-1));
0218 ind=i(:)+(j(:)-1)*n;
0219 np=n*(m-2);
0220 fda=fda+sparse(repmat(ind,1,3),[ind-n,ind,ind+n], ...
0221 repmat([1 -2 1],np,1),nm,nm);
0222 end
0223
0224
0225 rhs=-fda(:,known_list)*A(known_list);
0226 k=find(any(fda(:,nan_list),2));
0227
0228
0229 B=A;
0230 B(nan_list(:,1))=fda(k,nan_list(:,1))\rhs(k);
0231
0232 case 2
0233
0234
0235
0236
0237
0238
0239
0240 if (m == 1) || (n == 1)
0241
0242 error('Method 2 has problems for vector input. Please use another method.')
0243
0244 else
0245
0246 L = find((nan_list(:,2) > 1) & (nan_list(:,2) < n));
0247 nl=length(L);
0248 if nl>0
0249 fda=sparse(repmat(nan_list(L,1),1,3), ...
0250 repmat(nan_list(L,1),1,3)+repmat([-1 0 1],nl,1), ...
0251 repmat([1 -2 1],nl,1),n*m,n*m);
0252 else
0253 fda=spalloc(n*m,n*m,size(nan_list,1)*5);
0254 end
0255
0256
0257 L = find((nan_list(:,3) > 1) & (nan_list(:,3) < m));
0258 nl=length(L);
0259 if nl>0
0260 fda=fda+sparse(repmat(nan_list(L,1),1,3), ...
0261 repmat(nan_list(L,1),1,3)+repmat([-n 0 n],nl,1), ...
0262 repmat([1 -2 1],nl,1),n*m,n*m);
0263 end
0264
0265
0266
0267 if ismember(1,nan_list(:,1))
0268 fda(1,[1 2 n+1])=[-2 1 1];
0269 end
0270 if ismember(n,nan_list(:,1))
0271 fda(n,[n, n-1,n+n])=[-2 1 1];
0272 end
0273 if ismember(nm-n+1,nan_list(:,1))
0274 fda(nm-n+1,[nm-n+1,nm-n+2,nm-n])=[-2 1 1];
0275 end
0276 if ismember(nm,nan_list(:,1))
0277 fda(nm,[nm,nm-1,nm-n])=[-2 1 1];
0278 end
0279
0280
0281 rhs=-fda(:,known_list)*A(known_list);
0282
0283
0284 B=A;
0285 k=nan_list(:,1);
0286 B(k)=fda(k,k)\rhs(k);
0287
0288 end
0289
0290 case 3
0291
0292
0293
0294
0295 talks_to = [-2 0;-1 -1;-1 0;-1 1;0 -2;0 -1; ...
0296 0 1;0 2;1 -1;1 0;1 1;2 0];
0297 neighbors_list=identify_neighbors(n,m,nan_list,talks_to);
0298
0299
0300 all_list=[nan_list;neighbors_list];
0301
0302
0303
0304
0305 L = find( (all_list(:,2) >= 3) & ...
0306 (all_list(:,2) <= (n-2)) & ...
0307 (all_list(:,3) >= 3) & ...
0308 (all_list(:,3) <= (m-2)));
0309 nl=length(L);
0310 if nl>0
0311
0312 fda=sparse(repmat(all_list(L,1),1,13), ...
0313 repmat(all_list(L,1),1,13) + ...
0314 repmat([-2*n,-n-1,-n,-n+1,-2,-1,0,1,2,n-1,n,n+1,2*n],nl,1), ...
0315 repmat([1 2 -8 2 1 -8 20 -8 1 2 -8 2 1],nl,1),nm,nm);
0316 else
0317 fda=spalloc(n*m,n*m,size(all_list,1)*5);
0318 end
0319
0320
0321 L = find((((all_list(:,2) == 2) | ...
0322 (all_list(:,2) == (n-1))) & ...
0323 (all_list(:,3) >= 2) & ...
0324 (all_list(:,3) <= (m-1))) | ...
0325 (((all_list(:,3) == 2) | ...
0326 (all_list(:,3) == (m-1))) & ...
0327 (all_list(:,2) >= 2) & ...
0328 (all_list(:,2) <= (n-1))));
0329 nl=length(L);
0330 if nl>0
0331 fda=fda+sparse(repmat(all_list(L,1),1,5), ...
0332 repmat(all_list(L,1),1,5) + ...
0333 repmat([-n,-1,0,+1,n],nl,1), ...
0334 repmat([1 1 -4 1 1],nl,1),nm,nm);
0335 end
0336
0337 L = find( ((all_list(:,2) == 1) | ...
0338 (all_list(:,2) == n)) & ...
0339 (all_list(:,3) >= 2) & ...
0340 (all_list(:,3) <= (m-1)));
0341 nl=length(L);
0342 if nl>0
0343 fda=fda+sparse(repmat(all_list(L,1),1,3), ...
0344 repmat(all_list(L,1),1,3) + ...
0345 repmat([-n,0,n],nl,1), ...
0346 repmat([1 -2 1],nl,1),nm,nm);
0347 end
0348
0349 L = find( ((all_list(:,3) == 1) | ...
0350 (all_list(:,3) == m)) & ...
0351 (all_list(:,2) >= 2) & ...
0352 (all_list(:,2) <= (n-1)));
0353 nl=length(L);
0354 if nl>0
0355 fda=fda+sparse(repmat(all_list(L,1),1,3), ...
0356 repmat(all_list(L,1),1,3) + ...
0357 repmat([-1,0,1],nl,1), ...
0358 repmat([1 -2 1],nl,1),nm,nm);
0359 end
0360
0361
0362 rhs=-fda(:,known_list)*A(known_list);
0363 k=find(any(fda(:,nan_list(:,1)),2));
0364
0365
0366 B=A;
0367 B(nan_list(:,1))=fda(k,nan_list(:,1))\rhs(k);
0368
0369 case 4
0370
0371
0372
0373
0374
0375 hv_list=[-1 -1 0;1 1 0;-n 0 -1;n 0 1];
0376 hv_springs=[];
0377 for i=1:4
0378 hvs=nan_list+repmat(hv_list(i,:),nan_count,1);
0379 k=(hvs(:,2)>=1) & (hvs(:,2)<=n) & (hvs(:,3)>=1) & (hvs(:,3)<=m);
0380 hv_springs=[hv_springs;[nan_list(k,1),hvs(k,1)]];
0381 end
0382
0383
0384 hv_springs=unique(sort(hv_springs,2),'rows');
0385
0386
0387
0388
0389 nhv=size(hv_springs,1);
0390 springs=sparse(repmat((1:nhv)',1,2),hv_springs, ...
0391 repmat([1 -1],nhv,1),nhv,nm);
0392
0393
0394 rhs=-springs(:,known_list)*A(known_list);
0395
0396
0397 B=A;
0398 B(nan_list(:,1))=springs(:,nan_list(:,1))\rhs;
0399
0400 case 5
0401
0402
0403
0404
0405 fda=spalloc(n*m,n*m,size(nan_list,1)*9);
0406
0407
0408 L = find((nan_list(:,2) > 1) & (nan_list(:,3) > 1));
0409 nl=length(L);
0410 if nl>0
0411 fda=fda+sparse(repmat(nan_list(L,1),1,2), ...
0412 repmat(nan_list(L,1),1,2)+repmat([-n-1, 0],nl,1), ...
0413 repmat([1 -1],nl,1),n*m,n*m);
0414 end
0415
0416
0417 L = find(nan_list(:,3) > 1);
0418 nl=length(L);
0419 if nl>0
0420 fda=fda+sparse(repmat(nan_list(L,1),1,2), ...
0421 repmat(nan_list(L,1),1,2)+repmat([-n, 0],nl,1), ...
0422 repmat([1 -1],nl,1),n*m,n*m);
0423 end
0424
0425
0426 L = find((nan_list(:,2) < n) & (nan_list(:,3) > 1));
0427 nl=length(L);
0428 if nl>0
0429 fda=fda+sparse(repmat(nan_list(L,1),1,2), ...
0430 repmat(nan_list(L,1),1,2)+repmat([-n+1, 0],nl,1), ...
0431 repmat([1 -1],nl,1),n*m,n*m);
0432 end
0433
0434
0435 L = find(nan_list(:,2) > 1);
0436 nl=length(L);
0437 if nl>0
0438 fda=fda+sparse(repmat(nan_list(L,1),1,2), ...
0439 repmat(nan_list(L,1),1,2)+repmat([-1, 0],nl,1), ...
0440 repmat([1 -1],nl,1),n*m,n*m);
0441 end
0442
0443
0444 L = find(nan_list(:,2) < n);
0445 nl=length(L);
0446 if nl>0
0447 fda=fda+sparse(repmat(nan_list(L,1),1,2), ...
0448 repmat(nan_list(L,1),1,2)+repmat([1, 0],nl,1), ...
0449 repmat([1 -1],nl,1),n*m,n*m);
0450 end
0451
0452
0453 L = find((nan_list(:,2) > 1) & (nan_list(:,3) < m));
0454 nl=length(L);
0455 if nl>0
0456 fda=fda+sparse(repmat(nan_list(L,1),1,2), ...
0457 repmat(nan_list(L,1),1,2)+repmat([n-1, 0],nl,1), ...
0458 repmat([1 -1],nl,1),n*m,n*m);
0459 end
0460
0461
0462 L = find(nan_list(:,3) < m);
0463 nl=length(L);
0464 if nl>0
0465 fda=fda+sparse(repmat(nan_list(L,1),1,2), ...
0466 repmat(nan_list(L,1),1,2)+repmat([n, 0],nl,1), ...
0467 repmat([1 -1],nl,1),n*m,n*m);
0468 end
0469
0470
0471 L = find((nan_list(:,2) < n) & (nan_list(:,3) < m));
0472 nl=length(L);
0473 if nl>0
0474 fda=fda+sparse(repmat(nan_list(L,1),1,2), ...
0475 repmat(nan_list(L,1),1,2)+repmat([n+1, 0],nl,1), ...
0476 repmat([1 -1],nl,1),n*m,n*m);
0477 end
0478
0479
0480 rhs=-fda(:,known_list)*A(known_list);
0481
0482
0483 B=A;
0484 k=nan_list(:,1);
0485 B(k)=fda(k,k)\rhs(k);
0486
0487 end
0488
0489
0490
0491 B=reshape(B,n,m);
0492
0493
0494
0495
0496
0497
0498
0499
0500 function neighbors_list=identify_neighbors(n,m,nan_list,talks_to)
0501
0502
0503
0504
0505
0506
0507
0508
0509
0510
0511
0512
0513
0514
0515
0516
0517
0518
0519
0520
0521
0522
0523
0524
0525
0526
0527
0528 if ~isempty(nan_list)
0529
0530 nan_count=size(nan_list,1);
0531 talk_count=size(talks_to,1);
0532
0533 nn=zeros(nan_count*talk_count,2);
0534 j=[1,nan_count];
0535 for i=1:talk_count
0536 nn(j(1):j(2),:)=nan_list(:,2:3) + ...
0537 repmat(talks_to(i,:),nan_count,1);
0538 j=j+nan_count;
0539 end
0540
0541
0542
0543 L = (nn(:,1)<1)|(nn(:,1)>n)|(nn(:,2)<1)|(nn(:,2)>m);
0544 nn(L,:)=[];
0545
0546
0547 neighbors_list=[sub2ind([n,m],nn(:,1),nn(:,2)),nn];
0548
0549
0550 neighbors_list=unique(neighbors_list,'rows');
0551
0552
0553 neighbors_list=setdiff(neighbors_list,nan_list,'rows');
0554
0555 else
0556 neighbors_list=[];
0557 end
0558
0559
0560
0561
0562
0563
0564
0565
0566
0567