Mentions légales du service
Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
S
SR
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Deploy
Releases
Container registry
Model registry
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
LightFieldCodingLibrary
SR
Commits
1618a6fb
Commit
1618a6fb
authored
6 years ago
by
DIB Elian
Browse files
Options
Downloads
Patches
Plain Diff
Reworked warping entirely
parent
ef07f10c
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
warp.m
+153
-166
153 additions, 166 deletions
warp.m
warpSet.m
+4
-6
4 additions, 6 deletions
warpSet.m
with
157 additions
and
172 deletions
warp.m
+
153
−
166
View file @
1618a6fb
function
[
Value
,
Mask
,
Pos
,
DispX
,
Disp
Y
]
=
warp
(
Value
,
Mask
,
Pos
,
DispX
,
Disp
Y
,
varargin
)
function
[
Value
,
Mask
,
Pos
,
dX
,
d
Y
]
=
warp
(
Value
,
Mask
,
Pos
,
dX
,
d
Y
,
varargin
)
%WARP Summary of this function goes here
%WARP Summary of this function goes here
% Detailed explanation goes here
% Detailed explanation goes here
%% Set parameter values according to given arguments
%% Set parameter values according to given arguments
interps
=
{
'nearest'
,
'linear'
,
'cubic'
,
'spline'
};
interps
=
{
'nearest'
,
'linear'
,
'cubic'
,
'spline'
};
boundaryTypes
=
{
'current'
,
'any'
,
'all'
};
directions
=
{
'forward'
,
'backward'
};
directions
=
{
'forward'
,
'backward'
};
p
=
inputParser
;
p
.
KeepUnmatched
=
true
;
p
.
StructExpand
=
true
;
p
=
inputParser
;
p
.
KeepUnmatched
=
true
;
p
.
StructExpand
=
true
;
p
.
addParameter
(
'interpMethod'
,
'nearest'
,
@
(
x
)
any
(
validatestring
(
x
,
interps
)));
p
.
addParameter
(
'interpMethod'
,
'cubic'
,
@
(
x
)
any
(
validatestring
(
x
,
interps
)));
p
.
addParameter
(
'SRBoundary'
,
'current'
,
@
(
x
)
any
(
validatestring
(
x
,
boundaryTypes
)));
p
.
addParameter
(
'direction'
,
'forward'
,
@
(
x
)
any
(
validatestring
(
x
,
directions
)));
p
.
addParameter
(
'LFBoundary'
,
false
,
@
islogical
);
p
.
addParameter
(
'backproject'
,
true
,
@
islogical
);
p
.
addParameter
(
'direction'
,
'backward'
,
@
(
x
)
any
(
validatestring
(
x
,
directions
)));
p
.
addParameter
(
'relative'
,
true
,
@
islogical
);
p
.
parse
(
varargin
{:});
p
.
parse
(
varargin
{:});
interpMethod
=
p
.
Results
.
interpMethod
;
% interpolation method of Gridded Interpolant
interpMethod
=
p
.
Results
.
interpMethod
;
SRBoundary
=
p
.
Results
.
SRBoundary
;
% Query values to retain
direction
=
p
.
Results
.
direction
;
LFBoundary
=
p
.
Results
.
LFBoundary
;
% Retain values inside original boundaries
backproject
=
p
.
Results
.
backproject
;
direction
=
p
.
Results
.
direction
;
% Forward or backward projection
relative
=
p
.
Results
.
relative
;
% Scale disparity relative to reference view
%%
%% Compute reference grid
% Reference size
Size
=
size
(
Value
);
Size
=
size
(
Value
);
ValMask
=
~
isnan
(
Value
);
% Lightfield grid vectors representing super-ray bounding box
% Mask bounding box
ugv
=
Pos
(
1
)
+
reshape
(
1
:
Size
(
1
),[],
1
);
gv
=
subarrayIdx
(
Mask
);
vgv
=
Pos
(
2
)
+
reshape
(
1
:
Size
(
2
),
1
,[]);
xgv
=
Pos
(
3
)
+
reshape
(
1
:
Size
(
3
),
1
,
1
,[]);
ygv
=
Pos
(
4
)
+
reshape
(
1
:
Size
(
4
),
1
,
1
,
1
,[]);
gv
=
{
ugv
,
vgv
,
xgv
,
ygv
};
% Mask grid coordinates
[
~
,
~
,
X
,
Y
]
=
ndgrid
(
gv
{:});
% Lightfield coordinates (4D)
% Mask grid vectors
[
U
,
V
,
X
,
Y
]
=
ndgrid
(
ugv
,
vgv
,
xgv
,
ygv
);
[
ugv
,
vgv
,
~
,
~
]
=
deal
(
gv
{:});
ugv
=
reshape
(
ugv
,[],
1
);
vgv
=
reshape
(
vgv
,
1
,[]);
% Reference view
% Reference view
uref
=
median
(
ugv
);
u_ref
=
floor
(
numel
(
ugv
)/
2
)
+
1
;
vref
=
median
(
vgv
);
v_ref
=
floor
(
numel
(
vgv
)/
2
)
+
1
;
% Disparity
DispX
=
dX
*
(
ugv
-
u_ref
);
DispY
=
dY
*
(
vgv
-
v_ref
);
if
backproject
% Temporary mask
tempMask
=
Mask
(
gv
{:});
% Backproject coordinates
SRX
=
X
+
DispX
;
SRY
=
Y
+
DispY
;
% Backprojected boundaries
minSRX
=
floor
(
min
(
SRX
(
tempMask
)));
maxSRX
=
ceil
(
max
(
SRX
(
tempMask
)));
minSRY
=
floor
(
min
(
SRY
(
tempMask
)));
maxSRY
=
ceil
(
max
(
SRY
(
tempMask
)));
minSRX
=
max
(
minSRX
,
1
);
maxSRX
=
min
(
maxSRX
,
Size
(
3
));
minSRY
=
max
(
minSRY
,
1
);
maxSRY
=
min
(
maxSRY
,
Size
(
4
));
% Reference grid vectors
xgv
=
minSRX
:
maxSRX
;
ygv
=
minSRY
:
maxSRY
;
% Reference bounding box
gv
=
{
ugv
,
vgv
,
xgv
,
ygv
};
end
% Fill NaN values to allow cubic interpolation (way faster than fillmissing)
% Reference grid
seAng
=
strel
(
'arbitrary'
,[
0
,
1
,
0
]
|
[
0
,
1
,
0
]
'
);
[
~
,
~
,
X
,
Y
]
=
ndgrid
(
gv
{:});
seSpa
=
strel
(
'arbitrary'
,
reshape
([
0
,
1
,
0
]
|
[
0
,
1
,
0
]
'
,
1
,
1
,
3
,
3
));
if
strcmp
(
interpMethod
,
'cubic'
)
&&
any
(
isnan
(
Value
(:)))
%% Crop reference
Value
=
extend
(
Value
,
seSpa
,
6
);
Value
=
Value
(
gv
{:});
Value
=
extend
(
Value
,
seAng
,
6
);
Mask
=
Mask
(
gv
{:});
end
Pos_
=
cellfun
(
@
(
x
)
x
(
1
),
gv
)
-
1
;
if
strcmp
(
interpMethod
,
'cubic'
)
&&
any
(
isnan
(
DispX
(:)))
End_
=
cellfun
(
@
(
x
)
x
(
end
),
gv
);
DispX
=
extend
(
DispX
,
seSpa
,
6
);
DispX
=
extend
(
DispX
,
seAng
,
6
);
end
if
strcmp
(
interpMethod
,
'cubic'
)
&&
any
(
isnan
(
DispY
(:)))
DispY
=
extend
(
DispY
,
seSpa
,
6
);
DispY
=
extend
(
DispY
,
seAng
,
6
);
end
% If view-wise disparity, scale accordingly
%% Compute query grid
if
relative
% Project coordinates
DispX_
=
(
ugv
-
uref
)
.*
DispX
;
SRX
=
X
-
DispX
;
DispY_
=
(
vgv
-
vref
)
.*
DispY
;
SRY
=
Y
-
DispY
;
else
DispX_
=
DispX
;
DispY_
=
DispY
;
end
% Check size of interpolated data (for GriddedInterpolant)
% Projected boundaries
if
numel
(
Value
)
==
1
,
szVal
=
1
;
else
,
szVal
=
size
(
Value
);
end
minPosX
=
floor
(
min
(
SRX
(
Mask
)));
maxPosX
=
ceil
(
max
(
SRX
(
Mask
)));
singValue
=
szVal
==
1
;
minPosY
=
floor
(
min
(
SRY
(
Mask
)));
maxPosY
=
ceil
(
max
(
SRY
(
Mask
)));
if
numel
(
DispX
)
==
1
,
szDispX
=
1
;
else
,
szDispX
=
size
(
DispX
);
end
singDispX
=
szDispX
==
1
;
if
numel
(
DispY
)
==
1
,
szDispY
=
1
;
else
,
szDispY
=
size
(
DispX
);
end
singDispY
=
szDispY
==
1
;
% expand any singleton dimension (need at least 2)
if
any
(
singValue
),
Value
=
repmat
(
Value
,
2
*
singValue
);
end
szVal
=
size
(
Value
);
singDispX
(
end
+
1
:
numel
(
szVal
))
=
1
;
szDispX
(
end
+
1
:
numel
(
szVal
))
=
1
;
singDispY
(
end
+
1
:
numel
(
szVal
))
=
1
;
szDispY
(
end
+
1
:
numel
(
szVal
))
=
1
;
if
any
(
singDispX
),
DispX
=
repmat
(
DispX
,
szVal
.
/
szDispX
);
end
if
any
(
singDispY
),
DispY
=
repmat
(
DispY
,
szVal
.
/
szDispY
);
end
%
Initialize interpolant
s
%
Query grid vector
s
ValueInt
=
griddedInterpolant
(
gv
,
Value
,
interpMethod
,
'nearest'
);
% Interpolant on pixel values
uqgv
=
ugv
;
DispXInt
=
griddedInterpolant
(
gv
,
DispX
,
interpMethod
,
'nearest'
);
% Interpolant on pixel values
vqgv
=
vgv
;
DispYInt
=
griddedInterpolant
(
gv
,
DispY
,
interpMethod
,
'nearest'
);
% Interpolant on pixel values
xqgv
=
minPosX
:
maxPosX
;
MaskInt
=
griddedInterpolant
(
gv
,
double
(
Mask
),
'nearest'
,
'nearest'
);
% Interpolant on masked pixels
yqgv
=
minPosY
:
maxPosY
;
disp
([
'Value: "'
ValueInt
.
Method
'" interp., "'
ValueInt
.
ExtrapolationMethod
'" extrap.'
]);
% Query bounding box
disp
([
'Mask: "'
MaskInt
.
Method
'" interp., "'
MaskInt
.
ExtrapolationMethod
'" extrap.'
])
;
qgv
=
{
uqgv
,
vqgv
,
xqgv
,
yqgv
}
;
% Projected values
% Query grid
projX
=
X
-
DispX_
;
[
Uq
,
Vq
,
Xq
,
Yq
]
=
ndgrid
(
qgv
{:});
projY
=
Y
-
DispY_
;
% Rounded projected values
Xq
=
Xq
+
DispX
;
Yq
=
Yq
+
DispY
;
% Use invertible grid coordinates to compute mask
switch
direction
switch
direction
case
'forward'
case
'forward'
roundProjX
=
floor
(
proj
X
+
0.5
);
Xq_Mask
=
floor
(
X
q
+
0.5
);
roundProjY
=
floor
(
proj
Y
+
0.5
);
Yq_Mask
=
floor
(
Y
q
+
0.5
);
case
'backward'
case
'backward'
roundProjX
=
ceil
(
proj
X
-
0.5
);
Xq_Mask
=
ceil
(
X
q
-
0.5
);
roundProjY
=
ceil
(
proj
Y
-
0.5
);
Yq_Mask
=
ceil
(
Y
q
-
0.5
);
end
end
% Query coordinates
%% Interpolate
Uq
=
U
;
% Extend signal to allow cubic interpolation (way faster than fillmissing)
Vq
=
V
;
seAng
=
strel
(
'arbitrary'
,[
0
,
1
,
0
]
|
[
0
,
1
,
0
]
'
);
Xq
=
X
+
roundProjX
-
projX
;
seSpa
=
strel
(
'arbitrary'
,
reshape
([
0
,
1
,
0
]
|
[
0
,
1
,
0
]
'
,
1
,
1
,
3
,
3
));
Yq
=
Y
+
roundProjY
-
projY
;
% Interpolate at query coordinates
if
strcmp
(
interpMethod
,
'cubic'
)
&&
any
(
isnan
(
Value
(:)))
Value
=
ValueInt
(
Uq
,
Vq
,
Xq
,
Yq
);
Value
=
extend
(
Value
,
seSpa
,
6
);
DispX
=
DispXInt
(
Uq
,
Vq
,
Xq
,
Yq
);
Value
=
extend
(
Value
,
seAng
,
6
);
DispY
=
DispYInt
(
Uq
,
Vq
,
Xq
,
Yq
);
Mask
=
MaskInt
(
Uq
,
Vq
,
Xq
,
Yq
);
Mask
(
isnan
(
Mask
))
=
0
;
Mask
=
logical
(
Mask
);
% Create mask corresponding to query points
switch
SRBoundary
case
'current'
% inside boundary in current view
% Mask = Mask;
case
'any'
% inside boundary in at least one view
Mask
=
repmat
(
any
(
any
(
Mask
,
1
),
2
),
size
(
Mask
,
1
),
size
(
Mask
,
2
),
1
,
1
);
case
'all'
% keep all query points
Mask
=
true
(
Size
);
end
end
if
LFBoundary
% Expand any singleton dimension for interpolation (at least 3 for cubic)
% Mask corresponding to query points inside lightfield boundary
szVal
=
size
(
Value
);
szVal
(
end
+
1
:
4
)
=
1
;
Mask
=
Mask
&
...
Xq
-
Pos
(
3
)
>=
0.5
&
Xq
-
Pos
(
3
)
<=
Size
(
3
)
+
0.5
&
...
% <==> round(Xq)>=1 & round(Xq)<=LFSize(3)
singDims
=
double
(
szVal
==
1
);
Yq
-
Pos
(
4
)
>=
0.5
&
Yq
-
Pos
(
4
)
<=
Size
(
4
)
+
0.5
;
% & round(Yq)>=1 & round(Xq)<=LFSize(4)
if
any
(
singDims
)
Value
=
repmat
(
Value
,
2
*
double
(
singDims
)
+
1
);
for
it
=
find
(
singDims
)
gv
{
it
}
=
gv
{
it
}
-
1
:
gv
{
it
}
+
1
;
end
end
end
% Min and Max x and y coordinates of the pixels of the super-ray
dualDims
=
double
(
szVal
==
2
);
minProjX
=
floor
(
min
(
projX
(:)));
maxProjX
=
ceil
(
max
(
projX
(:)));
if
any
(
dualDims
)
minProjY
=
floor
(
min
(
projY
(:)));
maxProjY
=
ceil
(
max
(
projY
(:)));
Value
=
repmat
(
Value
,
double
(
dualDims
)
+
1
);
for
it
=
find
(
dualDims
)
gv
{
it
}
=
[
gv
{
it
},
gv
{
it
}(
end
)
+
1
];
end
end
% Query grid vectors
projxgv
=
reshape
(
minProjX
:
maxProjX
,
1
,
1
,[]);
projygv
=
reshape
(
minProjY
:
maxProjY
,
1
,
1
,
1
,[]);
% New position
% Cast mask as double for interpolation
projPos
=
Pos
;
Mask
=
double
(
Mask
);
projPos
(
3
)
=
minProjX
-
1
;
projPos
(
4
)
=
minProjY
-
1
;
% Initialize interpolants
ValueInt
=
griddedInterpolant
(
gv
,
Value
,
interpMethod
,
'nearest'
);
% New size
MaskInt
=
griddedInterpolant
(
gv
,
Mask
,
'nearest'
,
'nearest'
);
projSize
=
Size
;
projSize
(
3
)
=
numel
(
projxgv
);
projSize
(
4
)
=
numel
(
projygv
);
% Determine indices corresponding to original and warped pixels
ind
=
sub2ind_
(
Size
,
Pos
,
U
(
ValMask
),
V
(
ValMask
),
X
(
ValMask
),
Y
(
ValMask
));
roundInd
=
sub2ind_
(
projSize
,
projPos
,
U
(
ValMask
),
V
(
ValMask
),
roundProjX
(
ValMask
),
roundProjY
(
ValMask
));
roundMaskInd
=
sub2ind_
(
projSize
,
projPos
,
U
(
Mask
),
V
(
Mask
),
roundProjX
(
Mask
),
roundProjY
(
Mask
));
% Performing warping
projValue
=
nan
(
projSize
);
projMask
=
false
(
projSize
);
projDispX
=
nan
(
projSize
);
projDispY
=
nan
(
projSize
);
projValue
(
roundInd
)
=
Value
(
ind
);
projMask
(
roundMaskInd
)
=
true
;
projDispX
(
roundInd
)
=
DispX
(
ind
);
projDispY
(
roundInd
)
=
DispY
(
ind
);
Value
=
projValue
;
Mask
=
projMask
;
DispX
=
-
projDispX
;
DispY
=
-
projDispY
;
Pos
=
projPos
;
end
function
ind
=
sub2ind_
(
Size
,
Pos
,
varargin
)
% Interpolation
subs
=
varargin
;
Value
=
ValueInt
(
Uq
,
Vq
,
Xq
,
Yq
)
;
Pos
=
num2cell
(
Pos
);
Mask
=
MaskInt
(
Uq
,
Vq
,
Xq_Mask
,
Yq_Mask
);
Mask
=
logical
(
Mask
);
subs
=
cellfun
(
@
minus
,
subs
,
Pos
,
'UniformOutput'
,
false
);
% Mask of query coordinates inside reference boundary
subs
=
cellfun
(
@
(
x
)
x
(:),
subs
,
'UniformOutput'
,
false
);
refMask
=
Xq_Mask
>
Pos_
(
3
)
&
Xq_Mask
<
End_
(
3
)
+
1
&
Yq_Mask
>
Pos_
(
4
)
&
Yq_Mask
<
End_
(
4
)
+
1
;
ind
=
sub2ind
(
Size
,
subs
{:});
end
function
varargout
=
ind2sub_
(
Size
,
Pos
,
ind
)
% New mask
subs
=
cell
(
1
,
numel
(
Size
));
Mask
=
Mask
&
refMask
;
[
subs
{:}]
=
ind2sub
(
Size
,
ind
);
Pos
=
num2cell
(
Pos
);
% New position
Pos
=
Pos
+
cellfun
(
@
(
x
)
x
(
1
),
qgv
)
-
1
;
varargout
=
cellfun
(
@
plus
,
subs
,
Pos
,
'UniformOutput'
,
false
);
% New disparities
dX
=
-
dX
;
dY
=
-
dY
;
end
%% Auxiliary functions
% Compute bounding box of mask
function
gv
=
subarrayIdx
(
Mask
)
s
=
regionprops
(
Mask
,
'SubarrayIdx'
);
if
numel
(
s
)
==
1
gv
=
s
.
SubarrayIdx
;
else
gv
=
{
s
.
SubarrayIdx
};
[
ugv
,
vgv
,
xgv
,
ygv
]
=
cellfun
(
@
(
x
)
deal
(
x
{:}),
gv
,
'UniformOutput'
,
false
);
for
it
=
1
:
numel
(
s
)
-
1
ugv
=
[
union
(
ugv
{
1
},
ugv
{
2
}),
ugv
(
3
:
end
)];
vgv
=
[
union
(
vgv
{
1
},
vgv
{
2
}),
vgv
(
3
:
end
)];
xgv
=
[
union
(
xgv
{
1
},
xgv
{
2
}),
xgv
(
3
:
end
)];
ygv
=
[
union
(
ygv
{
1
},
ygv
{
2
}),
ygv
(
3
:
end
)];
end
ugv
=
min
(
ugv
{:}):
max
(
ugv
{:});
vgv
=
min
(
vgv
{:}):
max
(
vgv
{:});
xgv
=
min
(
xgv
{:}):
max
(
xgv
{:});
ygv
=
min
(
ygv
{:}):
max
(
ygv
{:});
gv
=
{
ugv
,
vgv
,
xgv
,
ygv
};
end
end
end
% Extend signal
function
Value
=
extend
(
Value
,
se
,
numIter
)
function
Value
=
extend
(
Value
,
se
,
numIter
)
for
i
=
1
:
numIter
for
i
=
1
:
numIter
Mask
=
~
isnan
(
Value
);
Mask
=
isnan
(
Value
);
Temp
=
Value
;
Temp
=
Value
;
Temp
(
~
Mask
)
=-
Inf
;
Temp
(
Mask
)
=-
Inf
;
Temp
=
imdilate
(
Temp
,
se
);
Temp
=
imdilate
(
Temp
,
se
);
Temp
(
isinf
(
Temp
))
=
NaN
;
Temp
(
isinf
(
Temp
))
=
NaN
;
Value
(
~
Mask
)
=
Temp
(
~
Mask
);
Value
(
Mask
)
=
Temp
(
Mask
);
end
end
end
end
\ No newline at end of file
This diff is collapsed.
Click to expand it.
warpSet.m
+
4
−
6
View file @
1618a6fb
...
@@ -4,19 +4,17 @@ function SRSet = warpSet(SRSet,varargin)
...
@@ -4,19 +4,17 @@ function SRSet = warpSet(SRSet,varargin)
[
Val
,
Lab
,
Pos
,
DispX
,
DispY
]
=
SR
.
SetToFields
(
SRSet
);
[
Val
,
Lab
,
Pos
,
DispX
,
DispY
]
=
SR
.
SetToFields
(
SRSet
);
Mask
=
Lab
;
for
it
=
1
:
numel
(
Lab
)
for
it
=
1
:
numel
(
Lab
)
Mask
{
it
}
=
Lab
{
it
}
==
it
;
Lab
{
it
}
=
Lab
{
it
}
==
it
;
end
end
for
it
=
1
:
numel
(
Val
)
for
it
=
1
:
numel
(
Val
)
[
Val
{
it
},
Mask
{
it
},
Pos
{
it
},
DispX
{
it
},
DispY
{
it
}]
=
SR
.
warp
(
...
[
Val
{
it
},
Lab
{
it
},
Pos
{
it
},
DispX
{
it
},
DispY
{
it
}]
=
SR
.
warp
(
...
Val
{
it
},
Mask
{
it
},
Pos
{
it
},
DispX
{
it
},
DispY
{
it
},
varargin
{:});
Val
{
it
},
Lab
{
it
},
Pos
{
it
},
DispX
{
it
},
DispY
{
it
},
varargin
{:});
end
end
for
it
=
1
:
numel
(
Lab
)
for
it
=
1
:
numel
(
Lab
)
Lab
{
it
}
=
it
*
double
(
Mask
{
it
});
Lab
{
it
}
=
it
*
double
(
Lab
{
it
});
end
end
SRSet
=
SR
.
FieldsToSet
(
Val
,
Lab
,
Pos
,
DispX
,
DispY
);
SRSet
=
SR
.
FieldsToSet
(
Val
,
Lab
,
Pos
,
DispX
,
DispY
);
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment