Skip to content

Commit 96a0750

Browse files
authored
Add files via upload
1 parent ca34a96 commit 96a0750

14 files changed

+743
-0
lines changed

Diff for: estimateggdparam.m

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
function [gamparam,sigma] = estimateggdparam(vec)
2+
3+
4+
5+
gam = 0.1:0.001:10;
6+
r_gam = (gamma(1./gam).*gamma(3./gam))./((gamma(2./gam)).^2);
7+
8+
sigma_sq = mean((vec).^2);
9+
sigma = sqrt(sigma_sq);
10+
E = mean(abs(vec));
11+
rho = sigma_sq/E^2;
12+
[min_difference, array_position] = min(abs(rho - r_gam));
13+
gamparam = gam(array_position);
14+
15+
16+
17+
18+
19+

Diff for: example.m

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
%example code
2+
clear all;
3+
4+
%add pyramid toolbox to path
5+
addpath('E:\Pavan\pano_test\matlabPyrTools-master');
6+
7+
patch_size = 100;
8+
9+
%load constituent images
10+
for k = 1:5
11+
im_constituent{k} = imread(['images\' num2str(k) '.jpg']);
12+
end
13+
14+
%load stitched image
15+
stitched_im = imread('images\stitched.jpg');
16+
17+
%% remove overlapping regions from one of the images
18+
% This part of the code is optional. It is used to extract regions such that
19+
% overlapping regions are used only once for processing. This can be done
20+
% manually or using the code below. The below code uses SIFT to remove out
21+
% overlapping regions. If the images have large resolution this can be
22+
% quite time consuming
23+
24+
%add vl_feat
25+
% vl_feat can be downloaded from http://www.vlfeat.org/index.html
26+
27+
ip = pwd;
28+
cd E:\Pavan\pano_test\vlfeat-0.9.19\toolbox;
29+
feval('vl_setup');
30+
cd(ip);
31+
addpath('modelspecific');
32+
addpath('multigs');
33+
34+
im_constituent = extract_novp(im_constituent);
35+
36+
%% Feature extraction
37+
%extract features from constituent images
38+
feat_c = extract_feat_constituent(im_constituent,patch_size);
39+
40+
%extract features from stitched image
41+
feat_g = extract_feat_stitched(stitched_im,patch_size);
42+
43+
%% score prediction
44+
feat = feat_c - feat_g;feat = feat';
45+
46+
%feature normalization
47+
load('model_parameters');
48+
load('model');
49+
feat = (2./(high-low)).*(feat - (high+low)/2);
50+
51+
% add libsvm to path
52+
% change path for linux and Mac
53+
addpath('E:\Pavan\pano_test\matlabPyrTools-master\libsvm-3.22\windows');
54+
quality_score = svmpredict(randi(100),feat,model,'-q')';

Diff for: extract_feat_constituent.m

+138
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
function feat = extract_feat_constituent(constituent_im,patch_size)
2+
3+
%function to extract features of PIQE framework for constituent images
4+
5+
for k = 1:length(constituent_im)
6+
[c_x{k},c_y{k}] = extract_patch(constituent_im{k},patch_size);
7+
end
8+
9+
%Steerable Pyramid Decomposition
10+
Nor = 6; %number of orientations
11+
scale = 2; %number of scales
12+
sig = 0.1; %sigma for patch weighting non-linearity
13+
14+
patch_sel_c_h = [];patch_sel_c_v = [];
15+
16+
disp('Extracting features of Marginal Distribution for constituent images....');
17+
for k = 1:length(constituent_im)
18+
sz = length(patch_sel_c_h);
19+
parfor t = 1:length(c_x{k})
20+
block_im = rgb2gray(constituent_im{k}(c_x{k}(t,1):c_x{k}(t,2),c_y{k}(t,1):c_y{k}(t,2),:));
21+
22+
%Steerable pyramid decomposition
23+
[pyr_c{k,t},pind_c{k,t}] = buildSFpyr(double(block_im),scale,Nor-1);
24+
25+
%GSM based divisive normalization and fitting marginal distribution using GGD
26+
marginal_c{sz+t} = marginal_est(pyr_c{k,t},pind_c{k,t},scale,Nor,1,1,3,3,50);
27+
28+
%values for patch weighting
29+
%Horizontal neighbors
30+
31+
du = zeros(13,13); %13 quantization levels
32+
quant_im = floor(double(block_im)/21)+1;
33+
[glcm_constituent,SI] = graycomatrix(quant_im,'Offset',[0,1],'NumLevels',...
34+
max(quant_im(:)) - min(quant_im(:)) + 1,'GrayLimits',[min(quant_im(:)) max(quant_im(:))]);
35+
du(min(quant_im(:)):max(quant_im(:)),min(quant_im(:)):max(quant_im(:))) = glcm_constituent;
36+
stats = graycoprops(du,'Energy');
37+
patch_sel_c_h(sz+t) = 1 - stats.Energy; %weight = 1 - energy
38+
patch_sel_c_h(sz+t) = non_lin_fn(patch_sel_c_h(sz+t),sig); %non_linearity
39+
40+
%Vertical Neighbors
41+
du = zeros(13,13); %13 quantization levels
42+
[glcm_constituent,SI] = graycomatrix(quant_im,'Offset',[1,0],'NumLevels',...
43+
max(quant_im(:)) - min(quant_im(:)) + 1,'GrayLimits',[min(quant_im(:)) max(quant_im(:))]);
44+
du(min(quant_im(:)):max(quant_im(:)),min(quant_im(:)):max(quant_im(:))) = glcm_constituent;
45+
stats = graycoprops(du,'Energy');
46+
patch_sel_c_v(sz+t) = 1 - stats.Energy; %weight = 1 - energy;
47+
patch_sel_c_v(sz+t) = non_lin_fn(patch_sel_c_v(sz+t),sig); %non_linearity
48+
end
49+
end
50+
51+
%concatenation
52+
sz = length(c_x{1});
53+
for k = 2:length(constituent_im)
54+
pyr_c(1,sz+1:sz+length(c_x{k})) = pyr_c(k,1:length(c_x{k}));
55+
pind_c(1,sz+1:sz+length(c_x{k})) = pind_c(k,1:length(c_x{k}));
56+
sz = size(pyr_c,2);
57+
end
58+
pyr_c(2:end,:) = [];pind_c(2:end,:) = [];
59+
60+
%patch weights
61+
wx = patch_sel_c_h';wy = patch_sel_c_v';
62+
wx = repmat(wx,1,12);wy = repmat(wy,1,12);
63+
64+
%steerable features weighted averaging
65+
wt = wx';
66+
g_shape = [];
67+
68+
parfor p = 1:length(marginal_c)
69+
if(~isempty(marginal_c{p}))
70+
g_shape(:,p) = marginal_c{p}(1:12); %shape parameters of ggd
71+
else
72+
g_shape(:,p) = -1*ones(12,1);
73+
end
74+
end
75+
76+
g_shape = g_shape.*wt;
77+
ft_marginal_c = sum(g_shape,2)/sum(wt(1,:));
78+
79+
%patches with non-zero weights
80+
ix = find(patch_sel_c_h>0);iy = find(patch_sel_c_v>0);
81+
82+
%Bivariste GMM fit
83+
disp('Extracting features of Bivariate Distribution for constituent images....');
84+
sc = scale-1;
85+
for orien = 1:Nor
86+
op = 2*orien - 1:2*orien;
87+
nband = (sc-1)*Nor+orien+1;
88+
parfor t = 1:min(length(ix),length(iy))
89+
aux_m = pyrBand(pyr_c{ix(t)}, pind_c{ix(t)}, nband);
90+
aux_h = find_neighbor(aux_m,1); %Horizontal neighbors
91+
92+
Xh = [aux_h{1}(:) - mean(aux_h{1}(:)), aux_h{2}(:) - mean(aux_h{2}(:))];
93+
joint_cx(t,op) = gmm_eig(Xh,4,2,35);
94+
95+
aux_m = pyrBand(pyr_c{iy(t)}, pind_c{iy(t)}, nband);
96+
aux_v = find_neighbor(aux_m,3); %Vertical neighbors
97+
98+
Xv = [aux_v{1}(:) - mean(aux_v{1}(:)), aux_v{2}(:) - mean(aux_v{2}(:))];
99+
joint_cy(t,op) = gmm_eig(Xv,4,2,35);
100+
end
101+
end
102+
103+
it = length(ix) >= length(iy);
104+
switch it
105+
case 1
106+
for orien = 1:Nor
107+
op = 2*orien - 1:2*orien;
108+
nband = (sc-1)*Nor+orien+1;
109+
parfor t = length(iy)+1:length(ix)
110+
aux_m = pyrBand(pyr_c{ix(t)}, pind_c{ix(t)}, nband);
111+
aux_h = find_neighbor(aux_m,1); %Horizontal neighbors
112+
113+
Xh = [aux_h{1}(:) - mean(aux_h{1}(:)), aux_h{2}(:) - mean(aux_h{2}(:))];
114+
joint_cx(t,op) = gmm_eig(Xh,4,2,35);
115+
end
116+
end
117+
case 0
118+
for orien = 1:Nor
119+
op = 2*orien - 1:2*orien;
120+
nband = (sc-1)*Nor+orien+1;
121+
parfor t = length(ix)+1:length(iy)
122+
aux_m = pyrBand(pyr_c{iy(t)}, pind_c{iy(t)}, nband);
123+
aux_v = find_neighbor(aux_m,3); %Vertical neighbors
124+
125+
Xv = [aux_v{1}(:) - mean(aux_v{1}(:)), aux_v{2}(:) - mean(aux_v{2}(:))];
126+
joint_cy(t,op) = gmm_eig(Xv,4,2,35);
127+
end
128+
end
129+
end
130+
131+
joint_c_avex = zeros(size(wx));joint_c_avey = zeros(size(wy));
132+
joint_c_avex(ix,:) = joint_cx;joint_c_avey(ix,:) = joint_cy;
133+
134+
%square root of eigen values
135+
joint_c_avex = sqrt(joint_c_avex.*(wx.^2));joint_c_avey = sqrt(joint_c_avey.*(wy.^2));
136+
joint_featx = sum(joint_c_avex,1)'/sum(wx(:,1));joint_featy = sum(joint_c_avey,1)'/sum(wy(:,1));
137+
138+
feat = [ft_marginal_c;joint_featx;joint_featy];

Diff for: extract_feat_stitched.m

+123
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
function feat = extract_feat_stitched(stitched_im,patch_size)
2+
3+
%function to extract features of PIQE framework for stitched stitched_images
4+
[s_x,s_y] = extract_patch(stitched_im,patch_size);
5+
6+
%Steerable Pyramid Decomposition
7+
Nor = 6; %number of orientations
8+
scale = 2; %number of scales
9+
sig = 0.1; %sigma for patch weighting non-linearity
10+
11+
patch_sel_s_h = [];patch_sel_s_v = [];
12+
13+
%feature extraction for stitched images
14+
disp('Extracting features of Marginal Distribution for stitched image....');
15+
16+
parfor t = 1:length(s_x)
17+
block_im = rgb2gray(stitched_im(s_x(t,1):s_x(t,2),s_y(t,1):s_y(t,2),:));
18+
[pyr_s{t},pind_s{t}] = buildSFpyr(double(block_im),scale,Nor-1);
19+
20+
%GSM based divisive normalization and fitting marginal distribution using GGD
21+
marginal_s{t} = marginal_est(pyr_s{t},pind_s{t},scale,Nor,1,1,3,3,50);
22+
23+
%values for patch weighting
24+
%Horizontal neighbors
25+
26+
du = zeros(13,13); %13 quantization levels
27+
quant_im = floor(double(block_im)/21)+1;
28+
[glcm_constituent,SI] = graycomatrix(quant_im,'Offset',[0,1],'NumLevels',...
29+
max(quant_im(:)) - min(quant_im(:)) + 1,'GrayLimits',[min(quant_im(:)) max(quant_im(:))]);
30+
du(min(quant_im(:)):max(quant_im(:)),min(quant_im(:)):max(quant_im(:))) = glcm_constituent;
31+
stats = graycoprops(du,'Energy');
32+
patch_sel_s_h(t) = 1 - stats.Energy; %weight = 1 - energy
33+
patch_sel_s_h(t) = non_lin_fn(patch_sel_s_h(t),sig); %non_linearity
34+
35+
%Vertical Neighbors
36+
du = zeros(13,13); %13 quantization levels
37+
[glcm_constituent,SI] = graycomatrix(quant_im,'Offset',[1,0],'NumLevels',...
38+
max(quant_im(:)) - min(quant_im(:)) + 1,'GrayLimits',[min(quant_im(:)) max(quant_im(:))]);
39+
du(min(quant_im(:)):max(quant_im(:)),min(quant_im(:)):max(quant_im(:))) = glcm_constituent;
40+
stats = graycoprops(du,'Energy');
41+
patch_sel_s_v(t) = 1 - stats.Energy; %weight = 1 - energy
42+
patch_sel_s_v(t) = non_lin_fn(patch_sel_s_v(t),sig); %non_linearity
43+
end
44+
45+
%patch weights
46+
wx = patch_sel_s_h';wy = patch_sel_s_v';
47+
wx = repmat(wx,1,12);wy = repmat(wy,1,12);
48+
49+
%steerable features weighted averaging
50+
wt = wx';
51+
g_shape = [];
52+
53+
parfor p = 1:length(marginal_s)
54+
if(~isempty(marginal_s{p}))
55+
g_shape(:,p) = marginal_s{p}(1:12); %shape parameters of ggd
56+
else
57+
g_shape(:,p) = -1*ones(12,1);
58+
end
59+
end
60+
61+
g_shape = g_shape.*wt;
62+
ft_marginal_s = sum(g_shape,2)/sum(wt(1,:));
63+
64+
%patches with non-zero weights
65+
ix = find(patch_sel_s_h>0);iy = find(patch_sel_s_v>0);
66+
67+
%Bivariste GMM fit
68+
disp('Extracting features of Bivariate Distribution for stitched image....');
69+
sc = scale - 1;
70+
for orien = 1:Nor
71+
op = 2*orien - 1:2*orien;
72+
nband = (sc-1)*Nor+orien+1;
73+
parfor t = 1:min(length(ix),length(iy))
74+
aux_m = pyrBand(pyr_s{ix(t)}, pind_s{ix(t)}, nband);
75+
aux_h = find_neighbor(aux_m,1); %Horizontal neighbors
76+
77+
Xh = [aux_h{1}(:) - mean(aux_h{1}(:)), aux_h{2}(:) - mean(aux_h{2}(:))];
78+
joint_sx(t,op) = gmm_eig(Xh,4,2,35);
79+
80+
aux_m = pyrBand(pyr_s{iy(t)}, pind_s{iy(t)}, nband);
81+
aux_v = find_neighbor(aux_m,3); %Vertical neighbors
82+
83+
Xv = [aux_v{1}(:) - mean(aux_v{1}(:)), aux_v{2}(:) - mean(aux_v{2}(:))];
84+
joint_sy(t,op) = gmm_eig(Xv,4,2,35);
85+
end
86+
end
87+
88+
it = length(ix) >= length(iy);
89+
switch it
90+
case 1
91+
for orien = 1:Nor
92+
op = 2*orien - 1:2*orien;
93+
nband = (sc-1)*Nor+orien+1;
94+
parfor t = length(iy)+1:length(ix)
95+
aux_m = pyrBand(pyr_s{ix(t)}, pind_s{ix(t)}, nband);
96+
aux_h = find_neighbor(aux_m,1); %Horizontal neighbors
97+
98+
Xh = [aux_h{1}(:) - mean(aux_h{1}(:)), aux_h{2}(:) - mean(aux_h{2}(:))];
99+
joint_sx(t,op) = gmm_eig(Xh,4,2,35);
100+
end
101+
end
102+
case 0
103+
for orien = 1:Nor
104+
op = 2*orien - 1:2*orien;
105+
nband = (sc-1)*Nor+orien+1;
106+
parfor t = length(ix)+1:length(iy)
107+
aux_m = pyrBand(pyr_s{iy(t)}, pind_s{iy(t)}, nband);
108+
aux_v = find_neighbor(aux_m,3); %Vertical neighbors
109+
110+
Xv = [aux_v{1}(:) - mean(aux_v{1}(:)), aux_v{2}(:) - mean(aux_v{2}(:))];
111+
joint_sy(t,op) = gmm_eig(Xv,4,2,35);
112+
end
113+
end
114+
end
115+
116+
joint_s_avex = zeros(size(wx));joint_s_avey = zeros(size(wy));
117+
joint_s_avex(ix,:) = joint_sx;joint_s_avey(ix,:) = joint_sy;
118+
119+
%square root of eigen values
120+
joint_s_avex = sqrt(joint_s_avex.*(wx.^2));joint_s_avey = sqrt(joint_s_avey.*(wy.^2));
121+
joint_featx = sum(joint_s_avex,1)'/sum(wx(:,1));joint_featy = sum(joint_s_avey,1)'/sum(wy(:,1));
122+
123+
feat = [ft_marginal_s;joint_featx;joint_featy];

Diff for: extract_novp.m

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
function im = extract_novp(im)
2+
3+
M = 500; % Number of hypotheses for RANSAC.
4+
thr = 0.1; % RANSAC threshold.
5+
6+
%global functions
7+
global fitfn resfn degenfn psize numpar
8+
fitfn = 'homography_fit';
9+
resfn = 'homography_res';
10+
degenfn = 'homography_degen';
11+
psize = 4;
12+
numpar = 9;
13+
14+
[points, descriptors] = vl_sift(single(rgb2gray(im{1})),'PeakThresh', 0,'edgethresh',500);
15+
16+
for n=2:length(im)
17+
pointsPrev = points;
18+
descriptorsPrev = descriptors;
19+
20+
[points, descriptors] = vl_sift(single(rgb2gray(im{n})),'PeakThresh', 0,'edgethresh',500);
21+
matches = vl_ubcmatch(descriptorsPrev,descriptors);
22+
23+
%data normalization
24+
data_orig = [pointsPrev(1:2,matches(1,:)) ; ones(1,size(matches,2)) ; points(1:2,matches(2,:)) ; ones(1,size(matches,2)) ];
25+
[dat_norm_img1,T1] = normalise2dpts(data_orig(1:3,:));
26+
[dat_norm_img2,T2] = normalise2dpts(data_orig(4:6,:));
27+
data_norm = [ dat_norm_img1 ; dat_norm_img2 ];
28+
29+
%RANSAC
30+
[ ~,res,~,~ ] = multigsSampling(100,data_norm,M,10);
31+
con = sum(res<=thr);
32+
[ ~, maxinx ] = max(con);
33+
inliers = find(res(:,maxinx)<=thr);
34+
35+
max_x = max(data_orig(4,inliers));
36+
im{n} = im{n}(:,round(max_x+1):end,:);
37+
end

0 commit comments

Comments
 (0)