summaryrefslogtreecommitdiffstats
path: root/SD-VBS/common/toolbox/toolbox_basic/affine
diff options
context:
space:
mode:
Diffstat (limited to 'SD-VBS/common/toolbox/toolbox_basic/affine')
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/affine/README5
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/affine/carve_it.m25
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/affine/compute_AD.m90
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/affine/compute_AD_disp.m103
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/affine/compute_J.m31
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/affine/find_AD.m82
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/affine/find_D.m65
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/affine/find_center.m4
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/affine/gen_feature_s.m17
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/affine/grad.m24
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/affine/hemisphere_s.m27
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/affine/im.m3
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/affine/iter_AD.m26
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/affine/m_interp4.m49
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/affine/norm_inten.m11
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/affine/pan.0.pgm53
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/affine/pan.1.pgm59
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/affine/readpgm.m26
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/affine/simulation.m42
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/affine/sports1_11_28.jpegbin0 -> 23655 bytes
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/affine/test_affine.m33
21 files changed, 775 insertions, 0 deletions
diff --git a/SD-VBS/common/toolbox/toolbox_basic/affine/README b/SD-VBS/common/toolbox/toolbox_basic/affine/README
new file mode 100755
index 0000000..e578a74
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/affine/README
@@ -0,0 +1,5 @@
1Top level program is "compute_AD.m". Use "compute_AD_disp.m" if one
2wants to display results as program runs.
3
4The testing programs are called "simulation.m" for synthetic images,
5and "test_affine.m" for real images.
diff --git a/SD-VBS/common/toolbox/toolbox_basic/affine/carve_it.m b/SD-VBS/common/toolbox/toolbox_basic/affine/carve_it.m
new file mode 100755
index 0000000..1a44f89
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/affine/carve_it.m
@@ -0,0 +1,25 @@
1function img = carve_it(I,center,window_size_h)
2
3[size_y,size_x]= size(I);
4min_x = round(center(1)-window_size_h(1));
5max_x = round(center(1)+window_size_h(1));
6min_y = round(center(2)-window_size_h(2));
7max_y = round(center(2)+window_size_h(2));
8window_size = window_size_h*2 +1;
9
10if (min_x <1)|(max_x > size_x)|(min_y<1)|(max_y>size_y),
11 disp('window too big');
12 center
13 window_size_h
14 img = zeros(window_size(2),window_size(1));
15 n_min_x = max(1,round(min_x));
16 n_min_y = max(1,round(min_y));
17 n_max_x = min(size_x,round(max_x));
18 n_max_y = min(size_y,round(max_y));
19 img(1+(n_min_y-min_y):window_size(2)-(max_y-n_max_y),1+(n_min_x-min_x):window_size(1)-(max_x-n_max_x))=I(n_min_y:n_max_y,n_min_x:n_max_x);
20else
21 img = I(center(2)-window_size_h(2):center(2)+window_size_h(2),...
22 center(1)-window_size_h(1):center(1)+window_size_h(1));
23end
24
25
diff --git a/SD-VBS/common/toolbox/toolbox_basic/affine/compute_AD.m b/SD-VBS/common/toolbox/toolbox_basic/affine/compute_AD.m
new file mode 100755
index 0000000..a39acd6
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/affine/compute_AD.m
@@ -0,0 +1,90 @@
1function [A,D,mask] =...
2compute_AD(img_i,img_j,center_i,center_j,window_size_h,num_iter,w,num_trans,Dest,mask)
3%
4% function [A,D,mask] = ...
5% compute_AD(img_i,img_j,center_i,center_j,window_size_h,num_iter,w,
6% mask,num_trans)
7%
8% A: Affine motion;
9% D: Displacement;
10%
11% img_i, img_j: the two image(in full size);
12% center_i, center_j: the centers of the feature in two images;
13% window_size_h: half size of the feature window;
14% num_iter: number of iterations;
15% w: parameter used in "grad.m" for computing gaussians used for
16% gradient estimation;
17%
18% num_trans: OPTIONAL, number of translation iteration; default = 3;
19% mask: OPTIONAL, if some area of the square shaped feature window should
20% be weighted less;
21%
22
23%
24% Jianbo Shi
25%
26
27if ~exist('Dest'),
28 Dest = [0,0];
29end
30
31if ~exist('mask'),
32 mask = ones(2*window_size_h+1)';
33end
34
35% set the default num_trans
36if ~exist('num_trans'),
37 num_trans= 3;
38end
39
40% normalize image intensity to the range of 0.0-1.0
41img_i = norm_inten(img_i);
42img_j = norm_inten(img_j);
43
44window_size = 2*window_size_h + 1;
45I = carve_it(img_i,center_i,window_size_h);
46J = carve_it(img_j,center_j,window_size_h);
47
48% init. step
49J_computed = I;
50D_computed = Dest;
51A_computed = eye(2);
52J_computed = compute_J(A_computed,D_computed,img_i,center_i,window_size_h);
53
54%% level of noise
55sig = 0.1;
56
57records = zeros(num_iter,6);
58errs = zeros(1,num_iter);
59
60k = 1;
61% iteration
62while k <= num_iter,
63 [A,D] = iter_AD(J_computed,J,mask,w,k,num_trans);
64
65 A_computed = A*A_computed;
66 D_computed = (A*D_computed')' + D;
67
68 % compute the warped image
69 J_computed = compute_J(A_computed,D_computed,img_i,center_i,window_size_h);
70
71 % compute the SSD error
72 errs(k) = sqrt(sum(sum((mask.*(J_computed-J)).^2)))/prod(size(J));
73
74 % update the mask, discounting possible occlusion region
75 if (k>num_trans),
76 mask = exp(-abs(J_computed-J)/sig);
77 end
78
79 % record the A and D
80 records(k,:) = [reshape(A_computed,1,4),reshape(D_computed,1,2)];
81
82 k = k+1;
83end
84
85[tmp,id] = min(errs);
86A = reshape(records(id,1:4),2,2);
87D = reshape(records(id,5:6),1,2);
88
89J_computed = compute_J(A,D,img_i,center_i,window_size_h);
90mask = exp(-abs(J_computed-J)/sig);
diff --git a/SD-VBS/common/toolbox/toolbox_basic/affine/compute_AD_disp.m b/SD-VBS/common/toolbox/toolbox_basic/affine/compute_AD_disp.m
new file mode 100755
index 0000000..f2e6c62
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/affine/compute_AD_disp.m
@@ -0,0 +1,103 @@
1function [A,D,mask] =...
2compute_AD_disp(img_i,img_j,center_i,center_j,window_size_h,num_iter,w,fig_disp,num_trans,Dest,mask)
3%
4% function [A,D,mask] = ...
5% compute_AD_disp(img_i,img_j,center_i,center_j,window_size_h,num_iter,w,
6% fig_disp,mask,num_trans)
7%
8% Computing affine transform for matching to image patches. Display results
9% as program runs.
10%
11% A: Affine motion;
12% D: Displacement;
13%
14%
15% img_i, img_j: the two image(in full size);
16% center_i, center_j: the centers of the feature in two images;
17% window_size_h: half size of the feature window;
18% num_iter: number of iterations;
19% w: parameter used in "grad.m" for computing gaussians used for
20% gradient estimation;
21% fig_disp: figure for display;
22%
23% num_trans: OPTIONAL, number of translation iteration;
24% mask: OPTIONAL, if some area of the square shaped feature window should
25% be weighted less;
26%
27
28
29%
30% Jianbo Shi
31%
32
33if ~exist('mask'),
34 mask = ones(2*window_size_h+1)';
35end
36
37if ~exist('Dest'),
38 Dest = [0,0];
39end
40
41% set the default num_trans
42if ~exist('num_trans'),
43 num_trans= 3;
44end
45
46% normalize image intensity to the range of 0.0-1.0
47img_i = norm_inten(img_i);
48img_j = norm_inten(img_j);
49
50window_size = 2*window_size_h + 1;
51I = carve_it(img_i,center_i,window_size_h);
52J = carve_it(img_j,center_j,window_size_h);
53
54% init. step
55D_computed = Dest;
56A_computed = eye(2);
57J_computed = compute_J(A_computed,D_computed,img_i,center_i,window_size_h);
58
59
60
61figure(fig_disp);subplot(1,3,1);imagesc(I);colormap(gray);axis('image');
62subplot(1,3,3);imagesc(J);axis('image');
63drawnow;
64
65sig = 0.1;
66
67records = zeros(num_iter,6);
68errs = zeros(1,num_iter);
69
70k = 1;
71% iteration
72while k <= num_iter,
73 [A,D] = iter_AD(J_computed,J,mask,w,k,num_trans);
74
75 A_computed = A*A_computed;
76 D_computed = (A*D_computed')' + D;
77
78 % compute the warped image
79 J_computed = compute_J(A_computed,D_computed,img_i,center_i,window_size_h);
80
81 % compute the SSD error
82 errs(k) = sqrt(sum(sum((mask.*(J_computed-J)).^2)))/prod(size(J))
83
84 % update the mask, discounting possible occlusion region
85 if (k>num_trans+1),
86 mask = exp(-abs(J_computed-J)/sig);
87 end
88
89 % record the A and D
90 records(k,:) = [reshape(A_computed,1,4),reshape(D_computed,1,2)];
91
92 figure(fig_disp);subplot(1,3,2);imagesc(J_computed);axis('image');
93 title(sprintf('iter:%d: dx=%3.3f, dy = %3.3f',k,D_computed(1),D_computed(2)));drawnow;
94
95 k = k+1;
96end
97
98[tmp,id] = min(errs);
99A = reshape(records(id,1:4),2,2);
100D = reshape(records(id,5:6),1,2);
101
102J_computed = compute_J(A,D,img_i,center_i,window_size_h);
103mask = exp(-abs(J_computed-J)/sig);
diff --git a/SD-VBS/common/toolbox/toolbox_basic/affine/compute_J.m b/SD-VBS/common/toolbox/toolbox_basic/affine/compute_J.m
new file mode 100755
index 0000000..80db273
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/affine/compute_J.m
@@ -0,0 +1,31 @@
1function [JJ,mask] = compute_J(A,D,I,center,window_size_h)
2%% function J = compute_J(A,D,I,center,window_size_h)
3%
4
5[size_y,size_x] = size(I);
6
7center_x = center(1);
8center_y = center(2);
9
10[XX,YY] = meshgrid(1:size_x,1:size_y);
11x = reshape(XX,size_x*size_y,1);
12y = reshape(YY,size_x*size_y,1);
13index(:,1) = x-center_x;
14index(:,2) = y-center_y;
15
16position_new = A*index'+ [D(1),0;0,D(2)]*ones(2,size_x*size_y);
17position_new(1,:) = position_new(1,:)+center_x;
18position_new(2,:) = position_new(2,:)+center_y;
19
20position_new_x = reshape(position_new(1,:),size_y,size_x);
21position_new_y = reshape(position_new(2,:),size_y,size_x);
22
23[J,mask]= m_interp4(I,position_new_x,position_new_y);
24
25JJ = J(center(2)-window_size_h(2):center(2)+window_size_h(2),...
26 center(1)-window_size_h(1):center(1)+window_size_h(1));
27mask = mask(center(2)-window_size_h(2):center(2)+window_size_h(2),...
28 center(1)-window_size_h(1):center(1)+window_size_h(1));
29
30
31
diff --git a/SD-VBS/common/toolbox/toolbox_basic/affine/find_AD.m b/SD-VBS/common/toolbox/toolbox_basic/affine/find_AD.m
new file mode 100755
index 0000000..3cccefb
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/affine/find_AD.m
@@ -0,0 +1,82 @@
1function [A,D] = find_AD(I,J,mask,w)
2%
3% [A,D] = find_AD(I,J,mask,w)
4%
5% find the matrix affine transform A and displacement D,
6% such that SSD difference of I(Ax-d)-J(x) is minimized,
7%
8
9%
10% Jianbo Shi
11%
12
13
14[gy1,gx1] = grad(I,w);
15[gy2,gx2] = grad(J,w);
16
17gx = 0.5*(gx1+gx2);
18gy = 0.5*(gy1+gy2);
19
20[size_y,size_x] = size(I);
21[center_y,center_x] = find_center(size_y,size_x);
22mask = mask(w+1:size_y-w,w+1:size_x-w);
23
24[x,y] = meshgrid(1:size_x,1:size_y);
25x = x- center_x;
26y = y-center_y;
27
28x = x(w+1:size_y-w,w+1:size_x-w);
29y = y(w+1:size_y-w,w+1:size_x-w);
30
31gx_sqr = gx.*mask.*gx;
32gx_gy = gx.*mask.*gy;
33gy_sqr = gy.*mask.*gy;
34
35x_sqr = x.*x;
36x_y = x.*y;
37y_sqr = y.*y;
38
39T= zeros(6,6);
40T(1,1) = 0.5*trapz(trapz(gx_sqr.*x_sqr));
41T(2,1) = trapz(trapz(gx_gy.*x_y));
42T(3,1) = trapz(trapz(gx_sqr.*x_y));
43T(4,1) = trapz(trapz(gx_gy.*x_sqr));
44T(5,1) = trapz(trapz(gx_sqr.*x));
45T(6,1) = trapz(trapz(gx_gy.*x));
46T(2,2) = 0.5*trapz(trapz(gy_sqr.*y_sqr));
47T(3,2) = trapz(trapz(gx_gy.*y_sqr));
48T(4,2) = trapz(trapz(gy_sqr.*x_y));
49T(5,2) = trapz(trapz(gx_gy.*y));
50T(6,2) = trapz(trapz(gy_sqr.*y));
51T(3,3) = 0.5*trapz(trapz(gx_sqr.*y_sqr));
52T(4,3) = trapz(trapz(gx_gy.*x_y));
53T(5,3) = trapz(trapz(gx_sqr.*y));
54T(6,3) = trapz(trapz(gx_gy.*y));
55T(4,4) = 0.5*trapz(trapz(gy_sqr.*x_sqr));
56T(5,4) = trapz(trapz(gx_gy.*x));
57T(6,4) = trapz(trapz(gy_sqr.*x));
58T(5,5) = 0.5*trapz(trapz(gx_sqr));
59T(6,5) = trapz(trapz(gx_gy));
60T(6,6) = 0.5*trapz(trapz(gy_sqr));
61
62T = T+T';
63
64J = J(w+1:size_y-w,w+1:size_x-w);
65I = I(w+1:size_y-w,w+1:size_x-w);
66
67
68diff = (J-I).*mask;
69b(1) = trapz(trapz(diff.*gx.*x));
70b(2) = trapz(trapz(diff.*gy.*y));
71b(3) = trapz(trapz(diff.*gx.*y));
72b(4) = trapz(trapz(diff.*gy.*x));
73b(5) = trapz(trapz(diff.*gx));
74b(6) = trapz(trapz(diff.*gy));
75
76a = inv(T)*b';
77
78A = [1+a(1), a(3);
79a(4),1+a(2)];
80
81D= [a(5),a(6)];
82
diff --git a/SD-VBS/common/toolbox/toolbox_basic/affine/find_D.m b/SD-VBS/common/toolbox/toolbox_basic/affine/find_D.m
new file mode 100755
index 0000000..1e42cb2
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/affine/find_D.m
@@ -0,0 +1,65 @@
1function D = find_D(I,J,mask,w)
2%
3% function D = find_D(I,J,mask,w)
4%
5% find the vector D such that it minimizes then
6% difference between I(Ax-d)-J(x).
7%
8% mask: the weight matrix,
9% w: window size for estimating gradiant, use a large value
10% when A,D are large.
11%
12
13%
14% NOTE: Because gradient values on the boarder regions of
15% I and J can not be computed accuately when using
16% a gaussian of large support, those boarder regions
17% of width w are not used in computing D.
18%
19
20%
21% Jianbo Shi
22%
23
24[gy1,gx1] = grad(I,w);
25[gy2,gx2] = grad(J,w);
26
27gx = 0.5*(gx1+gx2);
28gy = 0.5*(gy1+gy2);
29
30[size_y,size_x] = size(I);
31[center_y,center_x] = find_center(size_y,size_x);
32mask = mask(w+1:size_y-w,w+1:size_x-w);
33
34[x,y] = meshgrid(1:size_x,1:size_y);
35x = x- center_x;
36y = y-center_y;
37
38x = x(w+1:size_y-w,w+1:size_x-w);
39y = y(w+1:size_y-w,w+1:size_x-w);
40
41gx_sqr = gx.*mask.*gx;
42gx_gy = gx.*mask.*gy;
43gy_sqr = gy.*mask.*gy;
44
45
46T= zeros(2,2);
47
48T(1,1) = 0.5*trapz(trapz(gx_sqr));
49T(2,1) = trapz(trapz(gx_gy));
50T(2,2) = 0.5*trapz(trapz(gy_sqr));
51
52T = T+T';
53
54J = J(w+1:size_y-w,w+1:size_x-w);
55I = I(w+1:size_y-w,w+1:size_x-w);
56
57
58diff = (J-I).*mask;
59b(1) = trapz(trapz(diff.*gx));
60b(2) = trapz(trapz(diff.*gy));
61
62a = inv(T)*b';
63
64D= [a(1),a(2)];
65
diff --git a/SD-VBS/common/toolbox/toolbox_basic/affine/find_center.m b/SD-VBS/common/toolbox/toolbox_basic/affine/find_center.m
new file mode 100755
index 0000000..b12ac7b
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/affine/find_center.m
@@ -0,0 +1,4 @@
1function [center_x,center_y] = find_center(size_x,size_y)
2
3center_x = 0.5*(size_x +1);
4center_y = 0.5*(size_y +1);
diff --git a/SD-VBS/common/toolbox/toolbox_basic/affine/gen_feature_s.m b/SD-VBS/common/toolbox/toolbox_basic/affine/gen_feature_s.m
new file mode 100755
index 0000000..3c113e9
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/affine/gen_feature_s.m
@@ -0,0 +1,17 @@
1function I = gen_feature_s(size_of_feature)
2% function I = gen_feature(size_of_feature)
3% generates a spherical features with size
4% of "size_of_feature"
5%
6
7ss = round(0.4*size_of_feature);
8[X,Y,II] = hemisphere_s(ss);
9
10II = abs(II);
11II = 1/max(max(II))*II;
12
13I = zeros(size_of_feature,size_of_feature);
14
15t = round((size_of_feature-ss)/2);
16
17I(1+t:1+t+ss,1+t:1+t+ss) = II;
diff --git a/SD-VBS/common/toolbox/toolbox_basic/affine/grad.m b/SD-VBS/common/toolbox/toolbox_basic/affine/grad.m
new file mode 100755
index 0000000..53bab55
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/affine/grad.m
@@ -0,0 +1,24 @@
1% gradient of an image
2% coordinates (r, c) follow matrix convention;
3% the gaussian is truncated at x = +- tail, and there are samples samples
4% inbetween, where samples = hsamples * 2 + 1
5
6function[gr,gc] = gradient(image, hsamples)
7
8tail=4;
9samples = hsamples * 2 + 1;
10
11x = linspace(-tail, tail, samples);
12gauss = exp(-x.^2);
13n = gauss * ones(samples,1);
14gauss = gauss/n;
15
16gaussderiv = -x.*gauss;
17n = -gaussderiv*linspace(1,samples,samples)';
18gaussderiv = gaussderiv/n;
19
20gr = conv2(conv2(image, gaussderiv','valid'), gauss,'valid');
21gc = conv2(conv2(image, gaussderiv,'valid'), gauss','valid');
22
23%gr = conv2(conv2(image, gaussderiv','same'), gauss,'same');
24%gc = conv2(conv2(image, gaussderiv,'same'), gauss','same');
diff --git a/SD-VBS/common/toolbox/toolbox_basic/affine/hemisphere_s.m b/SD-VBS/common/toolbox/toolbox_basic/affine/hemisphere_s.m
new file mode 100755
index 0000000..5300183
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/affine/hemisphere_s.m
@@ -0,0 +1,27 @@
1function [x,y,z] = hemisphere(r)
2%HEMISPHERE Generate sphere and transform from spherical coordinates.
3%
4% [X,Y,Z] = HEMISPHERE(N) generates three (n+1)-by-(n+1)
5% matrices so that SURF(X,Y,Z) produces a sphere.
6%
7% [X,Y,Z] = HEMISPHERE(R,N) generates three (n+1)-by-(n+1)
8% matrices so that SURF(X,Y,Z,R) produces a sphere colored by R
9%
10% [X,Y,Z] = HEMISPHERE(R,THETA,PHI) converts from spherical coordinates
11% to cartesian coordinates.
12
13% Modified from
14% Clay M. Thompson 4-24-91
15% Copyright (c) 1991-92 by the MathWorks, Inc.
16% by Carlo Tomasi
17
18error(nargchk(1,3,nargin));
19
20n = r;
21% 0 <= theta <= 2*pi and 0 <= phi <= pi/2
22[theta,phi] = meshgrid((pi/n/2)*[-n:2:n],(pi/2/n)*[-n:2:n]);
23r = ones(n+1,n+1);
24
25x = r .* cos(phi) .* sin(theta);
26y = r .* sin(phi);
27z = r .* cos(phi) .* cos(theta).*phi.*theta;
diff --git a/SD-VBS/common/toolbox/toolbox_basic/affine/im.m b/SD-VBS/common/toolbox/toolbox_basic/affine/im.m
new file mode 100755
index 0000000..6450120
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/affine/im.m
@@ -0,0 +1,3 @@
1function im(I)
2
3imagesc(I);axis('image');drawnow; \ No newline at end of file
diff --git a/SD-VBS/common/toolbox/toolbox_basic/affine/iter_AD.m b/SD-VBS/common/toolbox/toolbox_basic/affine/iter_AD.m
new file mode 100755
index 0000000..50bdae1
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/affine/iter_AD.m
@@ -0,0 +1,26 @@
1function [A,D] = iter_AD(I,J,mask,w,k,num_trans)
2%
3% function [A,D] = iter_AD(I,J,mask,w,k,num_trans)
4%
5% find the affine motion A, and displacement D,
6% such that difference between I(Ax-D) and J(x) is minimized.
7% If k <= num_trans, only translation is computed. This is useful
8% in practice, when translation is relative large.
9%
10% mask: the weight matrix,
11% w: window size for estimating gradiant, use a large value
12% when A,D are large.
13%
14
15%
16% Jianbo Shi
17%
18
19
20if k <= num_trans,
21 D = find_D(I,J,mask,w);
22 A = eye(2);
23else
24 [A,D] = find_AD(I,J,mask,w);
25end
26
diff --git a/SD-VBS/common/toolbox/toolbox_basic/affine/m_interp4.m b/SD-VBS/common/toolbox/toolbox_basic/affine/m_interp4.m
new file mode 100755
index 0000000..314f140
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/affine/m_interp4.m
@@ -0,0 +1,49 @@
1function [F,mask] = m_interp4(z,s,t)
2%INTERP4 2-D bilinear data interpolation.
3% ZI = INTERP4(Z,XI,YI) assumes X = 1:N and Y = 1:M, where
4% [M,N] = SIZE(Z).
5%
6% Copyright (c) 1984-93 by The MathWorks, Inc.
7% Clay M. Thompson 4-26-91, revised 7-3-91, 3-22-93 by CMT.
8%
9% modified to
10
11
12[nrows,ncols] = size(z);
13
14
15if any(size(z)<[3 3]), error('Z must be at least 3-by-3.'); end
16if size(s)~=size(t), error('XI and YI must be the same size.'); end
17
18% Check for out of range values of s and set to 1
19sout = find((s<1)|(s>ncols));
20if length(sout)>0, s(sout) = ones(size(sout)); end
21
22% Check for out of range values of t and set to 1
23tout = find((t<1)|(t>nrows));
24if length(tout)>0, t(tout) = ones(size(tout)); end
25
26% Matrix element indexing
27ndx = floor(t)+floor(s-1)*nrows;
28
29% Compute intepolation parameters, check for boundary value.
30d = find(s==ncols);
31s(:) = (s - floor(s));
32if length(d)>0, s(d) = s(d)+1; ndx(d) = ndx(d)-nrows; end
33
34% Compute intepolation parameters, check for boundary value.
35d = find(t==nrows);
36t(:) = (t - floor(t));
37if length(d)>0, t(d) = t(d)+1; ndx(d) = ndx(d)-1; end
38d = [];
39
40% Now interpolate, reuse u and v to save memory.
41F = ( z(ndx).*(1-t) + z(ndx+1).*t ).*(1-s) + ...
42 ( z(ndx+nrows).*(1-t) + z(ndx+(nrows+1)).*t ).*s;
43
44mask = ones(size(z));
45
46% Now set out of range values to zeros.
47if length(sout)>0, F(sout) = zeros(size(sout));mask(sout)=zeros(size(sout));end
48if length(tout)>0, F(tout) = zeros(size(tout));mask(tout)=zeros(size(tout));end
49
diff --git a/SD-VBS/common/toolbox/toolbox_basic/affine/norm_inten.m b/SD-VBS/common/toolbox/toolbox_basic/affine/norm_inten.m
new file mode 100755
index 0000000..8e8865b
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/affine/norm_inten.m
@@ -0,0 +1,11 @@
1function I = norm_inten(J)
2%
3% I = norm_inten(J)
4%
5% normalize image intensity to the range of 0.0-1.0
6%
7
8max_J = max(max(J));
9min_J = min(min(J));
10
11I = (J-min_J)/(max_J-min_J);
diff --git a/SD-VBS/common/toolbox/toolbox_basic/affine/pan.0.pgm b/SD-VBS/common/toolbox/toolbox_basic/affine/pan.0.pgm
new file mode 100755
index 0000000..2e7b5f6
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/affine/pan.0.pgm
@@ -0,0 +1,53 @@
1P5
2# CREATOR: XV Version 3.10a Rev: 12/29/94
3128 96
4255
5qquvvvvwzyz{}~qrrsvxwxyzzz{{|~~tuwuruzzyzz{}}}tvwxyxwwz{{z|{|}tvwwyz{ywz}}mzuuvvvurvuwxz{{{}BUwxz}~}~{{GcZW}}~}~Geoxae~~ηFakswveyӺùIbjnpu|x_nbb_eq¿漭㖽>q}̶Gbjkloqw|pnrcbbehq.ٻfbf0^xF_VYqH^ehkoopqyf|x;33>AVyi5!qcMi<2<3WWB=XFoZMqeHNtMdfVwNiv\uat}c*dHY]ZtG]aced`C233++%)(*59:@7B>F>FEA=<\g^gb\^Ya][\PD83.2<Fgua?>X_=Hj?42)Wh3%GkgpD8xb`vJQjFktVR|LvtTytLU{OdoU}N]sSwZl[+eIVYRqI[^___W?519+&'112>;9G<@;E8BG<:5V[FYYLPIHHMA4=A83:PMd{m@BdmUOi?$ByC!'Q_pS$l|hSrJMqG^ugpOs~Rq|QRN\wM}SYyQuPeX#_NQ_RpFX\]^YK512:)&(032>?9B=E:G7AJ@B;W\GRWHOHEJIB5>C@:4NQ^xp<5[njFlJ, %pIQk]L*&Xw{qReNBnIGeԨYjKayPRXQQuXQOtUb^%[QPcRoGUY]YNC445=)%+.01?98EAG=E6>H@B<S\KPY?LFKOKG9GA8>7BFRwvN\r>itK2WRJmRZ9(AepvPZ[BpVCfΨU]N[zSKgUPjbJQpX\d%UVPhNmFUYYTG>26;?*'+247><;HCM@I7<LCE:T[JKWAJJMVJMAGB394<GLny]#HpGYY:!Eh-(ekhG'2zli{_UkBgfAXlYLWP~cOqQT_rMTlaZm'LYMiMrGVYVNC?368@.)+123?<9JEL@K;;K?D;QXNL\FOTQYOVKB@3:26FHg}o/
63oXKrJ*4r=UzhI'-%lzp|mWtF[n<GZhIbOnVSx]X~MUgkZu,H^MoPqHTTPH?</4<?*),.+2><<I>J@H:;JAF>O[SM_PR]XVLSJ8>8565BD_v>)hiEwU-"lLGpcaHA$U~o~wRjLJrCCZuDtsF}yPqSmlTMsY`tZ~2CeMrRqIRSMGMXPF>A.**0.<C>APIR>L?9K;DEQ]XP`VS]\[OML5?C8?7BDX|~R[sBm_7[_"=cqfj_W;Is|~T\[HvRCa^DxGjHqPgW\yXSee^Z9@kLrPmGOOIM[\MC>@+(*-,7>;<MDM=G<7G>GAJYUU_ZU^ZOKGP?IH2?5>GRue&KuK]gH#DoNXhj]FE]jb|rvZRmIp_?fbCxV[NdQ\[UQyW`o[\A<qNvPmHOKFM[\NB>?)(,,+>BBDSHP@FA8ICG@F\WV]bS_\KLISOED2:4:FNpt85teThQ+*ENWOG6*+;PVm|xkPpK`pVpzuoZYW_ZhPPm`[{[\}L;~wSvQiFIHDLXVJ@<>(''+)7AEESGO<GE;HBG@B_a[^^RTURVNWUGC3789KNh}F*lxMzV3)7/5FHD:*"7JKTy~yOiKQn69.bRhRoWuTVem[^]sQ3t|PuRdDFECJTM?3 
7
8")+8ABBSFN=FD8HFHFB`a]^UONRRYRWVH=:787AA_`!aMdgN,!*5?>4*))(ATq~Q[VIt<6:RTq}UVV|a^x]^afV+nOoS]EFEELOB/&5?ABREK=CI;KLIH=b_\YVPMT[cZVVGDA4<6>BT}m+N|\[f/"$');GGC7,%2W]l^UhHk:+DEZ`WwTrVmn]Xbyeb\%hQlV]GGHDJL;+.%%1'1-!<?BRIH>?L@GMIN@\aYTVVQWgaWPMKIC1:6<ES}|><pY;%%"&/BPF<>9* ,NUVzmV{GW5 #FBuhZUj\cXiXW}epmcc(^Pf[[EEFDJH4$&(COEZsW.<CCNEFEAN?FQHM?Z_UTSZYc_`^QVTNI3726BKoO+t}O<*-,2<@=71-*($%9GJn}XlKD2";Dc}X^]b\^]ZUvijwdk'XTbaXDDECJD+3N<.Avh:8B?NIDE>Q=GQDR:V]U^]`_`\^[M]VOI8868CIf_!a_.')/3:1-35.+)#,DPFcbdY:1,;M[Xv\m\k[\~Wopgas(TUafUBCGBF:&&""$.ReV4 8A?NHDJ>O>DPISAP][dcb[ZSZfX`QBH?37/AD\u0F~T.31./:?:'9DBGJW}dVj@5"3@XXWo^}_xY[nbjyjd|+R[ZlWDFGDA3+,!12'6FDIKJO>RBGUMUCQdcjfaWWT^gZXYFHK291<FW}D6sC%8LPFFpmM,39jt]qH'1LfT_d\_Y~eglhgf4Qa[s[CDECB.'+ -3'7EFLNKR?QDGRDMDJadh[UVY_ecUMXPTM18*2FQwU+^..?Xga\od4+8i~aoN$RvUpsaas\q^wmczjig>KhZuWHGDDE.# 
9!"9HGJOLUCPEHRKMFJaf`XW^_e`^aUa^KI5:.,FLkd$I#:WRQXXiy|wzs;1/]af]%! DuZg\g`Wh_i}ecje|EDiXzVEGFDC1-)%0ZdH')3;=HGEMKVBQJJTJNHHfc`WOjg_X]dXabOK674+EIdp6 +!Njv}}v>-"S~vz{csbb`fdgaohxXAs\[GFFFC/44,-ZkL+*0=AGFCILUHQLJPAMHA^ZX[OkcVXdfYX]LLA3:1>K^C $Tgmt{vuz{}|>%R|pnhs^qbmZzkfr]<vw[}_EGIJSK>AOUaga^bcehnppprvvvtw{xz{x~v)+UL>516HZU?8?QhsE!cFFIL[bcfjlnoqruwyyz|~~}}zE:\?+)69:|=.0BTx^28^nmkijiiijfffdbcb`aa`_]^^``_\\\\]^`__a`b`bdb_GHJM[XPNOQTTVVWYZZ[[\\^]]^_`aabbbbbbcdfgfggghikllmoppqqrqqrrsrB>eSLIE:[C<LahjDZ~IJKK_kmmoqrsuwyz}~W.Exwftaqg8XHHJKZddcfhkmopttvxyz}~}}~s@;kbNp~}{zxwwwttrrppmmihhfdb`_][VIKMLI5
10
11 
12
13
14
15 
16  
17 
18 5H]vbW* #$$&&%'&%$&'%$##&$$$#$$$##$$#!##$"IIIHG=*
19  
20  (KUf~v1GCVvN$! -01*  ! ! ! ILLJLE2  
21
22
23   
24
25 
26
27  ;R]qvHE`sF'&0/!=?B'   JJLJGB8(3>2,94>BB.7AB11< ''
28"5 $EXg~p|W5((..!!%GHN)   <YT:EBMXS\jcIM\kfKJJJIE?)5B42@;FKH3@IG9;D
29 
30#nf$!"
31;Xfx|yr:T47A3,MSQ*  $2 TigRMHYc]]ieMLbonIKLLIGB4DR;;HAVXY9M]^CN^'
32  "^Z%!"<iTI<hG:W7YcmZ<).+1Lt{=FCyo6s'  Bk*B]RSKSr|qWSRhxqnvq\etLKJJKGE:VeCK\TkokBcruL[q/
33
34  *m`%06$?hRJBnEQ΂0W`adwotp5Rt9^X7ʇj1@1;QOQP`|`d`xJLMLIHG;YoJUg]t}pEn}~L^o(  *n[,PdC M?qDT́!EY\bYQZ^hy}|wcql3Tu.5ρ_ը׀/C5LPTXNiqpoIKMKKIG<\rGZg^zmDpz~Mcn%
35   /td0g|K  O<xBY{?UXWL<4C_v{yyixo1\w.;zXȽz>5*U{`<Sqs{JLMNNKG>_uH\h_xfDt|~Ngk!  /t_$$&T={@^z @U\iuxxzxs3Zs-AyjvO@2RRIQMxxst~KNNNOO_WesG_jbxfHw}Nnj  
365|]$##Z??bpQdPY`inr}|u}e7Vu%Ovlˁz8HwgMeZxvrrLNNNVgjYgvKegcygJx}~Qsi   !#3_O#>EL\cOONWWRT]kqkozd:1><"2LTSqgM=FNHFIUqrqpOPRRdmkXfuQjhg~jLzPxf
37
38
39#&!]mOKIOY_badin\G:6$<WZ_y¿ԵH^\EKEAA[rrsoMMPTellUewWqfalLz~S|b  
40"$5OMMJFMXafdVls1#">WZbܬNRJDKB>BgqvvoMNQVgolUiv[sdcqN}S|b 
41 
42%%ۼ׎GOPMKQ\\SS=&FX[f\<R^MVL?srwwpMOPWhnmNez]we_tO||Z^ 
43 
44$%JwHMMLNOHZl\]o>KWZOUOF|uzz~tMPRXjqlJb|e{ebyzV~|[\
45  
46 !$' صnILJG;qVfqkCYaDGZbOVWQzwzKMPXinkC[}awhb|Y|\Z
47    $%>뷗\{S@Fb羥lY\Z<=5czK^nb{}t{KMQXjojFWfyqf`|_Y 
48  '& K؞h]j<wvSPO5>7PwO|w~pzLNOZloh>Ncsyh[|}aY    %&N﷜exhG?5Lp^;^zs~qwLMOZloh>Fcpmc~b_   '%8鼸9><Sa`FZs˨vnLNPYmpi@Ajhl]{^j 
49$%6RJTXOFKEwѱ}qIMNYknhG>~p^k}bz\w!
50  )' xf\WVIHnjz|ϴ{kMOOZoqhE9~`pwbva|* 
51 ()a`Ê|ɰýqbNNP^ppiC0{ayujql4 %
52"*(gaG]uVŭùqSMNQ^qohI&jYfuqdsz6
53 ! !)+ >S_s²{p~JMMO_wwpcVapXWkWr{OKfpk' $!#..!^ef}rWh¥x¸ſx{DKOQbrrtwy|GNBF7sgkwŭ¼s?MPRYF997:<><>>><<;;:<<?@BCGKQTV[_bhmuzڸLNR_jkhilmmoqtttuuvussrpoommlkjigedbba^\ZXXUCҿȸ뗀LLQbrsuvy{}Ǵz{ywvvtstuqpqponmlkkjljigHMMH2 "%*,17;>AEINS[aflqtx}vͽILLMB$ LԲIKKJD-  T׶#&$# ! !  !!JKLIF7  PӻC&$#"  !""!"""!"#"%$EJLHC;' ]ñw%&%##"!#"!"#"#""""#$$&'IJIHF?. u›ľ2)&$"#$#!"""#"#&%%&)(()HJKGDA7$  &Ư߲W,(%%%$"#$####$&&()(+.0GHJJHB=, @衤$('''%%&''&%&&'(),*,/2FGFGEB?2 [ԯ❝9-))('%'''&&((+---.022GHHGFB?7& oϦۻʙn+++(()'&%&'*+--.04333FFFGFB?9*~קַ§.-+*((')()+,-./013444FGJIGDA;0  "ݵ𳷽S5/++,+++-/./10362251DGGGEB@<4& BҰʴ⡶)-.,,+*,.00122244444FFEEDA@=8- _ླྀ±źћ60,,-.../0334555553/BBDDCB?;6." y̹ܵǹđn-.-/../112333335421EDDEB@?<80% 6ѕIJ6.,/121134464543244ADECAA?<93' NⲫĹ̬Z20012/233121132122@?B@A?A=:4+!dͷȵžæ/44314442034532441BABBCB@><82& љĬ}Q84443444222333121>@CDDCB?<93(Dú݊bnt88432421255422122=>@AABA@<94+"nݱ캙vkwwyyWpvpU973222122233220252@AABCB@><97.#(rH 9ltvpmb\ZZrT !&nks2.BS@78423322312311221/11>@ABABA=<;72'(0&;_ggea\SQU]iSflV7@CDK<3443223322334443233110=>CCBBAB@<94)!  ""!!"""##%"#&'!(AW^_``\XY^XWbP%xmZ8:>FNI:899:7878557677766777554>?@BABB@?<95. !!"""##$%%##$%%&((''(-5@LSWYXVTRKDI^`hz`5*, /uaX=;=DOYI889:9::999879::999:98886 \ No newline at end of file
diff --git a/SD-VBS/common/toolbox/toolbox_basic/affine/pan.1.pgm b/SD-VBS/common/toolbox/toolbox_basic/affine/pan.1.pgm
new file mode 100755
index 0000000..9d57f70
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/affine/pan.1.pgm
@@ -0,0 +1,59 @@
1P5
2# CREATOR: XV Version 3.10a Rev: 12/29/94
3128 96
4255
5prsrxxwxz{{||||}~~ſ¿prsttuyxyyz{|{{|~tuuuwwvwyxzz{|}tuwwxxzyy{{{{||}~uvuwyyz{~{z~~~_`k{x{{zzywzyz{{{}~~8:E[{|}57@_WYĿ:9D`ny_iδ8:B^kryxc}ѷ¸8;C[gorv}wbned_gxߍ0mt9;D^iloquz~nqxifdefq1ͺ؁x^[rk4\|JSZ87A[gjknqtw{f䍀y962??Xvb0 nWGa7-84Z`HA`Hu_NulKQwIaiTxNcw]uZm|i&[~KQ_8:BZdeffcK5850)%)09::B6BAIAGIEB>]linhbc[e_^aRC71/4=Eera?=Y_=He<30(Wd0$FkenD9y_]wKQlImuVS|LvvSvrKT{MbqS|R[vSvUb]$\KM`;;CX`cba[A2/41)&2-/=74C<?9G9AE=;5U`BVTDJBDEJB6<A7,4RNc{l?BenWOi?"Bu@#$M[lP'myfWtLNsK`vkvSt}NmSQMZ~Nz}UT{OrQcb$XRIb:;CU^__\Q:226-%'/03=75C<C:D7@J??8V]DPVBIE@DI@2=A@;5NS^xn;9`lgHkH+$lBSi]I((Z~tzpNaQErKGeڨWjL`wPQZPOpZNOqV\e$QVKl;=EVZ]\RF7559.+)32/:;9C>C8H8?H<?<TYFMY=MFHPLF9FB9?6DHRsuK ]p?lqJ5\UIiNX9'CfnuPYZBpWCgЪUZNYyVNjVQfkKNi]Yn(I^Go<=DQYZVLA579<*'+1-4=66E@H=D7;LCE<TZGGU=GJLULL@DA5:4=FLpyZ HqH\X:!Fe)$agiG&0yjgz]TlCgfDZkZKWM}fQtQW^tKSgeWw.DaJp>?EUYVQF>7:>A,%(2-6A:;N@KBL:7L?G@UYJ@XEMQP\GTF@@4:58EHh}m/ 6nXOmG*3q<S{jJ$)&lwqnUvG[n>FUhJcLqV|StbWMzTcoY~3CiLq??ESURJA=46<?,)+2,6A<=J?H=H;:J?G=OVMK`NQ]YWIRI8?8875CF`u=)kiGqO,"nL*Vn]T)*T~n~xNiLKsDC\uErtG|yOmShpULm_\{V::}oLtA@FSSNFFTSFA@+*,.-;=?AOBO:F=6L?IDQ^WN]RP_YTKIJ2@D8<6FFY|zN]vFp^6$^cDSYjlt;0@s|T]^GuRBb`FyGhKo}NgWV|TWdjY[J6xsMq@BFQQKL[[QD>A+)*+*7>>>LEL>I?7G<GBL\ZQ_YS\XKHBL;GG3?8@HSwc$ItP_hG4RgqgRJ]q{G&%5|rv[RlHoaAfcBxWZOaR[`VPu[`u[ZyJ2vzPu=@GNLJN]]QD<>+,,0+<>>ES@KDGC;GBHBF^^X]aP[WEKBRNGC0969GKoq45teWjJERTOC3,7O_K*#h}{oRqJanUirwqW]U`WkRQne[Z]sT1t~PrACEJIFKYWLB>>'#(-*8>>@REM<EF:HBEEC`a\\[MOPMSITPED6847KMh{E+mzO}_53CMKB.#6FKH3+V{PiJOm69.aOjPoTxVXbs[\]jT)lNl@?DFFDISQG>)
6 &':=@CSDJ>GH<HFHI@ab\VPJFNMVSVXG<<696AA_^a~S6(#'3BJ</(*'>UC/ G~PZWIr:37QSnV}V~Tyf_{\b|ca\&aMeACEHGELUF6&6<@BREH;?K<JLII>caYUSNLRX`YWUEDB4;7?EVm*O{P'$&)8DIG;.'.S[E'2}^RiGh:*ED[^VtToTjr\Vcqj`b"[Oa?CHIGELQ?/1) -#+'&7=DTHI==L>GOFO=^\WRPUSYd^PKIHHC062;EP{}7
7=S*# (>RG9?9/ @VJ3'j~~mUyGX1!FCujYUfZaXgYVzffubk'UR]ACDEFFKL8'&#@UERnX-9BCNEDC=L=FPFL:X\RRSZYc]]YKPPOI3616CLnL".),*-8A@;53/*%$8HH;R}~YmLC/#;Ec~Ya[`[b\YVpmgcr%RWXCCEFHFKG-+OA3;tn98@@QFEJAS?GRGR:S`W]\_b`W[[P]VNH8845BIf`" #&+/40/78/,+%!8NE>#B^aW;2.9NYW~v]q^q^Ys^luid{+O_UACEEFCE>''')',JeZ=!7A<JHFL>Q@EPEP?P^Ycdc]WOXd\cSDG>46.CF[s4!!,42-.7;8)-<CJKJ26z|~dXmB5$6CYXXn]`}Z]hig}hg0KeWEFFHHGE7..! %&34$2C>EKEP@THIULTAMbajebUUV`h[XUFIN2;-;FW}F%(4HPH=blQ49:1$f}wuZrF%.MjXee^^{]hculhf?GlVBDDEHFC1(-
8)2%0@DEKHS>SFIUFLCHachZYXW`fbUOYPUO19*2GPuB'8Od`Uel<)51Uz}`qN&QuTpwaaoYm]tr`fie~EAqWEEGIHEG0!
9#"6FEHQKTEQDERKMDEae^UR^^d\V[P`^KI3</.GNmB/LMEMTcu{zvzJ53/By\aY  Dw[e]faVd`ch_jcyJ<|tXEFGIIIG3+(%+O`H'(2:>IIFOLU@NIHTKKDCe_ZTMkg\UXcW^^JH6:6+DGb<@es~|I0*3.2y}s|zaueeae_h`khr]:z}YFEFIIJI323()UkO*(.9AIDBKGOCNJKRCNHA^UT[Jg`WVbdZV[JNA5<0>I\.Ehpx}yxz{I'!,$#g~znlgt[qchYufwiii;oYEGIKLIPI;:GM[c^X[]acgklmmqpoqswuvwt{zy}zBKSG<69G[ZI@EUlwT(IFEFILMYgiikoprvwy}}Y-UM2)-88{}B/'8Xsi4(Imnnmnmlhhigeccecb__`a^^\^]\\\]^]]][\^^``bbceebFGGJLLZYOMNOOQRTTSUVYYYZ[[\\^^___^^^`abbcegffffgijiknnnonooqY(2`TGCA=KK9>V_xwHPoHIJMMN^lqopqrsuwzz}n4Ajymei`_vM@FGHJKKZghgilnoruwwz|}~~M;awWj~}|{yxwvtrpomlkhffebaaa_\[YWTKMMLNMK8"
10 
11
12
13
14
15
16
17
18
19 
20  ,?QttaA!!"$&%$&'''&(&'&'(&%%#%$"$$%#!"##"HKKJJKI?+   
21
22    
23
24ASd|>AGRve5"++!$" .12,!! "! ! JJLMLLKD5 
25   
26 
27 
283P\m|E?Wwz*11''1/ =AB)  KKNMKKID;%->5-:3:@C.5AC52=  (+ 3 !?Wf{~o{~(00&%-. #$EDN+   8WX=GCMZTZfdIL]IJLJKKKJA+1D3,@8FKL.9GG64F    kj(#$4S`u£|x3qq;S69G6*MQQ( +
29NeeRMDRd^]feGG[JJKLONMKE2>S@9LAVXY9H[]CG_)
30
31
32 \[%"$<hSF=jF:|\bmdJ1005Qu|t:?FDzr6u' 
33 <l,=^SUMOq{rXUNdvpmwu^_qKKKKONMJE6JgLEbSmopC]rtORo,
34   &kb'-4%@gTI:kCNĩcaa[exps:vq6Rt8[|Z0ˉg3A2:QPQU_hd]y{IKLLNMLJH:QoOOm`s}xFg|NWt-
35  (l`*QfDK;oES|[_d_Xccfxxt;vl2Tx-4т_֦ׄ,D5JOSYQfrqjLLJKOLLJH=TsKToc{vFm{N[r( 
36 +rc.gNP<vG[əYWUPB9C]pwxvp<yq3Yw-:Yɿ~;6(Nt_<RznurLLLMNOOKI=XuITk_xpEo{Ods%  
37
38 -tb%&)!T;{B^ȟZ[eqr~xxop=u3Xu,AyeľuK=.QQDOKvxrv{LLNPRQPO[V\zJWi`{qGu|Rlq"  
39 3{`$"%Y>>cÍUYbkswwx_p:{s3Ov-Ivj΀z7GuhLc[{tsJLNNOOUfkW`zL\ia|oHv~Soo  #& 5bR$AHMpMNUXSSZhqlkx^r0QK-.<:#2NUQmeO:FMGCHRssqPORRRSdnmYb|Naj_}rJxTsj  
40$%  yFLIQY]dhbgnvl=77*,43$8UZ\lϸIY\DNHBF\oopMOOOORdnmV`|Sgk^~uKwTuh  #%+UKKHEJS^dda[^/1:8':VX`|֪KPICMD?AbnrqNNMQSUgpoU^SgiZ{MxSye
41
42
43 
44%%!ٺɒBJNMKQ[\WLG9$ ! >W[bx۳Z5G_LZN@qnvsMNOQQTgpnP^Zni\~}QuU|c 
45
46
47$& _yFKLKLNKOK'%%EX[k<HR`RTODxpwtOONOQWiqoJRbul[}VzZa 
48  &'޹pHLKFB[`<)HY[og?W_BCUgGMZJwvzNOOPQViqmEQ_nk\Xz[a   
49&' -™]svM>Azqvʅ^^vjT[[;;*UzKYn^}x{LMNOQViqkDNbqt_^z__  %&A࢏f]kAjnǡnOOP7</HyKytz}LNNPQYkplFHbk~e\v``   
50%'S󽗈hzg֝D>.Do[6^trPMMPRVjokIBiln~]xad 
51%'!?渲7<3La^CVlǨMNOQRYlpmK>rclx^v[o  
52')`QEMTQFHBs~ѳNMPOOYmpkN8|~`kvat^z'
53  '&:Y[[UTG@ʎwzϴLMNPPYnrlO6z]tpcn`z- 
54   ))˵٠aǍz|DZ¼uNPQPQ]qtlN+o`{}tmgmw7 &
55! !/MOHnlZFZ}Q¾ƪÿmNNMNQ]qtlP$a^]rvbxv9   !!xkD\P|]p~álLNPRR_wytgYbs]XpYk~UF{ees, $!!6RazrViƬxļnKLMPS`rssvy|LZ?HKDG:rknyƳ½wKLNPRZH9:99<=<>=@=::<;;==?@BGLORUY_ciosx~оLKMOP^lnlllmnopsuuuwwvutsqpopnmmjhgeeb`__]\_x{}}~JLMKN\nrsru{}Յ{zvvtrrqpprqpoommmmkkihgheLKJNOK:
56
57  $',048:>CHNTX^chdLMLLMNH*  }ոo{LJJLJJG4
58 E(%!KKLLIIH>% ټ{&#!! !!!!" !#LLKLKIE?-  ϭ2&$#""!!! !!""!!"!#""$MKLMJFGB5   4֥`+$#$$!$$""#! ######%'&KIJJIGEB:( Nζɻ#)'%$"###""#####!#%%&%&)KHHJIIFC?/ lɪᰡ<+($$$'&&$#$$%$#$%&&&),+KIHJJHGD?4# ⫗s(*(&'&&&&&&&&&'('&)*,..IHHIJFECA9(-ฤڬ7-,)(''&'''')(&'*-./123IIIHEFECA<0 =뾬ֽЫ\0-*)(''''('')*+,--0123HHGHHIGEC>4%Uó(,*+)))*+***+,-/223365GEHIFFDDB?7)k¶찯D0,**((*+++++./0344223GGHGGFIFCA</"ѻɾͿۡz-,-.-)+,,-./131343343EDDFEEEDC@<2&3ƟЙ6.,---,,..0/023332222CCDFGHGEA><6-!Fة‘k0/-/.,-./01212342243DDDEGGECB@<7."`Īɼλ򹋦1.-.--.-0/0223310110CBDDECDB??<80$,{wټʶǼZ111/./0110111310110BABDEEFC@?=;4)  7ƺy0200010011331110121D?ACEDEECA>;7,#lͺqyqwnȽM5331121/1220100220?=@BDDDDB@=97.%!̯jrut~Uhj͟`9431121212111100/00@=AAEHGDC@>:62&RA*\qsrmaYWUkT#jj;=UG7322243122112100110-.?=>@CDEDCA><83* ,0$,Rfgeb_URU]hS
59 |bX5?BIL;2222201232332111221011/?<=>BDDA@BA>;4+!  !" !""!$$%$'&(6Q\\_b]ZXZXR^yY (܊o|Z:;AJOE7355356866544565565553311>=??BBCDCA@>950! "!!#"!""$$%#$$%%&*29GQUWYUTTLDEVWZeX9180>ךryM==AJTS<6799788768987677886676765 \ No newline at end of file
diff --git a/SD-VBS/common/toolbox/toolbox_basic/affine/readpgm.m b/SD-VBS/common/toolbox/toolbox_basic/affine/readpgm.m
new file mode 100755
index 0000000..a5fd7f2
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/affine/readpgm.m
@@ -0,0 +1,26 @@
1function img = pgmread(filename)
2% function img = pgmread(filename)
3% this is my version of pgmread for the pgm file created by XV.
4%
5% this program also corrects for the shifts in the image from pm file.
6
7
8fid = fopen(filename,'r');
9fscanf(fid, 'P5\n');
10cmt = '#';
11while findstr(cmt, '#'),
12 cmt = fgets(fid);
13 if length(findstr(cmt, '#')) ~= 1,
14 YX = sscanf(cmt, '%d %d');
15 y = YX(1); x = YX(2);
16 end
17end
18
19fgets(fid);
20
21%img = fscanf(fid,'%d',size);
22%img = img';
23
24img = fread(fid,[y,x],'uint8');
25img = img';
26fclose(fid);
diff --git a/SD-VBS/common/toolbox/toolbox_basic/affine/simulation.m b/SD-VBS/common/toolbox/toolbox_basic/affine/simulation.m
new file mode 100755
index 0000000..2186a6d
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/affine/simulation.m
@@ -0,0 +1,42 @@
1clear
2
3figure(1);colormap(gray);
4
5%------------ Parameters --------------------------
6window_size_h = 40;
7window_size = 2*window_size_h+1;
8noise_level = 40/256;
9
10% define A and D
11x_ext = -0.423;
12ext = 1.232;
13A = [ext+x_ext, 0.2534; 0.3423,ext];
14
15D = [3,1];
16
17%------------- compute image I and J ---------------
18disp('generating I')
19I_init = gen_feature_s(window_size);
20[size_y,size_x] = size(I_init);
21
22%define image center
23[center_x,center_y] = find_center(size_x,size_y);
24
25% adding noise to image I
26I = I_init+noise_level*rand(size_y,size_x);
27% make sure all intensities are positive
28I = I.*(I>0);
29
30disp('computing J')
31J_init = compute_J(A,D,I_init,[center_x,center_y],[window_size_h,window_size_h]);
32J = J_init+noise_level*rand(size_y,size_x);
33J = J.*(J>0);
34
35
36%------------- compute A and residue ----------------
37c = [center_x,center_y];
38num_iter = 8; w = 9;win_h = [window_size_h,window_size_h];
39
40fig_disp = 1;
41[Ac,Dc,mask] = compute_AD_disp(I,J,c,c,win_h,num_iter,w,fig_disp);
42
diff --git a/SD-VBS/common/toolbox/toolbox_basic/affine/sports1_11_28.jpeg b/SD-VBS/common/toolbox/toolbox_basic/affine/sports1_11_28.jpeg
new file mode 100755
index 0000000..39ebed5
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/affine/sports1_11_28.jpeg
Binary files differ
diff --git a/SD-VBS/common/toolbox/toolbox_basic/affine/test_affine.m b/SD-VBS/common/toolbox/toolbox_basic/affine/test_affine.m
new file mode 100755
index 0000000..41b48b9
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/affine/test_affine.m
@@ -0,0 +1,33 @@
1%%% This is a test program for Affine tracker %%%%
2
3disp(sprintf('This is a test program of Affine tracker'));
4
5%% read in images
6
7disp(sprintf('read in images'));
8I = readpgm('pan.0.pgm');
9J = readpgm('pan.1.pgm');
10
11figure(1); im(I); colormap(gray);
12figure(2); im(J); colormap(gray);
13
14
15figure(1);disp(sprintf('click on the center of a image window'));
16c = round(ginput(1));
17
18%% compute the displacement of that image window
19disp(sprintf('computing...'));
20
21win_hsize_temp = [8,8];
22w = 3;
23num_iter = 6;
24
25disp_flag = 1;
26
27win_h = win_hsize_temp + [w,w];
28if disp_flag == 1,
29 figure_id = 3;
30 [A,D,mask] = compute_AD_disp(I,J,c,c,win_h,num_iter,w,figure_id);
31else
32 [A,D,mask] = compute_AD(I,J,c,c,win_h,num_iter,w);
33end