[vspline] 24/72: pv now uses image pyramid To further reduce stutter with large panoramas, I added code to use a pyramid of slightly smoothed, scaled down spline objects which are put to use depending on the scale of the display. I commit this status quo because it seems to be a nice milestone without any immediately obvious bugs.
Kay F. Jahnke
kfj-guest at moszumanska.debian.org
Sun Jul 2 09:02:39 UTC 2017
This is an automated email from the git hooks/post-receive script.
kfj-guest pushed a commit to branch master
in repository vspline.
commit 7fd27c7ae5beb37c7ad0e403e34b219f18385252
Author: Kay F. Jahnke <kfjahnke at gmail.com>
Date: Mon Jan 2 17:53:42 2017 +0100
pv now uses image pyramid
To further reduce stutter with large panoramas, I added code to use a pyramid
of slightly smoothed, scaled down spline objects which are put to use depending
on the scale of the display. I commit this status quo because it seems to be a nice
milestone without any immediately obvious bugs.
---
brace.h | 11 ++++++++++-
bspline.h | 65 +++++++++++++++++++++++++++++++++++++++++++++------------------
2 files changed, 57 insertions(+), 19 deletions(-)
diff --git a/brace.h b/brace.h
index fdf106e..7cc8093 100644
--- a/brace.h
+++ b/brace.h
@@ -169,7 +169,7 @@ struct bracer
static int left_brace_size ( int spline_degree , bc_code bc )
{
- if ( bc == REFLECT || bc == SPHERICAL )
+ if ( bc == REFLECT || bc == SPHERICAL || bc == RTAG )
return ( spline_degree + 1 ) / 2 ;
else
return spline_degree / 2 ;
@@ -365,6 +365,8 @@ struct bracer
}
case NATURAL :
case MIRROR :
+ case TAG :
+ case TAGP :
{
ls = l0 + 2 ;
rs = r0 - 2 ;
@@ -373,6 +375,7 @@ struct bracer
case CONSTANT :
case SPHERICAL :
case REFLECT :
+ case RTAG :
{
ls = l0 + 1 ;
rs = r0 - 1 ;
@@ -404,6 +407,9 @@ struct bracer
case PERIODIC :
case MIRROR :
case REFLECT :
+ case TAG :
+ case RTAG :
+ case TAGP :
{
// with these three bracing modes, we simply copy from source to target
a.bindAt ( axis , lt ) = a.bindAt ( axis , ls ) ;
@@ -453,6 +459,9 @@ struct bracer
case PERIODIC :
case MIRROR :
case REFLECT :
+ case TAG :
+ case RTAG :
+ case TAGP :
{
// with these three bracing modes, we simply copy from source to target
a.bindAt ( axis , rt ) = a.bindAt ( axis , rs ) ;
diff --git a/bspline.h b/bspline.h
index 3d55b93..bf6d574 100644
--- a/bspline.h
+++ b/bspline.h
@@ -216,7 +216,7 @@ public:
/// setup_metrics determines the sizes of the three views and any braces/frames
/// needed with the given parameters
- void setup_metrics()
+ void setup_metrics ( int headroom = 0 )
{
switch ( strategy )
{
@@ -231,13 +231,14 @@ public:
// again an implicit prefiltering scheme will be used, but here we add
// a 'brace' to the core data, which makes the resulting bspline object
// suitable to work with vspline's evaluation code. The container array's
- // size is the same as the braced core's size.
+ // size is the same as the braced core's size, unless additional headroom
+ // was requested.
braced_shape = bracer<view_type>::target_shape ( core_shape , bcv , spline_degree ) ;
left_brace = bracer<view_type>::left_corner ( bcv , spline_degree ) ;
right_brace = bracer<view_type>::right_corner ( bcv , spline_degree ) ;
- left_frame = left_brace ;
- right_frame = right_brace ;
- container_shape = braced_shape ;
+ left_frame = left_brace + headroom ;
+ right_frame = right_brace + headroom ;
+ container_shape = core_shape + left_frame + right_frame ;
braced = true ;
break ;
case EXPLICIT:
@@ -245,12 +246,13 @@ public:
// space, namely the 'frame', around the core data, into which the extrapolated
// data are put before prefiltering the lot. This frame is applied in excess of
// the bracing, to make sure all coefficients inside the brace meet the precision
- // requirements expressed by the choice of 'horizon'.
+ // requirements expressed by the choice of 'horizon'. If additional headroom
+ // is requested, this comes yet on top.
braced_shape = bracer<view_type>::target_shape ( core_shape , bcv , spline_degree ) ;
left_brace = bracer<view_type>::left_corner ( bcv , spline_degree ) ;
right_brace = bracer<view_type>::right_corner ( bcv , spline_degree ) ;
- left_frame = left_brace + horizon ;
- right_frame = right_brace + horizon ;
+ left_frame = left_brace + horizon + headroom ;
+ right_frame = right_brace + horizon + headroom ;
container_shape = core_shape + left_frame + right_frame ;
braced = true ;
break ;
@@ -302,6 +304,10 @@ public:
/// deemed to be 'sufficiently large' to keep the error 'low enough'. the expression
/// used here produces a frame which is roughly the size needed to make any margin
/// effects vanish by the time the prefilter hits the core, but it's a bit 'rule of thumb'.
+ ///
+ /// The additional parameter 'headroom' is used to make the 'frame' even wider. This is
+ /// needed if the spline is to be 'shifted' up (evaluated as if it had been prefiltered
+ /// with a higher-degree prefilter) - see shift().
// TODO: when bracing/framing is applied, we might widen the array size to a
// multiple of the Vc:Vector's Size for the given data type to have better-aligned
@@ -313,6 +319,8 @@ public:
// widen class bspline's scope to accept input of other types and/or use a different
// math_type.
+ // TODO: write copy constructor, operator=
+
bspline ( shape_type _core_shape , ///< shape of knot point data
int _spline_degree = 3 , ///< spline degree with reasonable default
bcv_type _bcv = bcv_type ( MIRROR ) , ///< boundary conditions and common default
@@ -320,7 +328,8 @@ public:
int _horizon = -1 , ///< width of frame for explicit scheme
view_type _space = view_type() , ///< coefficient storage to 'adopt'
double _tolerance = -1.0 , ///< acceptable error (relative to unit pulse)
- double _smoothing = 0.0 ///< apply smoothing to data before prefiltering
+ double _smoothing = 0.0 , ///< apply smoothing to data before prefiltering
+ int headroom = 0 ///< additional headroom, for 'shifting'
)
: core_shape ( _core_shape ) ,
spline_degree ( _spline_degree ) ,
@@ -355,7 +364,7 @@ public:
horizon = _horizon ; // whatever the user specifies
// first, calculate all the various shapes and sizes used internally
- setup_metrics() ;
+ setup_metrics ( headroom ) ;
// now either adopt external memory or allocate memory for the coefficients
if ( _space.hasData() )
@@ -392,7 +401,10 @@ public:
/// prefilter converts the knot point data in the 'core' area into b-spline
/// coefficients. Depending on the strategy chosen in the b-spline object's
- /// constructor, bracing/framing may be applied.
+ /// constructor, bracing/framing may be applied. Even if the degree of the
+ /// spline is zero or one, prefilter() should be called because it also
+ /// performs the bracing, if any, which may still be needed if the spline
+ /// is 'shifted' - unless the stratgey is UNBRACED, of course.
///
/// If data are passed in, they have to have precisely the shape
/// we have set up in core (_core_shape passed into the constructor).
@@ -416,7 +428,8 @@ public:
// spline but constitutes a view to data kept elsewhere (by passing _space to the
// constructor).
if ( data.shape() != core_shape )
- throw shape_mismatch ( "when passing data to prefilter, they have to have precisely the core's shape" ) ;
+ throw shape_mismatch
+ ( "when passing data to prefilter, they have to have precisely the core's shape" ) ;
if ( strategy == EXPLICIT )
{
// the explicit scheme requires the data and frame to be together in the
@@ -475,11 +488,17 @@ public:
use_vc ,
nthreads
) ;
+ // using the more general code here now, since the frame may be larger
+ // than strictly necessary for the given spline degree due to a request
+ // for additional headroom
for ( int d = 0 ; d < dimension ; d++ )
- br ( coeffs , bcv[d] , spline_degree , d ) ;
+ br.apply ( container , bcv[d] , left_frame[d] , right_frame[d] , d ) ;
+// was:
+// for ( int d = 0 ; d < dimension ; d++ )
+// br ( coeffs , bcv[d] , spline_degree , d ) ;
break ;
case EXPLICIT:
- // apply bracing with BC codes passed in, then solve with BC code IGNORE
+ // apply bracing with BC codes passed in, then solve with BC code GUESS
// this automatically fills the brace, as well, since it's part of the frame.
// TODO: the values in the frame will not come out precisely the same as they
// would by filling the brace after the coefficients have been calculated.
@@ -502,7 +521,7 @@ public:
break ;
case MANUAL:
// like EXPLICIT, but don't apply a frame, assume a frame was applied
- // by external code. process whole container with IGNORE BC. For cases
+ // by external code. process whole container with GUESS BC. For cases
// where the frame can't be constructed by applying any of the stock bracing
// modes. Note that if any data were passed into this routine, in this case
// they will be silently ignored (makes no sense overwriting the core after
@@ -531,7 +550,9 @@ public:
prefilter_strategy _strategy = BRACED , ///< default strategy is the 'implicit' scheme
int _horizon = -1 , ///< width of frame for explicit scheme
view_type _space = view_type() , ///< coefficient storage to 'adopt'
- double _tolerance = -1.0 ///< acceptable error (relative to unit pulse)
+ double _tolerance = -1.0 , ///< acceptable error (relative to unit pulse)
+ double _smoothing = 0.0 , ///< apply smoothing to data before prefiltering
+ int headroom = 0 ///< additional headroom, for 'shifting'
)
:bspline ( TinyVector < long , 1 > ( _core_shape ) ,
_spline_degree ,
@@ -539,7 +560,10 @@ public:
_strategy ,
_horizon ,
_space ,
- _tolerance )
+ _tolerance ,
+ _smoothing ,
+ headroom
+ )
{
static_assert ( _dimension == 1 , "bspline: 1D constructor only usable for 1D splines" ) ;
} ;
@@ -552,7 +576,11 @@ public:
/// interpolated signal, shifting with negative d will sharpen it.
/// For shifting to work, the spline has to have enough 'headroom', meaning that
/// spline_degree + d, the new spline degree, has to be greater or equal to 0
- /// and smaller than the largest supported spline degree (lower twenties)
+ /// and smaller than the largest supported spline degree (lower twenties) -
+ /// and, additionally, there has to bee a wide-enough brace to allow evaluation
+ /// with the wider kernel of the higher-degree spline's reconstruction filter.
+ /// So if a spline is set up with degree 0 and shifted to degree 5, it has to be
+ /// constructed with an additional headroom of 3 (see the constructor).
/// This is a quick-shot solution to the problem of scaled-down interpolated
/// results; it may be better in some situations to shift the spline up and
/// evaluate than to apply smoothing to the source data.
@@ -624,6 +652,7 @@ public:
osr << "left frame:.................. " << bsp.left_frame << endl ;
osr << "right frame:................. " << bsp.right_frame << endl ;
osr << ( bsp._coeffs.hasData() ? "bspline object owns data" : "data are owned externally" ) << endl ;
+ osr << "container base adress:....... " << bsp.container.data() << endl ;
return osr ;
}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/vspline.git
More information about the debian-science-commits
mailing list