-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathshowKeypoints.cpp
192 lines (163 loc) · 6.56 KB
/
showKeypoints.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
/* ============================================================================================
showKeypoints.cpp Version 3 04/07/2017 Arthur Koehl
this program:
[1] reads in parameters for surf detection, input image and output image from command line
if no options for surf specified will use those set in code in variable declaration
[2] uses opencv's Feature Detection class to detect all the keypoints
[3] filters the keypoints based on a sizemin and responsemin specified
[4] uses opencv's Circle function to draw all the keypoints over the image
[5] saves the image with drawn keypoints into file specified in step 1
mainly use this program to test parameters and to see the location and intensity of keypoints
============================================================================================ */
#include <iostream>
#include <fstream>
#include <cstdlib>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/nonfree/nonfree.hpp"
using namespace std;
using namespace cv;
int usage ();
void read_flags (int argc, char **argv, string *input, string *output, string *param, int *minh, int *octaves, int *layers, int *sizemin, double *responsemin);
void read_surfparams (string param, int *min, int *octaves, int *layers, int *sizemin, double *responsemin);
void filter_keypoints (vector <KeyPoint> &keypoints, int sizemin, double responsemin);
int main(int argc, char **argv)
{
/* =====================================================================================
if program executed without commands or '-h' or '-help' flag then run usage
===================================================================================== */
if (argc < 2)
return usage();
string checker = argv[1];
if (checker == "-h" || checker == "-help")
return usage();
/* =====================================================================================
variables for surf parameters, file names, image, and vector of keypoints
===================================================================================== */
int minh = 2000;
int octaves = 8;
int layers = 8;
int sizemin = 50;
double responsemin = 100;
string input, output;
string param = "";
vector <KeyPoint> keypoints;
Mat image;
Mat outimage;
/* =====================================================================================
parse command line into variables above and read in the image into Mat image
===================================================================================== */
read_flags(argc, argv, &input, &output, ¶m, &minh, &octaves, &layers, &sizemin, &responsemin);
if (param != "")
read_surfparams (param, &minh, &octaves, &layers, &sizemin, &responsemin);
image = imread (input);
/* =====================================================================================
create openCV's SurfFreatureDetector and then run detect() function
===================================================================================== */
SurfFeatureDetector detector (minh, octaves, layers);
detector.detect (image, keypoints);
int original = keypoints.size();
filter_keypoints (keypoints, sizemin, responsemin);
/* =====================================================================================
call drawkeypoints from opencv and write to the output image
===================================================================================== */
drawKeypoints (image, keypoints, outimage, Scalar (155,0,0), 4);
imwrite (output, outimage);
return 0;
}
int usage ()
{
cout << "./a.out -i input -o output -p paramfilepath " << endl;
cout << "otherwise, without param file:" << endl;
cout << "./a.out -i input -o output -h # -oct # -l # -s # -r #" << endl;
return -1;
}
void read_flags (int argc, char **argv, string *input, string *output, string *param, int *minh, int *octaves, int *layers, int *sizemin, double *responsemin)
{
string parser;
for (int i = 0; i < argc; i++)
{
parser = argv[i];
if (parser == "-i")
*input = argv[i + 1];
if (parser == "-o")
*output = argv[i+1];
if (parser == "-p")
*param = argv[i+1];
if (parser == "-h")
*minh = atoi(argv[i+1]);
if (parser == "-oct")
*octaves = atoi(argv[i+1]);
if (parser == "-l")
*layers = atoi(argv[i+1]);
if (parser == "-s")
*sizemin = atoi(argv[i+1]);
if (parser == "-r")
*responsemin = atoi(argv[i+1]);
}
}
/* ===============================================================================================
Procedure to read parameters for SURF from the parameter file
=============================================================================================== */
void read_surfparams(string param, int *minHessian, int *octaves, int *octaveLayers, int *SizeMin, double *RespMin)
{
ifstream inFile;
inFile.open(param.c_str());
string record;
stringstream ss;
while ( !inFile.eof () ) {
getline(inFile,record);
if (record.find("minHessian") != std::string::npos) {
ss<<record.substr(record.find_last_of(":") + 1);
ss>> *minHessian;
ss.str("");
ss.clear();
}
if (record.find("octaves") != std::string::npos) {
ss<<record.substr(record.find_last_of(":") + 1);
ss>> *octaves;
ss.str("");
ss.clear();
}
if (record.find("octaveLayers") != std::string::npos) {
ss<<record.substr(record.find_last_of(":") + 1);
ss>> *octaveLayers;
ss.str("");
ss.clear();
}
if (record.find("min Size") != std::string::npos) {
ss<<record.substr(record.find_last_of(":") + 1);
ss>> *SizeMin;
ss.str("");
ss.clear();
}
if (record.find("min Resp") != std::string::npos) {
ss<<record.substr(record.find_last_of(":") + 1);
ss>> *RespMin;
ss.str("");
ss.clear();
}
}
}
/* ===============================================================================================
Procedure to filter the keypoints from the keypoint vector by minimum size and response
=============================================================================================== */
void filter_keypoints (vector <KeyPoint> &keypoints, int sizemin, double responsemin)
{
vector <KeyPoint> temp;
int npoints = keypoints.size();
int size;
double response;
//filter based on size and response size
for (int i = 0; i < npoints; i++)
{
size = keypoints[i].size;
response = keypoints[i].response;
if (size > sizemin && response > responsemin)
temp.push_back(keypoints[i]);
}
keypoints.clear();
keypoints = temp;
return;
}