Skip to content

Commit a30a990

Browse files
griwodzCarsten Griwodz
andauthored
[sift] Remove direct downscaling from input image to top level of every octave (#178)
* [sift] Remove option to create all octaves directly from the input * [sift] reduce size of GaussTable dd to 1: The other levels of this table existed only for direct downscaling. * update CHANGES * [sift] remove some code that is now dead --------- Co-authored-by: Carsten Griwodz <[email protected]>
1 parent e4e114a commit a30a990

File tree

11 files changed

+38
-108
lines changed

11 files changed

+38
-108
lines changed

CHANGES.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1515

1616
### Removed
1717

18+
## [0.10.1] - 2025-10-21
19+
20+
### Removed
21+
22+
- Removed option to create top level of every octave from input image [PR](https://github.com/alicevision/popsift/pull/178)
23+
1824
## [0.10.0] - 2025-10-14
1925

2026
### Added

src/application/main.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,6 @@ static void parseargs(int argc, char** argv, popsift::Config& config, string& in
8888
"reject points when reaching max iterations, "
8989
"first contrast threshold is floor(.5 * peak thresh). "
9090
"Computed filter width are lower than VLFeat/PopSift")
91-
("direct-scaling", bool_switch()->notifier([&](bool b) { if(b) config.setScalingMode(popsift::Config::ScaleDirect); }),
92-
"Direct each octave from upscaled orig instead of blurred level.")
9391
("norm-multi", value<int>()->notifier([&](int i) {config.setNormalizationMultiplier(i); }), "Multiply the descriptor by pow(2,<int>).")
9492
( "norm-mode", value<std::string>()->notifier([&](const std::string& s) { config.setNormMode(s); }),
9593
popsift::Config::getNormModeUsage() )

src/application/match.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,6 @@ static void parseargs(int argc, char** argv, popsift::Config& config, string& lF
8686
"reject points when reaching max iterations, "
8787
"first contrast threshold is floor(.5 * peak thresh). "
8888
"Computed filter width are lower than VLFeat/PopSift")
89-
("direct-scaling", bool_switch()->notifier([&](bool b) { if(b) config.setScalingMode(popsift::Config::ScaleDirect); }),
90-
"Direct each octave from upscaled orig instead of blurred level.")
9189
("norm-multi", value<int>()->notifier([&](int i) {config.setNormalizationMultiplier(i); }), "Multiply the descriptor by pow(2,<int>).")
9290
( "norm-mode", value<std::string>()->notifier([&](const std::string& s) { config.setNormMode(s); }),
9391
popsift::Config::getNormModeUsage() )

src/popsift/gauss_filter.cu

Lines changed: 17 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -102,21 +102,19 @@ void print_gauss_filter_symbol( int columns )
102102
}
103103
printf("\n");
104104

105-
printf(" level 0-filters for direct downscaling\n");
105+
printf(" level 0-filter for the creation of the first level of the first octave\n" );
106106

107-
for( int lvl=0; lvl<MAX_OCTAVES; lvl++ ) {
108-
int span = d_gauss.dd.span[lvl] + d_gauss.dd.span[lvl] - 1;
107+
int span = d_gauss.dd.span[0] + d_gauss.dd.span[0] - 1;
109108

110-
printf(" %d %d %2.6f: ", lvl, span, d_gauss.dd.sigma[lvl] );
111-
int m = min( d_gauss.dd.span[lvl], columns );
112-
for( int x=0; x<m; x++ ) {
113-
printf("%0.8f ", d_gauss.dd.filter[lvl*GAUSS_ALIGN+x] );
114-
}
115-
if( m < d_gauss.dd.span[lvl] )
116-
printf("...\n");
117-
else
118-
printf("\n");
109+
printf(" %d %d %2.6f: ", 0, span, d_gauss.dd.sigma[0] );
110+
int m = min( d_gauss.dd.span[0], columns );
111+
for( int x=0; x<m; x++ ) {
112+
printf("%0.8f ", d_gauss.dd.filter[x] );
119113
}
114+
if( m < d_gauss.dd.span[0] )
115+
printf("...\n");
116+
else
117+
printf("\n");
120118
printf("\n");
121119
}
122120

@@ -215,26 +213,17 @@ void init_filter( const Config& conf,
215213
h_gauss.abs_oN.computeBlurTable( &h_gauss );
216214

217215
/* dd :
218-
* The direct-downscaling kernels make use of the assumption that downscaling
219-
* from MAX_LEVEL-3 is identical to applying 2*sigma on the identical image
220-
* before downscaling, which would be identical to applying 1*sigma after
221-
* downscaling.
222-
* In reality, this is not true because images are not continuous, but we
223-
* support the options because it is interesting. Perhaps it works for the later
224-
* octaves, where it is also good for performance.
216+
* A leftover from an attempt to create all top levels of all octaves from the
217+
* input image.
225218
* dd is only for creating level 0 of all octave directly from the input image.
226219
*/
227-
for( int oct=0; oct<MAX_OCTAVES; oct++ ) {
228-
// sigma * 2^i
229-
float oct_sigma = scalbnf( sigma0, oct );
230220

231-
// subtract initial blur
232-
float b = sqrt( fabs( oct_sigma * oct_sigma - initial_blur * initial_blur ) );
221+
// subtract initial blur
222+
const float sigma_o0_l0 = sqrt( fabs( sigma0 * sigma0 - initial_blur * initial_blur ) );
233223

234-
// sigma / 2^i
235-
h_gauss.dd.sigma[oct] = scalbnf( b, -oct );
236-
h_gauss.dd.computeBlurTable( &h_gauss );
237-
}
224+
// sigma / 2^i
225+
h_gauss.dd.sigma[0] = sigma_o0_l0;
226+
h_gauss.dd.computeBlurTable( &h_gauss );
238227

239228
cudaError_t err;
240229
err = cudaMemcpyToSymbol( d_gauss,

src/popsift/gauss_filter.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,13 @@ struct GaussInfo
7474
*/
7575
GaussTable<GAUSS_LEVELS> abs_oN;
7676

77-
/* In theory, level 0 of octave 2 contains the same information
78-
* whether it is constructed by downscaling and blurring the
79-
* input image with sigma or by blurring the input image with 2*sigma
80-
* and downscaling afterwards.
77+
/* The dd table was meant for the creation of every top-level of
78+
* every octave directly from the upscaling input image. This option
79+
* has been removed because it didn't work well.
80+
* As a consequence, the table dd needs only its first entry for
81+
* Gaussian filtering of the first octave.
8182
*/
82-
GaussTable<MAX_OCTAVES> dd;
83+
GaussTable<1> dd;
8384

8485
__host__
8586
void clearTables( );

src/popsift/s_pyramid_build.cu

Lines changed: 7 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,9 @@ void make_dog( cudaTextureObject_t src_data,
9494
} // namespace gauss
9595

9696
__host__
97-
inline void Pyramid::horiz_from_input_image( const Config& conf, ImageBase* base, int octave, cudaStream_t stream )
97+
inline void Pyramid::horiz_from_input_image( const Config& conf, ImageBase* base, cudaStream_t stream )
9898
{
99-
Octave& oct_obj = _octaves[octave];
99+
Octave& oct_obj = _octaves[0];
100100

101101
const int width = oct_obj.getWidth();
102102
const int height = oct_obj.getHeight();
@@ -109,8 +109,8 @@ inline void Pyramid::horiz_from_input_image( const Config& conf, ImageBase* base
109109
const Config::SiftMode& mode = conf.getSiftMode();
110110
float shift = 0.5f;
111111

112-
if( octave == 0 && ( mode == Config::PopSift || mode == Config::VLFeat ) ) {
113-
shift = 0.5f * powf( 2.0f, conf.getUpscaleFactor() - octave );
112+
if( mode == Config::PopSift || mode == Config::VLFeat ) {
113+
shift = 0.5f * powf( 2.0f, conf.getUpscaleFactor() );
114114
}
115115

116116
gauss::normalizedSource::horiz
@@ -119,7 +119,6 @@ inline void Pyramid::horiz_from_input_image( const Config& conf, ImageBase* base
119119
oct_obj.getIntermediateSurface(),
120120
width,
121121
height,
122-
octave,
123122
shift );
124123

125124
POP_SYNC_CHK;
@@ -475,16 +474,7 @@ void Pyramid::build_pyramid( const Config& conf, ImageBase* base )
475474
Octave& oct_obj = _octaves[octave];
476475
cudaStream_t stream = oct_obj.getStream();
477476

478-
if( ( conf.getScalingMode() == Config::ScaleDirect ) &&
479-
( conf.getGaussMode() == Config::Fixed9 || conf.getGaussMode() == Config::Fixed15 ) ) {
480-
if( octave == 0 ) {
481-
make_octave( conf, base, oct_obj, stream, true );
482-
} else {
483-
horiz_from_input_image( conf, base, octave, stream );
484-
vert_from_interm( octave, 0, stream, NotInterpolated_FromPrevious );
485-
make_octave( conf, base, oct_obj, stream, false );
486-
}
487-
} else if( conf.getGaussMode() == Config::Fixed9 || conf.getGaussMode() == Config::Fixed15 ) {
477+
if( conf.getGaussMode() == Config::Fixed9 || conf.getGaussMode() == Config::Fixed15 ) {
488478
if( octave == 0 ) {
489479
make_octave( conf, base, oct_obj, stream, true );
490480
} else {
@@ -496,30 +486,14 @@ void Pyramid::build_pyramid( const Config& conf, ImageBase* base )
496486
}
497487

498488
cuda::event_record( oct_obj.getEventScaleDone(), stream, __FILE__, __LINE__ );
499-
} else if( conf.getScalingMode() == Config::ScaleDirect ) {
500-
GaussTableChoice useGauss = ( conf.getGaussMode() == Config::VLFeat_Relative ) ? Interpolated_FromPrevious
501-
: NotInterpolated_FromPrevious;
502-
for( int level=0; level<_levels; level++ )
503-
{
504-
if( level == 0 )
505-
{
506-
horiz_from_input_image( conf, base, octave, stream );
507-
vert_from_interm( octave, level, stream, useGauss );
508-
}
509-
else
510-
{
511-
horiz_from_prev_level( octave, level, stream, useGauss );
512-
vert_from_interm( octave, level, stream, useGauss );
513-
}
514-
}
515489
} else if( conf.getGaussMode() == Config::VLFeat_Relative ) {
516490
for( int level=0; level<_levels; level++ )
517491
{
518492
if( level == 0 )
519493
{
520494
if( octave == 0 )
521495
{
522-
horiz_from_input_image( conf, base, 0, stream );
496+
horiz_from_input_image( conf, base, stream );
523497
vert_from_interm( octave, 0, stream, Interpolated_FromPrevious );
524498
}
525499
else
@@ -551,7 +525,7 @@ void Pyramid::build_pyramid( const Config& conf, ImageBase* base )
551525
{
552526
if( octave == 0 )
553527
{
554-
horiz_from_input_image( conf, base, 0, stream );
528+
horiz_from_input_image( conf, base, stream );
555529
vert_from_interm( octave, 0, stream, NotInterpolated_FromPrevious );
556530
}
557531
else

src/popsift/s_pyramid_build_ra.cu

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,15 @@ void horiz( cudaTextureObject_t src_linear_tex,
1919
cudaSurfaceObject_t dst_data,
2020
int dst_w,
2121
int dst_h,
22-
int octave,
2322
float shift )
2423
{
25-
// Create level-0 for any octave from the input image.
26-
// Since we are computing the direct-downscaling gauss filter tables
27-
// and the first entry in that table is identical to the "normal"
28-
// table, we do not need a special case.
29-
3024
const int write_x = blockIdx.x * blockDim.x + threadIdx.x;
3125
const int write_y = blockIdx.y;
3226

3327
if( write_x >= dst_w ) return;
3428

35-
const int span = d_gauss.dd.span[octave];
36-
const float* filter = &d_gauss.dd.filter[octave*GAUSS_ALIGN];
29+
const int span = d_gauss.dd.span[0];
30+
const float* filter = &d_gauss.dd.filter[0];
3731
const float read_x = ( blockIdx.x * blockDim.x + threadIdx.x + shift ) / dst_w;
3832
const float read_y = ( blockIdx.y + shift ) / dst_h;
3933

src/popsift/s_pyramid_build_ra.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ __global__ void horiz(cudaTextureObject_t src_data,
1515
cudaSurfaceObject_t dst_data,
1616
int dst_w,
1717
int dst_h,
18-
int octave,
1918
float shift);
2019

2120
__global__ void horiz_level(cudaTextureObject_t src_linear_tex,

src/popsift/sift_conf.cu

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ Config::Config( )
2525
, _gauss_mode( getGaussModeDefault() )
2626
, _sift_mode( Config::PopSift )
2727
, _log_mode( Config::None )
28-
, _scaling_mode( Config::ScaleDefault )
2928
, _desc_mode( Config::Loop )
3029
, _grid_filter_mode( Config::RandomScale )
3130
, verbose( false )
@@ -182,11 +181,6 @@ Config::LogMode Config::getLogMode( ) const
182181
return _log_mode;
183182
}
184183

185-
void Config::setScalingMode( ScalingMode mode )
186-
{
187-
_scaling_mode = mode;
188-
}
189-
190184
/**
191185
* Normalization mode
192186
* Should the descriptor normalization use L2-like classic normalization
@@ -313,7 +307,6 @@ bool Config::equal( const Config& other ) const
313307
COMPARE( _edge_limit ) ||
314308
COMPARE( _threshold ) ||
315309
COMPARE( _upscale_factor ) ||
316-
COMPARE( _scaling_mode ) ||
317310
COMPARE( _max_extrema ) ||
318311
COMPARE( _gauss_mode ) ||
319312
COMPARE( _sift_mode ) ||

src/popsift/sift_conf.h

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -69,16 +69,6 @@ struct Config
6969
All
7070
};
7171

72-
/**
73-
* @brief The scaling mode.
74-
*/
75-
enum ScalingMode
76-
{
77-
ScaleDirect,
78-
/// Indirect - only working method
79-
ScaleDefault
80-
};
81-
8272
/**
8373
* @brief Modes for descriptor extraction.
8474
*/
@@ -164,7 +154,6 @@ struct Config
164154
* @see LogMode
165155
*/
166156
void setLogMode( LogMode mode = All );
167-
void setScalingMode( ScalingMode mode = ScaleDefault );
168157

169158
/**
170159
* @brief Enable/desable verbose mode.
@@ -328,13 +317,6 @@ struct Config
328317
*/
329318
GridFilterMode getFilterSorting() const { return _grid_filter_mode; }
330319

331-
/**
332-
* @brief Get the scaling mode.
333-
* @return the descriptor extraction mode.
334-
* @see ScalingMode
335-
*/
336-
inline ScalingMode getScalingMode() const { return _scaling_mode; }
337-
338320
/**
339321
* @brief Get the descriptor extraction mode
340322
* @return the descriptor extraction mode
@@ -361,9 +343,6 @@ struct Config
361343
/// default LogMode::None
362344
LogMode _log_mode;
363345

364-
/// default: ScalingMode::DownscaledOctaves
365-
ScalingMode _scaling_mode;
366-
367346
/// default: DescMode::Loop
368347
DescMode _desc_mode;
369348

0 commit comments

Comments
 (0)