Skip to content

Commit 0873914

Browse files
author
Carsten Griwodz
committed
[testing] Compare various descriptors
[test] split compare functions [test] remove binary [test] rename file for Make executation [test] minor code cleanup [test] CMake for compareSiftFiles binary [test] add compareDescriptors to cmake [test] add popsift prefix to testing binary [test] adapt scripts to new name [test] new option dv, fix codacy bug [test] typo [test] move desc comparator to src [test] CodeFactor fix [test] update CHANGES.md [test] fixed typo [test] autofill some variables in compare script [test] generate make helper for desc comparison [test] boost program options in compareSiftFiles [test] generated test files [test] relative test script path [test] convert test images
1 parent 2fc75f4 commit 0873914

15 files changed

Lines changed: 797 additions & 0 deletions

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2323
- CMake: support for cuda 11 [PR](https://github.com/alicevision/popsift/pull/103)
2424
- Support for Cuda CC 7 cards (RTX 2080) [PR](https://github.com/alicevision/popsift/pull/67)
2525
- Support for Boost 1.70 [PR](https://github.com/alicevision/popsift/pull/65)
26+
- Test: adding descriptor comparator [PR](https://github.com/alicevision/popsift/pull/115)
2627

2728
### Fixed
2829
- CMake: fixes to allow building on Windows using vcpkg [PR](https://github.com/alicevision/popsift/pull/92)

CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ else()
3434
message(STATUS "Building in ${CMAKE_BUILD_TYPE} configuration")
3535
endif()
3636

37+
include(FindOpenACC)
38+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenACC_CXX_FLAGS}")
39+
3740
# ensure the proper linker flags when building the static version on MSVC
3841
if(MSVC AND NOT BUILD_SHARED_LIBS)
3942
foreach(config "DEBUG" "RELEASE" "MINSIZEREL" "RELWITHDEBINFO")

src/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,3 +150,7 @@ if(PopSift_BUILD_EXAMPLES)
150150
add_subdirectory(application)
151151
endif()
152152

153+
if(PopSift_USE_TEST_CMD)
154+
add_subdirectory(compareSiftFiles)
155+
endif()
156+
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
if(NOT CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
2+
# I am top-level project, i.e. I am not being include by another project
3+
cmake_minimum_required(VERSION 3.12)
4+
project(PopSiftCompareDescriptors LANGUAGES CXX)
5+
6+
include(GNUInstallDirs)
7+
8+
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}")
9+
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}")
10+
endif()
11+
12+
if(PopSift_BOOST_USE_STATIC_LIBS)
13+
set(Boost_USE_STATIC_LIBS ON)
14+
endif()
15+
find_package(Boost 1.53.0 REQUIRED COMPONENTS filesystem program_options system)
16+
if(WIN32)
17+
add_definitions("-DBOOST_ALL_NO_LIB")
18+
endif(WIN32)
19+
20+
#############################################################
21+
# compareSiftFiles
22+
#############################################################
23+
24+
add_executable(popsift-compareSiftFiles
25+
compareSiftFiles.cpp
26+
csf_feat.cpp csf_feat.h
27+
csf_options.cpp csf_options.h)
28+
29+
target_include_directories(popsift-compareSiftFiles PUBLIC ${Boost_INCLUDE_DIRS})
30+
target_link_libraries(popsift-compareSiftFiles PUBLIC ${Boost_LIBRARIES})
31+
32+
set_property(TARGET popsift-compareSiftFiles PROPERTY CXX_STANDARD 11)
33+
34+
#############################################################
35+
# installation
36+
#############################################################
37+
38+
install(TARGETS popsift-compareSiftFiles DESTINATION ${CMAKE_INSTALL_BINDIR})
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
#include <iostream>
2+
#include <iomanip>
3+
#include <fstream>
4+
#include <sstream>
5+
#include <cmath>
6+
#include <vector>
7+
#include <algorithm>
8+
#include <cstring>
9+
10+
#include <boost/program_options.hpp>
11+
12+
#include "csf_feat.h"
13+
#include "csf_options.h"
14+
15+
using namespace std;
16+
17+
typedef vector<float> desc_t;
18+
19+
void readFile( vector<feat_t>& vec, const std::string& filename );
20+
21+
int main( int argc, char* argv[] )
22+
{
23+
Parameters param;
24+
25+
parseargs( argc, argv, param );
26+
27+
vector<feat_t> l_one;
28+
vector<feat_t> l_two;
29+
30+
readFile( l_one, param.input[0] );
31+
readFile( l_two, param.input[1] );
32+
33+
ostream* outfile = &cout;
34+
if( ! param.outfile_name.empty() )
35+
{
36+
ostream* o = new ofstream( param.outfile_name );
37+
if( o->good() )
38+
{
39+
outfile = o;
40+
}
41+
}
42+
43+
ostream* descfile = 0;
44+
if( ! param.descfile_name.empty() )
45+
{
46+
ostream* o = new ofstream( param.descfile_name );
47+
if( o->good() )
48+
{
49+
descfile = o;
50+
}
51+
}
52+
53+
int len = l_one.size();
54+
int ct = 0;
55+
float nextpercent = 10;
56+
57+
vector<float> desc_stats( 128, 0.0f );
58+
59+
for( auto l : l_one )
60+
{
61+
ostream* print_dists = param.descfile_verbose ? descfile : 0;
62+
63+
l.compareBestMatch( *outfile, print_dists, l_two, desc_stats, param.briefinfo );
64+
ct++;
65+
if( float(ct * 100) / len >= float(nextpercent) )
66+
{
67+
cerr << nextpercent << "% " << ct << endl;
68+
nextpercent += 10;
69+
}
70+
}
71+
72+
if( descfile )
73+
{
74+
int sz = l_one.size();
75+
(*descfile) << "========== Summary Stats ==========" << endl
76+
<< "Average values:" << endl
77+
<< setprecision(3);
78+
for( int i=0; i<128; i++ )
79+
{
80+
if( i%32==0 ) (*descfile) << "X=0 | ";
81+
if( i%32==8 ) (*descfile) << "X=1 | ";
82+
if( i%32==16 ) (*descfile) << "X=2 | ";
83+
if( i%32==24 ) (*descfile) << "X=3 | ";
84+
desc_stats[i] /= sz;
85+
(*descfile) << setw(8) << desc_stats[i] << " ";
86+
if( i%8==7 ) (*descfile) << endl;
87+
}
88+
(*descfile) << endl;
89+
}
90+
91+
if( ! param.outfile_name.empty() )
92+
{
93+
delete outfile;
94+
}
95+
}
96+
97+
void readFile( vector<feat_t>& vec, const std::string& filename )
98+
{
99+
ifstream infile( filename );
100+
101+
if( ! infile.good() )
102+
{
103+
cerr << "File " << filename << " is not open." << endl;
104+
exit( -1 );
105+
}
106+
107+
int lines_read = readFeats( vec, infile );
108+
cerr << "Read " << lines_read << " lines from " << filename << endl;
109+
}
110+

src/compareSiftFiles/csf_feat.cpp

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
#include <sstream>
2+
#include <cmath>
3+
#include <algorithm>
4+
5+
#include "csf_feat.h"
6+
7+
using namespace std;
8+
9+
const float M_PI2 = 2.0f * 3.14159265358979323846f;
10+
11+
bool feat_t::_use_l2_distance = true;
12+
13+
int readFeats( vector<feat_t>& l_one, ifstream& f_one )
14+
{
15+
char buffer[1024];
16+
int lines_read;
17+
18+
lines_read = 0;
19+
while( f_one.good() )
20+
{
21+
f_one.getline( buffer, 1024 );
22+
if( f_one.good() )
23+
{
24+
bool success = addFeat( l_one, buffer );
25+
if( success )
26+
{
27+
lines_read++;
28+
}
29+
}
30+
}
31+
return lines_read;
32+
}
33+
34+
bool addFeat( vector<feat_t>& features, char* line )
35+
{
36+
vector<float> values(5+128); // 4 or 5 values followed by 128 desc values
37+
38+
int i = 0;
39+
istringstream s( line );
40+
while( s >> values[i] )
41+
{
42+
i++;
43+
}
44+
45+
// cerr << "Found " << i << " floats in line" << endl;
46+
features.emplace_back( i, values );
47+
48+
if( i == 0 ) return false;
49+
return true;
50+
}
51+
52+
feat_t::feat_t( int num, const vector<float>& input )
53+
: desc(128)
54+
{
55+
auto it = input.begin();
56+
auto to = desc.begin();
57+
if( num == 132 )
58+
{
59+
x = *it++;
60+
y = *it++;
61+
sigma = *it++;
62+
ori = *it++;
63+
for( int i=0; i<128; i++ ) *to++ = *it++;
64+
}
65+
else if( num == 133 )
66+
{
67+
float odbss;
68+
x = *it++;
69+
y = *it++;
70+
odbss = *it++;
71+
sigma = odbss == 0.0f ? 0.0f : sqrtf( 1.0f / odbss );
72+
ori = 0.0f;
73+
it++;
74+
it++;
75+
for( int i=0; i<128; i++ ) *to++ = *it++;
76+
}
77+
else
78+
{
79+
cerr << "The keypoint line contains an unexpected number of floats (" << num << ")" << endl;
80+
return;
81+
}
82+
}
83+
84+
void feat_t::print( ostream& ostr ) const
85+
{
86+
ostr << "(" << x << "," << y << ")";
87+
ostr << " sigma=" << sigma << " ori=" << ori;
88+
for( auto it : desc )
89+
{
90+
ostr << " " << it;
91+
}
92+
}
93+
94+
void feat_t::compareBestMatch( ostream& ostr, ostream* dstr, const vector<feat_t>& l_one, vector<float>& desc_stats, bool minOnly ) const
95+
{
96+
vector<float> distances;
97+
distances.reserve( l_one.size() );
98+
99+
if( !minOnly ) ostr << "==========" << endl;
100+
for( auto r : l_one )
101+
{
102+
float v = dist( r );
103+
distances.push_back( v );
104+
}
105+
106+
auto it = distances.begin();
107+
108+
auto m = min_element( distances.begin(), distances.end() );
109+
110+
float second = INFINITY;
111+
112+
for( auto r : l_one )
113+
{
114+
if( minOnly )
115+
{
116+
if( it == m )
117+
{
118+
ostr << "desc dist " << *it
119+
<< " MIN"
120+
<< " pixdist " << sqrtf( (x-r.x)*(x-r.x) + (y-r.y)*(y-r.y) )
121+
<< " angledist " << fabsf( ori/M_PI2*360.0f - r.ori/M_PI2*360.0f );
122+
123+
if( dstr )
124+
{
125+
auto left = desc.begin();
126+
auto right = r.desc.begin();
127+
for( int i=0; i<128; i++, left++, right++ )
128+
{
129+
float diff = *left - *right;
130+
(*dstr) << diff << " ";
131+
desc_stats[i] += diff;
132+
}
133+
(*dstr) << endl;
134+
}
135+
}
136+
else if( *it > *m )
137+
{
138+
second = min<float>( second, *it );
139+
}
140+
it++;
141+
}
142+
else
143+
{
144+
ostr << "desc dist " << *it;
145+
if( it == m )
146+
ostr << " MIN ";
147+
else
148+
ostr << " ";
149+
it++;
150+
ostr << " pixdist " << sqrtf( (x-r.x)*(x-r.x) + (y-r.y)*(y-r.y) )
151+
<< " angledist " << fabsf( ori/M_PI2*360.0f - r.ori/M_PI2*360.0f )
152+
<< endl;
153+
}
154+
}
155+
if( minOnly )
156+
{
157+
ostr << " 2best " << second << endl;
158+
}
159+
}
160+
161+
float feat_t::dist( const feat_t& r ) const
162+
{
163+
if( _use_l2_distance )
164+
{
165+
float sum = 0.0f;
166+
auto it_r = r.desc.begin();
167+
for( auto l : desc )
168+
{
169+
float val = l - *it_r++;
170+
sum += ( val * val );
171+
}
172+
return sqrtf( sum );
173+
}
174+
else
175+
{
176+
float sum = 0.0f;
177+
auto it_r = r.desc.begin();
178+
for( auto l : desc )
179+
{
180+
float val = l - *it_r++;
181+
sum += fabsf( val );
182+
}
183+
return sum / 128;
184+
}
185+
}
186+
187+
void feat_t::setL2Distance( bool onoff )
188+
{
189+
_use_l2_distance = onoff;
190+
}
191+

0 commit comments

Comments
 (0)