Skip to content
Closed
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
1e4d1df
[popsift] choosing a runtime between two descriptor printing mode
Oct 5, 2020
fa695d6
[bugfix] vlfeat compliance in orientation computation
Oct 5, 2020
608eac5
Merge branch 'develop' into fix/misalignBugOri
Oct 5, 2020
0b8fb18
[demo] print default values in usage
Oct 5, 2020
92f1846
[bug] corrected truncating in L2 normalization
Oct 5, 2020
a529cad
[bug] added reverse square root required by previous bugfix
Oct 5, 2020
a9ca694
[feature] VLFeat-compliant descriptor extraction
Oct 5, 2020
003e7ea
[popsift] cleanup
Oct 5, 2020
52c3cbe
[popsift] first parallelism in vlfeat descriptors
Oct 5, 2020
5c0256f
[bugfix] limit accepted orientations to histogram entries 0.8*max again
Oct 5, 2020
bf59959
[popsift] use 32 threads for each descriptor
Oct 5, 2020
d93b8e3
[popsift] commented extended option
Oct 6, 2020
9349547
[popsift] avoid a conflict between old and vlfeat orientation computa…
Oct 6, 2020
942aea1
[cleanup] remove histogram smoothing mode that was never used
Oct 6, 2020
aea885e
[cleanup] remove unused code
Oct 6, 2020
b7bbcd2
[popsift] move rotation compensation to descriptor extraction
Oct 6, 2020
b3f8434
Merge branch 'develop' into fix/vlfeatCompliance
Oct 7, 2020
e9ec403
[popsift] choose between orientation computation modes
Oct 7, 2020
cbf70d0
[bugfix] fix half-bin shift in Interpolated mode
Oct 7, 2020
2708e89
[popsift] minor range modification in orientation computation
Oct 8, 2020
bbc0e75
[doc] improved doc for enum DescMode
Oct 8, 2020
1ea511e
[doc] moved the Usage for the DescMode parameter to sift_conf.cu
Oct 8, 2020
6eeaee3
[doc] Integrating Config defaults into the Usage.
griwodz Oct 8, 2020
e370180
[popsift] added Config::getSigma()
Oct 8, 2020
5591c5b
[popsift] rotate orientation by 180deg in all older modes
Oct 10, 2020
6faa3f4
[test] draft comparison code
Oct 10, 2020
3cdc329
[popsift] remove circular limitation for descriptor in VLFeat mode
Oct 11, 2020
59a70c0
[popsift] avoid boost in libpopsift
Oct 11, 2020
1a54748
[test] updating descriptor file comparison
Oct 11, 2020
085694b
[testing] remove test file, prioritize main PR
Oct 11, 2020
3673a85
[popsift] shorter replace strcmp with string::op==
griwodz Oct 12, 2020
bd1c8ef
[popsift] add more Config::get* functions, improve usage
Oct 12, 2020
74f7053
[popsift] remove failed interpolating orientation code
Oct 16, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ CUDA_ADD_LIBRARY(popsift
popsift/s_desc_grid.cu popsift/s_desc_grid.h
popsift/s_desc_igrid.cu popsift/s_desc_igrid.h
popsift/s_desc_notile.cu popsift/s_desc_notile.h
popsift/s_desc_vlfeat.cu popsift/s_desc_vlfeat.h
popsift/s_desc_norm_rs.h
popsift/s_desc_norm_l2.h
popsift/s_desc_normalize.h
Expand Down
24 changes: 12 additions & 12 deletions src/application/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ using namespace std;
static bool print_dev_info = false;
static bool print_time_info = false;
static bool write_as_uchar = false;
static bool write_with_ori = false;
static bool dont_write = false;
static bool pgmread_loading = false;
static bool float_mode = false;
Expand All @@ -64,13 +65,13 @@ static void parseargs(int argc, char** argv, popsift::Config& config, string& in
parameters.add_options()
("octaves", value<int>(&config.octaves), "Number of octaves")
("levels", value<int>(&config.levels), "Number of levels per octave")
("sigma", value<float>()->notifier([&](float f) { config.setSigma(f); }), "Initial sigma value")
("sigma", value<float>()->notifier([&](float f) { config.setSigma(f); })->default_value(config.getSigma()), "Initial sigma value")

("threshold", value<float>()->notifier([&](float f) { config.setThreshold(f); }), "Contrast threshold")
("edge-threshold", value<float>()->notifier([&](float f) { config.setEdgeLimit(f); }), "On-edge threshold")
("threshold", value<float>()->notifier([&](float f) { config.setThreshold(f); }), "Contrast threshold (default 0.04)")
("edge-threshold", value<float>()->notifier([&](float f) { config.setEdgeLimit(f); }), "On-edge threshold (default 10.0)")
("edge-limit", value<float>()->notifier([&](float f) { config.setEdgeLimit(f); }), "On-edge threshold")
("downsampling", value<float>()->notifier([&](float f) { config.setDownsampling(f); }), "Downscale width and height of input by 2^N")
("initial-blur", value<float>()->notifier([&](float f) {config.setInitialBlur(f); }), "Assume initial blur, subtract when blurring first time");
("initial-blur", value<float>()->notifier([&](float f) {config.setInitialBlur(f); }), "Assume initial blur, subtract when blurring first time (default 0.5)");
}
options_description modes("Modes");
{
Expand All @@ -79,11 +80,8 @@ static void parseargs(int argc, char** argv, popsift::Config& config, string& in
popsift::Config::getGaussModeUsage() )
// "Choice of span (1-sided) for Gauss filters. Default is VLFeat-like computation depending on sigma. "
// "Options are: vlfeat, relative, relative-all, opencv, fixed9, fixed15"
("desc-mode", value<std::string>()->notifier([&](const std::string& s) { config.setDescMode(s); }),
"Choice of descriptor extraction modes:\n"
"loop, iloop, grid, igrid, notile\n"
"Default is loop\n"
"loop is OpenCV-like horizontal scanning, computing only valid points, grid extracts only useful points but rounds them, iloop uses linear texture and rotated gradiant fetching. igrid is grid with linear interpolation. notile is like igrid but avoids redundant gradiant fetching.")
( "desc-mode", value<std::string>()->notifier([&](const std::string& s) { config.setDescMode(s); }),
popsift::Config::getDescModeUsage() )
("popsift-mode", bool_switch()->notifier([&](bool b) { if(b) config.setMode(popsift::Config::PopSift); }),
"During the initial upscale, shift pixels by 1. In extrema refinement, steps up to 0.6, do not reject points when reaching max iterations, "
"first contrast threshold is .8 * peak thresh. Shift feature coords octave 0 back to original pos.")
Expand All @@ -100,11 +98,13 @@ static void parseargs(int argc, char** argv, popsift::Config& config, string& in
"Computed filter width are lower than VLFeat/PopSift")
("direct-scaling", bool_switch()->notifier([&](bool b) { if(b) config.setScalingMode(popsift::Config::ScaleDirect); }),
"Direct each octave from upscaled orig instead of blurred level.")
( "ori-mode", value<std::string>()->notifier([&](const std::string& s) {config.setOrientationMode(s); }),
popsift::Config::getOrientationModeUsage() )
("norm-multi", value<int>()->notifier([&](int i) {config.setNormalizationMultiplier(i); }), "Multiply the descriptor by pow(2,<int>).")
( "norm-mode", value<std::string>()->notifier([&](const std::string& s) { config.setNormMode(s); }),
popsift::Config::getNormModeUsage() )
( "root-sift", bool_switch()->notifier([&](bool b) { if(b) config.setNormMode(popsift::Config::RootSift); }),
popsift::Config::getNormModeUsage() )
"synonym to --norm-mode=RootSift" )
("filter-max-extrema", value<int>()->notifier([&](int f) {config.setFilterMaxExtrema(f); }), "Approximate max number of extrema.")
("filter-grid", value<int>()->notifier([&](int f) {config.setFilterGridSize(f); }), "Grid edge length for extrema filtering (ie. value 4 leads to a 4x4 grid)")
("filter-sort", value<std::string>()->notifier([&](const std::string& s) {config.setFilterSorting(s); }), "Sort extrema in each cell by scale, either random (default), up or down");
Expand All @@ -118,6 +118,7 @@ static void parseargs(int argc, char** argv, popsift::Config& config, string& in
("print-time-info", bool_switch(&print_time_info)->default_value(false), "A debug output printing image processing time after load()")
("write-as-uchar", bool_switch(&write_as_uchar)->default_value(false), "Output descriptors rounded to int.\n"
"Scaling to sensible ranges is not automatic, should be combined with --norm-multi=9 or similar")
("write-with-ori", bool_switch(&write_with_ori)->default_value(false), "Output points are written with sigma and orientation.\n")
("dont-write", bool_switch(&dont_write)->default_value(false), "Suppress descriptor output")
("pgmread-loading", bool_switch(&pgmread_loading)->default_value(false), "Use the old image loader instead of LibDevIL")
("float-mode", bool_switch(&float_mode)->default_value(false), "Upload image to GPU as float instead of byte")
Expand Down Expand Up @@ -254,7 +255,7 @@ void read_job( SiftJob* job, bool really_write )
nvtxRangePushA( "Writing features to disk" );

std::ofstream of( "output-features.txt" );
feature_list->print( of, write_as_uchar );
feature_list->print( of, write_as_uchar, write_with_ori );
}
delete feature_list;

Expand Down Expand Up @@ -327,4 +328,3 @@ int main(int argc, char **argv)

return EXIT_SUCCESS;
}

31 changes: 24 additions & 7 deletions src/popsift/features.cu
Original file line number Diff line number Diff line change
Expand Up @@ -107,16 +107,16 @@ void FeaturesHost::unpin( )
cudaHostUnregister( _ori );
}

void FeaturesHost::print( std::ostream& ostr, bool write_as_uchar ) const
void FeaturesHost::print( std::ostream& ostr, bool write_as_uchar, bool with_orientation ) const
{
for( int i=0; i<size(); i++ ) {
_ext[i].print( ostr, write_as_uchar );
_ext[i].print( ostr, write_as_uchar, with_orientation );
}
}

std::ostream& operator<<( std::ostream& ostr, const FeaturesHost& feature )
{
feature.print( ostr, false );
feature.print( ostr, false, false );
return ostr;
}

Expand Down Expand Up @@ -304,13 +304,30 @@ void FeaturesDev::match( FeaturesDev* other )
* Feature
*************************************************************/

void Feature::print( std::ostream& ostr, bool write_as_uchar ) const
void Feature::print( std::ostream& ostr, bool write_as_uchar, bool with_orientation ) const
{
float sigval = 1.0f / ( sigma * sigma );

for( int ori=0; ori<num_ori; ori++ ) {
ostr << xpos << " " << ypos << " "
<< sigval << " 0 " << sigval << " ";
if( with_orientation )
{
float dom_ori = orientation[ori];
// dom_ori = dom_ori / M_PI2 * 360;
// if (dom_ori < 0) dom_ori += 360;
if (dom_ori < 0) dom_ori += M_PI2;

ostr << std::setprecision(6)
<< xpos << " " << ypos << " "
<< sigma << " "
<< dom_ori << " ";
}
else
{
ostr << std::setprecision(6)
<< xpos << " " << ypos << " "
<< sigval << " 0 "
<< sigval << " ";
}
if( write_as_uchar ) {
for( int i=0; i<128; i++ ) {
ostr << roundf(desc[ori]->features[i]) << " ";
Expand All @@ -328,7 +345,7 @@ void Feature::print( std::ostream& ostr, bool write_as_uchar ) const

std::ostream& operator<<( std::ostream& ostr, const Feature& feature )
{
feature.print( ostr, false );
feature.print( ostr, false, false );
return ostr;
}

Expand Down
4 changes: 2 additions & 2 deletions src/popsift/features.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ struct Feature
float orientation[ORIENTATION_MAX_COUNT];
Descriptor* desc[ORIENTATION_MAX_COUNT];

void print( std::ostream& ostr, bool write_as_uchar ) const;
void print( std::ostream& ostr, bool write_as_uchar, bool with_orientation ) const;
};

std::ostream& operator<<( std::ostream& ostr, const Feature& feature );
Expand Down Expand Up @@ -91,7 +91,7 @@ class FeaturesHost : public FeaturesBase
inline Feature* getFeatures() { return _ext; }
inline Descriptor* getDescriptors() { return _ori; }

void print( std::ostream& ostr, bool write_as_uchar ) const;
void print( std::ostream& ostr, bool write_as_uchar, bool with_orientation ) const;

protected:
friend class Pyramid;
Expand Down
20 changes: 10 additions & 10 deletions src/popsift/s_desc_norm_l2.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,15 @@ void NormalizeL2::normalize( const float* src_desc, float* dst_desc, const bool
float norm;

if( threadIdx.x == 0 ) {
norm = normf( 128, src_desc );
norm = rnormf( 128, src_desc ); // 1/sqrt(sum of squares)
}
__syncthreads();
norm = popsift::shuffle( norm, 0 );

descr.x = min( descr.x, 0.2f*norm );
descr.y = min( descr.y, 0.2f*norm );
descr.z = min( descr.z, 0.2f*norm );
descr.w = min( descr.w, 0.2f*norm );
descr.x = min( descr.x*norm, 0.2f );
descr.y = min( descr.y*norm, 0.2f );
descr.z = min( descr.z*norm, 0.2f );
descr.w = min( descr.w*norm, 0.2f );

norm = descr.x * descr.x
+ descr.y * descr.y
Expand Down Expand Up @@ -96,14 +96,14 @@ void NormalizeL2::normalize( const float* src_desc, float* dst_desc, const bool
norm += popsift::shuffle_down( norm, 2 );
norm += popsift::shuffle_down( norm, 1 );
if( threadIdx.x == 0 ) {
norm = __fsqrt_rn( norm );
norm = __frsqrt_rn( norm );
}
norm = popsift::shuffle( norm, 0 );

descr.x = min( descr.x, 0.2f*norm );
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made a direct comparison between the develop branch and develop with the L2 normalization bug fixed.
I compare the descriptors extracted from all images in the dataset containing boat, bark, bikes, graf, leuven, tree, ubc and wall.
The average number of descriptors extracted per image was 10000.
The largest difference before and after the fix was 2 descriptors changed in 1 value.

descr.y = min( descr.y, 0.2f*norm );
descr.z = min( descr.z, 0.2f*norm );
descr.w = min( descr.w, 0.2f*norm );
descr.x = min( descr.x*norm, 0.2f );
descr.y = min( descr.y*norm, 0.2f );
descr.z = min( descr.z*norm, 0.2f );
descr.w = min( descr.w*norm, 0.2f );

norm = descr.x * descr.x
+ descr.y * descr.y
Expand Down
12 changes: 6 additions & 6 deletions src/popsift/s_desc_normalize.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,17 @@ void normalize_histogram( )
Descriptor* descs = dbuf.desc;
const int num_orientations = dct.ori_total;

int offset = blockIdx.x * 32 + threadIdx.y;
int offset = blockIdx.x * blockDim.y + threadIdx.y;

// all of these threads are useless
if( blockIdx.x * 32 >= num_orientations ) return;
if( blockIdx.x * blockDim.y >= num_orientations ) return;

offset = ( offset < num_orientations ) ? offset
: num_orientations-1;
Descriptor* desc = &descs[offset];
offset = min( offset, num_orientations-1 );

float* features = descs[offset].features;

bool ignoreme = ( offset >= num_orientations );

T::normalize( desc->features, ignoreme );
T::normalize( features, ignoreme );
}

Loading