Repository navigation
Expand file tree
/
Copy pathtask2.cpp
More file actions
executable file
·298 lines (262 loc) · 9.28 KB
/
Copy pathtask2.cpp
File metadata and controls
executable file
·298 lines (262 loc) · 9.28 KB
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
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
#include <string>
#include <vector>
#include <fstream>
#include <cassert>
#include <iostream>
#include <cmath>
#include "classifier.h"
#include "EasyBMP.h"
#include "linear.h"
#include "argvparser.h"
#include "hist.h"
#include "HOG.h"
#include "HOGComputer.h"
#include "matrix.h"
using std::string;
using std::vector;
using std::ifstream;
using std::ofstream;
using std::pair;
using std::make_pair;
using std::cout;
using std::cerr;
using std::endl;
using std::make_tuple;
using CommandLineProcessing::ArgvParser;
typedef vector<pair<BMP*, int> > TDataSet;
typedef vector<pair<string, int> > TFileList;
typedef vector<pair<vector<float>, int> > TFeatures;
enum {
DIVIDESIZE = 4,
PYRAMIDSIZE = 2
};
#define L_step 0.32
#define EPS 0.0000001
// Load list of files and its labels from 'data_file' and
// stores it in 'file_list'
void LoadFileList(const string& data_file, TFileList* file_list) {
ifstream stream(data_file.c_str());
string filename;
int label;
int char_idx = data_file.size() - 1;
for (; char_idx >= 0; --char_idx)
if (data_file[char_idx] == '/' || data_file[char_idx] == '\\')
break;
string data_path = data_file.substr(0,char_idx+1);
while(!stream.eof() && !stream.fail()) {
stream >> filename >> label;
if (filename.size())
file_list->push_back(make_pair(data_path + filename, label));
}
stream.close();
}
// Load images by list of files 'file_list' and store them in 'data_set'
void LoadImages(const TFileList& file_list, TDataSet* data_set) {
for (size_t img_idx = 0; img_idx < file_list.size(); ++img_idx) {
// Create image
BMP* image = new BMP();
// Read image from file
image->ReadFromFile(file_list[img_idx].first.c_str());
// Add image and it's label to dataset
data_set->push_back(make_pair(image, file_list[img_idx].second));
}
}
// Save result of prediction to file
void SavePredictions(const TFileList& file_list,
const TLabels& labels,
const string& prediction_file) {
// Check that list of files and list of labels has equal size
assert(file_list.size() == labels.size());
// Open 'prediction_file' for writing
ofstream stream(prediction_file.c_str());
// Write file names and labels to stream
for (size_t image_idx = 0; image_idx < file_list.size(); ++image_idx)
stream << file_list[image_idx].first << " " << labels[image_idx] << endl;
stream.close();
}
// same function was in first task
/**
* @brief transform bmp to matrix
*/
Image load_image(BMP *in)
{
Image res(in->TellHeight(), in->TellWidth());
for (uint i = 0; i < res.n_rows; ++i) {
for (uint j = 0; j < res.n_cols; ++j) {
RGBApixel *p = (*in)(j, i);
res(i, j) = make_tuple(p->Red, p->Green, p->Blue);
}
}
return res;
}
float KFunc(float x){
return 1 / cosh (M_PI * x);
}
vector <float> &ModifyFeature(const vector<float> &v, vector<float> &ans){
for(auto i = v.begin(); i!= v.end(); i++){
float x = abs(*i);
for (int n = -2; n <= 2; n++){
float lambda = n * L_step;
if (x < EPS){
ans.push_back(0);
ans.push_back(0);
} else {
ans.push_back(sin(lambda * log(x)) * sqrt(x * KFunc(lambda)));
ans.push_back(cos(lambda * log(x)) * sqrt(x * KFunc(lambda)));
}
}
}
return ans;
}
vector<float> pyramid(const Image& im){
HOG hog(im);
vector <float> v(hog.ComputeHog(DIVIDESIZE));
uint sizex = im.n_rows / PYRAMIDSIZE;
uint sizey = im.n_cols / PYRAMIDSIZE;
for (int i = 0; i < PYRAMIDSIZE; i++){
for (int j = 0; j < PYRAMIDSIZE; j++){
auto tmp = im.submatrix(i * sizex, j * sizey, sizex, sizey);
HOG halfhog(tmp);
vector<float> appending(halfhog.ComputeHog(DIVIDESIZE));
v.insert(v.end(), appending.begin(), appending.end() );
}
}
return v;
}
// Exatract features from dataset.
// You should implement this function by yourself =)
void ExtractFeatures(const TDataSet& data_set, TFeatures* features) {
for (size_t image_idx = 0; image_idx < data_set.size(); ++image_idx) {
// PLACE YOUR CODE HERE
// Remove this sample code and place your feature extraction code here
int index;
BMP *bmp;
tie(bmp, index) = data_set[image_idx];
Image im = load_image(bmp);
vector<float> v = pyramid(im);
vector <float> nv (0,0);
ModifyFeature(v, nv);
features->push_back(make_pair(v, index));
}
}
// Clear dataset structure
void ClearDataset(TDataSet* data_set) {
// Delete all images from dataset
for (size_t image_idx = 0; image_idx < data_set->size(); ++image_idx)
delete (*data_set)[image_idx].first;
// Clear dataset
data_set->clear();
}
// Train SVM classifier using data from 'data_file' and save trained model
// to 'model_file'
void TrainClassifier(const string& data_file, const string& model_file) {
// List of image file names and its labels
TFileList file_list;
// Structure of images and its labels
TDataSet data_set;
// Structure of features of images and its labels
TFeatures features;
// Model which would be trained
TModel model;
// Parameters of classifier
TClassifierParams params;
// Load list of image file names and its labels
LoadFileList(data_file, &file_list);
// Load images
LoadImages(file_list, &data_set);
// Extract features from images
ExtractFeatures(data_set, &features);
// PLACE YOUR CODE HERE
// You can change parameters of classifier here
//params.C = 0.01;
TClassifier classifier(params);
// Train classifier
classifier.Train(features, &model);
// Save model to file
model.Save(model_file);
// Clear dataset structure
ClearDataset(&data_set);
}
// Predict data from 'data_file' using model from 'model_file' and
// save predictions to 'prediction_file'
void PredictData(const string& data_file,
const string& model_file,
const string& prediction_file) {
// List of image file names and its labels
TFileList file_list;
// Structure of images and its labels
TDataSet data_set;
// Structure of features of images and its labels
TFeatures features;
// List of image labels
TLabels labels;
// Load list of image file names and its labels
LoadFileList(data_file, &file_list);
// Load images
LoadImages(file_list, &data_set);
// Extract features from images
ExtractFeatures(data_set, &features);
// Classifier
TClassifier classifier = TClassifier(TClassifierParams());
// Trained model
TModel model;
// Load model from file
model.Load(model_file);
// Predict images by its features using 'model' and store predictions
// to 'labels'
classifier.Predict(features, model, &labels);
// Save predictions
SavePredictions(file_list, labels, prediction_file);
// Clear dataset structure
ClearDataset(&data_set);
}
int main(int argc, char** argv) {
// Command line options parser
ArgvParser cmd;
// Description of program
cmd.setIntroductoryDescription("Machine graphics course, task 2. CMC MSU, 2014.");
// Add help option
cmd.setHelpOption("h", "help", "Print this help message");
// Add other options
cmd.defineOption("data_set", "File with dataset",
ArgvParser::OptionRequiresValue | ArgvParser::OptionRequired);
cmd.defineOption("model", "Path to file to save or load model",
ArgvParser::OptionRequiresValue | ArgvParser::OptionRequired);
cmd.defineOption("predicted_labels", "Path to file to save prediction results",
ArgvParser::OptionRequiresValue);
cmd.defineOption("train", "Train classifier");
cmd.defineOption("predict", "Predict dataset");
// Add options aliases
cmd.defineOptionAlternative("data_set", "d");
cmd.defineOptionAlternative("model", "m");
cmd.defineOptionAlternative("predicted_labels", "l");
cmd.defineOptionAlternative("train", "t");
cmd.defineOptionAlternative("predict", "p");
// Parse options
int result = cmd.parse(argc, argv);
// Check for errors or help option
if (result) {
cout << cmd.parseErrorDescription(result) << endl;
return result;
}
// Get values
string data_file = cmd.optionValue("data_set");
string model_file = cmd.optionValue("model");
bool train = cmd.foundOption("train");
bool predict = cmd.foundOption("predict");
// If we need to train classifier
if (train)
TrainClassifier(data_file, model_file);
// If we need to predict data
if (predict) {
// You must declare file to save images
if (!cmd.foundOption("predicted_labels")) {
cerr << "Error! Option --predicted_labels not found!" << endl;
return 1;
}
// File to save predictions
string prediction_file = cmd.optionValue("predicted_labels");
// Predict data
PredictData(data_file, model_file, prediction_file);
}
}