1 //:
2 // \file
3 // \brief executable to match queries based on the existance of distinguishable objects
4 // \author Yi Dong
5 // \date June 04, 2013
6
7 #include <algorithm>
8 #include <boxm2/volm/desc/boxm2_volm_desc_ex_land_only_matcher.h>
9 #include <boxm2/volm/desc/boxm2_volm_desc_ex_matcher.h>
10 #include <iostream>
11 #include <utility>
12 #include <volm/desc/volm_desc_ex_2d_matcher.h>
13 #include <volm/volm_buffered_index.h>
14 #include <volm/volm_io.h>
15 #include <volm/volm_tile.h>
16 #include "vul/vul_arg.h"
17 #ifdef _MSC_VER
18 # include "vcl_msvc_warnings.h"
19 #endif
20
error_report(std::string error_file,const std::string & error_msg)21 void error_report(std::string error_file, const std::string& error_msg)
22 {
23 std::cerr << error_msg;
24 volm_io::write_post_processing_log(std::move(error_file), error_msg);
25 }
26
main(int argc,char ** argv)27 int main(int argc, char** argv)
28 {
29 // query input
30 vul_arg<std::string> query_xml("-xml", "tagged xml file for query image", "");
31 vul_arg<std::string> query_vsl("-vsl", "bwm gui vxl file for query image","");
32 vul_arg<std::string> weight_file("-weight", "weight parameter file", "");
33 vul_arg<std::string> world_str("-world", "world region","");
34 vul_arg<std::string> query_name("-query-name", "query name", "");
35 vul_arg<unsigned> tile_id("-tile", "tile id", 1000);
36 // index and geolocation
37 vul_arg<std::string> geo_hypo_folder("-geo", "folder where the geolocation for this tile is stored", "");
38 vul_arg<std::string> desc_index_folder("-index", "directory that contains the created wr3db indices", "");
39 vul_arg<std::string> out_folder("-out", "output folder for the query image", "");
40 vul_arg<float> buffer_capacity("-buff", "buffer size used for loading indices", 2.0f);
41 vul_arg<bool> is_land_only("-land", "option to execute matcher using ex_land_only descriptor", false);
42 vul_arg<bool> is_ex_2d("-ex2d", "option to execute 2D existence matcher", true);
43 // post processing related
44 vul_arg<float> kl("-kl", "parameter for nonlinear score scaling", 200.0f);
45 vul_arg<float> ku("-ku", "parameter for nonlinear score scaling", 10.0f);
46 vul_arg<float> threshold("-thres", "threshold ratio for generating prob map", 0.3f);
47 vul_arg<unsigned> thresc("-thresc", "threshold that used to create candidate list", 0);
48 vul_arg<unsigned> top_size("-top", "desired top list for each candidate list", 1);
49 // options
50 vul_arg<bool> is_matcher("-match", "option to execute the matcher", false);
51 vul_arg<bool> is_cand("-cand", "option to execute the candidate list generation", false);
52
53 vul_arg_parse(argc, argv);
54
55 // run the existence matcher and generate probability map
56 if (is_matcher())
57 {
58 // input check
59 if (geo_hypo_folder().compare("") == 0 || desc_index_folder().compare("") == 0 || out_folder().compare("") == 0)
60 {
61 std::cerr << "ERROR: arguments error, check the input" << std::endl;
62 vul_arg_display_usage_and_exit();
63 return volm_io::EXE_ARGUMENT_ERROR;
64 }
65 if (query_xml().compare("") == 0 && query_vsl().compare("") == 0)
66 {
67 std::cerr << "ERROR: no query tagged file, either tagging xml or vsl file required" << std::endl;
68 }
69 // error log
70 std::stringstream err_log;
71 std::stringstream err_log_file;
72 err_log_file << out_folder() << "/err_log.xml";
73 // load the query information
74 std::string world_region;
75 std::string query_name;
76 unsigned ni, nj;
77 std::vector<volm_weight> weights;
78 depth_map_scene_sptr dms = new depth_map_scene;
79
80 // load query
81 if (!vul_file::exists(query_xml())) { // load query from vxl file and weight from weight file
82 world_region = world_str();
83 vsl_b_ifstream dis(query_vsl().c_str());
84 dms->b_read(dis);
85 dis.close();
86 // obtain the query name from image file name
87 query_name = vul_file::strip_extension(vul_file::strip_directory(dms->image_path()));
88 // load the weight parameter, if file does not exist, use average weight
89 if (vul_file::exists(weight_file()) ) {
90 // read the weight parameter from pre-loaded
91 volm_weight::read_weight(weights, weight_file());
92 // check whether the loaded weight parameters satisfy the requirement, if not, create default equal weight parameters
93 if (!volm_weight::check_weight(weights)) {
94 weights.clear();
95 volm_weight::equal_weight(weights, dms);
96 }
97 }
98 else {
99 // create equal weight parameter for all objects
100 volm_weight::equal_weight(weights, dms);
101 }
102 // check self_consistency between dms and loaded weight parameters
103 if (!dms->ground_plane().empty()) {
104 bool has_grd = false;
105 for (auto & weight : weights)
106 if ( weight.w_typ_ == "ground_plane" || weight.w_typ_ == "ground" ) {
107 has_grd = true;
108 break;
109 }
110 if (!has_grd) {
111 err_log << " ERROR: inconsistency between depth_map_scene and weight parameter in ground plane\n";
112 error_report(err_log_file.str(), err_log.str());
113 return volm_io::EXE_ARGUMENT_ERROR;
114 }
115 }
116 if (weights.size() != (!dms->sky().empty() + !dms->ground_plane().empty() + dms->scene_regions().size())) {
117 std::cout << " weights_size = " << weights.size() << std::endl;
118 std::cout << " depth map scene size = " << !dms->sky().empty() + !dms->ground_plane().empty() + dms->scene_regions().size() << std::endl;
119 for (auto & weight : weights) {
120 std::cout << " \t\t" << weight.w_name_ << " " << weight.w_obj_ << std::endl;
121 }
122 err_log << " ERROR: number of weight parameters is different from labeled depth_map_region objects\n";
123 error_report(err_log_file.str(), err_log.str());
124 return volm_io::EXE_ARGUMENT_ERROR;
125 }
126 }
127 else {
128 if (!vul_file::exists(query_xml())) { // load query and weight from tagging xml file
129 err_log << "ERROR: can not find query tag xml file: " << query_xml() << '\n';
130 error_report(err_log_file.str(), err_log.str());
131 return volm_io::EXE_ARGUMENT_ERROR;
132 }
133 volm_io::read_query_tags(query_xml(), dms, weights, world_region, ni, nj, query_name);
134 // check weight parameter (Note during parser, all labeled object are parsed into scene_regions, i.e., no sky or ground_plane
135 if (weights.size() != dms->scene_regions().size()) {
136 err_log << "ERROR: number of weight parameters (" << weights.size() << ") is inconsistent with labeled object (" << dms->scene_regions().size() << ")\n";
137 error_report(err_log_file.str(), err_log.str());
138 return volm_io::EXE_ARGUMENT_ERROR;
139 }
140 }
141
142 std::string image_name = vul_file::strip_extension(query_name);
143
144 // create tiles based on world_region
145 std::vector<volm_tile> tiles;
146 if (world_region.compare("Chile")==0) tiles = volm_tile::generate_p1b_wr1_tiles();
147 else if (world_region.compare("India")==0) tiles = volm_tile::generate_p1b_wr2_tiles();
148 else if (world_region.compare("Jordan")==0) tiles = volm_tile::generate_p1b_wr3_tiles();
149 else if (world_region.compare("Philippines")==0) tiles = volm_tile::generate_p1b_wr4_tiles();
150 else if (world_region.compare("Taiwan")== 0) tiles = volm_tile::generate_p1b_wr5_tiles();
151 else if (world_region.compare("Coast")== 0) tiles = volm_tile::generate_p1_wr2_tiles();
152 else if (world_region.compare("Desert")== 0) tiles = volm_tile::generate_p1_wr1_tiles();
153 else {
154 err_log << "ERROR: unknown ROI region: " << world_region << ", check tag xml. Available regions are: Coast, Desert, Chile, India, Jordan, Philippines, Taiwan\n";
155 error_report(err_log_file.str(), err_log.str());
156 return volm_io::EXE_ARGUMENT_ERROR;
157 }
158 if (tile_id() >= tiles.size()) {
159 err_log << "ERROR: unknown tile id " << tile_id() << " for ROI region: " << world_region << "!\n";
160 error_report(err_log_file.str(), err_log.str());
161 return volm_io::EXE_ARGUMENT_ERROR;
162 }
163
164 // create ex_matcher
165 std::stringstream params_file_pre;
166 params_file_pre << desc_index_folder() << "/desc_index_tile_" << tile_id();
167 //std::string params_file_pre = desc_index_folder() + "/desc_index_tile_0";
168 volm_buffered_index_params params;
169 if (!params.read_ex_param_file(params_file_pre.str())) {
170 err_log << " ERROR: fetching parameter failed from file: " << params_file_pre.str() << ".params\n";
171 error_report(err_log_file.str(), err_log.str());
172 return volm_io::EXE_ARGUMENT_ERROR;
173 }
174 volm_desc_matcher_sptr ex_matcher;
175 if (is_land_only()) {
176 ex_matcher = new boxm2_volm_desc_ex_land_only_matcher(dms, params.radius, params.nlands, 0);
177 }
178 else if (is_ex_2d()) {
179 ex_matcher = new volm_desc_ex_2d_matcher(dms, weights, params.radius, params.nlands, 0);
180 }
181 else {
182 ex_matcher = new boxm2_volm_desc_ex_matcher(dms, params.radius, params.norients, params.nlands, 0);
183 }
184
185 // create query
186 volm_desc_sptr query = ex_matcher->create_query_desc();
187 std::string query_file = out_folder() + "/query_annotation.svg";
188 query->visualize(query_file, 2);
189
190 // Screen output
191 std::cout << " =========== Start to execute existence matcher for image: " << image_name << " ===============" << std::endl;
192 std::cout << " \t Descriptor type : " << ex_matcher->get_index_type_str() << std::endl;
193 std::cout << " \t world region: " << world_region << std::endl;
194 std::cout << " \t weight parameters: " << std::endl;
195 for (auto & weight : weights) {
196 std::cout << " \t\t" << weight.w_name_ << " " << weight.w_obj_ << std::endl;
197 }
198 std::cout << " \t query " << query_name << " has following objects " << std::endl;
199 std::vector<depth_map_region_sptr> obj = dms->scene_regions();
200 for (unsigned i = 0; i < obj.size(); i++)
201 std::cout << " \t\t" << obj[i]->name() << " --- mindist = " << obj[i]->min_depth() << ", maxdist = " << obj[i]->max_depth()
202 << ", land = " << volm_osm_category_io::volm_land_table[obj[i]->land_id()].name_
203 << ", weight = " << weights[i].w_obj_ << std::endl;
204 std::cout << " \t query descriptor:\n";
205 query->print();
206 std::cout << std::endl;
207
208 // start the matcher
209 for (unsigned t_id = 0; t_id < tiles.size(); t_id++)
210 {
211 if (t_id != tile_id())
212 continue;
213 std::cout << " matcher on tile " << t_id << " in " << tiles.size() << " tiles...\n";
214 std::cout << std::flush;
215 // run matcher
216 if (!ex_matcher->matcher(query, geo_hypo_folder(), desc_index_folder(), buffer_capacity(), t_id)) {
217 err_log << "ERROR: matcher on tile " << t_id << " failed\n";
218 error_report(err_log_file.str(), err_log.str());
219 return volm_io::EXE_MATCHER_FAILED;
220 }
221 // save score binary
222 if (!ex_matcher->write_out(out_folder(), t_id)) {
223 err_log << "ERROR: matcher on tile " << t_id << " failed (can not save score binary)\n";
224 error_report(err_log_file.str(), err_log.str());
225 return volm_io::EXE_MATCHER_FAILED;
226 }
227 // create probability map
228 float gt_score = -1.0f;
229 vgl_point_3d<double> gt_loc(0.0,0.0,0.0);
230 if (!ex_matcher->create_prob_map(geo_hypo_folder(), out_folder(), t_id, tiles[t_id], gt_loc, gt_score)) {
231 err_log << " ERROR: creating probability map for tile " << t_id << " failed\n";
232 error_report(err_log_file.str(), err_log.str());
233 return volm_io::POST_PROCESS_FAILED;
234 }
235 // create scaled probability map
236 float thres_value = threshold();
237 std::cout << " \t threshold used for scaling probability maps: " << thres_value << std::endl;
238 if (!volm_desc_matcher::create_scaled_prob_map(out_folder(), tiles[t_id], t_id, ku(), kl(), thres_value)) {
239 err_log << "ERROR: create scaled probability map for tile " << t_id << " failed\n";
240 error_report(err_log_file.str(), err_log.str());
241 return volm_io::POST_PROCESS_FAILED;
242 }
243 }
244 std::cout << " ========================================== Finish ===============================================" << std::endl;
245 }
246 // generate candidate list once we have the scaled_probability map
247 if (is_cand())
248 {
249 if (out_folder().compare("") == 0) {
250 std::cerr << "ERROR: output folder and probability map folder can not be empty when creating candidate list. Check input" << std::endl;
251 vul_arg_display_usage_and_exit();
252 return volm_io::EXE_ARGUMENT_ERROR;
253 }
254 std::stringstream log;
255 std::stringstream log_file;
256 log_file << out_folder() << "/error_log_candidate_list.xml";
257 std::cout << " ============== Start to create candidate list ==================" << std::endl;
258 std::stringstream cand_folder;
259 cand_folder << out_folder() << "/T_" << thresc();
260 if (!vul_file::is_directory(cand_folder.str()))
261 vul_file::make_directory(cand_folder.str());
262 std::cout << "\t threshold: " << thresc() << std::endl;
263 std::cout << "\t probability maps are stored in: " << out_folder() << std::endl;
264 std::cout << "\t result stored in: " << cand_folder.str() << std::endl;
265 if (!volm_desc_matcher::create_candidate_list(out_folder(), cand_folder.str(), thresc(), top_size(), ku(), kl(), threshold(), query_name(), world_str())) {
266 //log << " creating candidate list failed at threshold " << thresc() << '\n';
267 //error_report(log_file.str(), log.str());
268 return volm_io::EXE_ARGUMENT_ERROR;
269 }
270 std::cout << " =========================== Finish =============================" << std::endl;
271 return volm_io::SUCCESS;
272 }
273
274 return volm_io::SUCCESS;
275 }
276 #if 0
277 int main(int argc, char** argv)
278 {
279 // query input
280 vul_arg<std::string> depth_scene("-dms", "depth map scene file", "");
281 vul_arg<std::string> weight_file("-weight", "weight parameter file", "");
282 // index and geolocation
283 vul_arg<unsigned> world_id("-world", "world id to specify the ROI region", 100);
284 vul_arg<unsigned> tile_id("-tile", "tile id to specify which tile are being matched", 100);
285 vul_arg<std::string> geo_hypo_folder("-geo", "folder where the geolocation for this tile is stored", "");
286 vul_arg<std::string> desc_index_folder("-index", "directory that contains the created wr3db indices", "");
287 vul_arg<std::string> out_folder("-out", "output folder for the query image", "");
288 vul_arg<float> buffer_capacity("-buff", "buffer size used for loading indices", 2.0f);
289 vul_arg<bool> is_land_only("-land", "option to execute matcher using ex_land_only descriptor", false);
290 vul_arg<bool> is_ex_2d("-ex2d", "option to execute 2D existence matcher", true);
291 // post processing related
292 vul_arg<std::string> gt_file("-gt", "ground truth files", "");
293 vul_arg<float> kl("-kl", "parameter for nonlinear score scaling", 200.0f);
294 vul_arg<float> ku("-ku", "parameter for nonlinear score scaling", 10.0f);
295 vul_arg<float> threshold("-thres", "threshold ratio for generating prob map", 0.3);
296 vul_arg<unsigned> test_id("-testid", "phase 1 test id", 1);
297 vul_arg<unsigned> id("-imgid", "query image id", 21);
298 vul_arg<unsigned> thresc("-thresc", "threshold that used to create candidate list", 0);
299 vul_arg<unsigned> top_size("-top", "desired top list for each candidate list", 1);
300 // options
301 vul_arg<bool> is_matcher("-match", "option to execute the matcher", false);
302 vul_arg<bool> is_cand("-cand", "option to execute the candidate list generation", false);
303
304 vul_arg_parse(argc, argv);
305
306 std::stringstream image_name;
307 if (id() < 10)
308 image_name << "p1b_test" << test_id() << "_00" << id();
309 else if (id() >= 10 && id() < 100)
310 image_name << "p1b_test" << test_id() << "_0" << id();
311 else
312 image_name << "p1b_test" << test_id() << "_" << id();
313 // run the existence matcher and generate probability map
314 if (is_matcher()) {
315 // check the argument
316 if (depth_scene().compare("") == 0 || geo_hypo_folder().compare("") == 0 || weight_file().compare("") == 0 ||
317 desc_index_folder().compare("") == 0 || out_folder().compare("") == 0 ||
318 gt_file().compare("") == 0 || id() > 200 || test_id() == 0 || tile_id() == 100 || world_id() == 100)
319 {
320 std::cerr << " ERROR: arguments error, check the input " << std::endl;
321 vul_arg_display_usage_and_exit();
322 return volm_io::EXE_ARGUMENT_ERROR;
323 }
324
325 // error log
326 std::stringstream err_log;
327 std::stringstream err_log_file;
328 err_log_file << out_folder() << "/err_log_tile_" << tile_id() << ".xml";
329
330
331 // load the depth map scene
332 if (!vul_file::exists(depth_scene())) {
333 err_log << " ERROR: can not find depth map scene file" << depth_scene() << '\n';
334 std::cerr << err_log;
335 volm_io::write_post_processing_log(err_log_file.str(), err_log.str());
336 return volm_io::EXE_ARGUMENT_ERROR;
337 }
338 depth_map_scene_sptr dms = new depth_map_scene;
339 vsl_b_ifstream dis(depth_scene().c_str());
340 dms->b_read(dis);
341 dis.close();
342
343 // load the weight parameter, if file does not exist, use average weight
344 std::vector<volm_weight> weights;
345 if (vul_file::exists(weight_file()) ) {
346 // read the weight parameter from pre-loaded
347 volm_weight::read_weight(weights, weight_file());
348 // check whether the loaded weight parameters satisfy the requirement, if not, create default equal weight parameters
349 if (!volm_weight::check_weight(weights)) {
350 weights.clear();
351 volm_weight::equal_weight(weights, dms);
352 }
353 }
354 else {
355 // create equal weight parameter for all objects
356 volm_weight::equal_weight(weights, dms);
357 }
358
359 // check self_consistency between dms and loaded weight parameters
360 if (!dms->ground_plane().empty()) {
361 bool has_grd = false;
362 for (std::vector<volm_weight>::iterator wit = weights.begin(); wit != weights.end(); ++wit)
363 if ( (*wit).w_typ_ == "ground_plane" ) {
364 has_grd = true;
365 break;
366 }
367 if (!has_grd) {
368 err_log << " ERROR: inconsistency between depth_map_scene and weight parameter in ground plane\n";
369 error_report(err_log_file.str(), err_log.str());
370 return volm_io::EXE_ARGUMENT_ERROR;
371 }
372 }
373 if (weights.size() != (!dms->sky().empty() + !dms->ground_plane().empty() + dms->scene_regions().size())) {
374 std::cout << " weights_size = " << weights.size() << std::endl;
375 std::cout << " depth map scene size = " << !dms->sky().empty() + !dms->ground_plane().empty() + dms->scene_regions().size() << std::endl;
376 for (unsigned i = 0; i < weights.size(); i++) {
377 std::cout << " \t\t" << weights[i].w_name_ << " " << weights[i].w_obj_ << std::endl;
378 }
379 err_log << " ERROR: number of weight parameters is different from labeled depth_map_region objects\n";
380 error_report(err_log_file.str(), err_log.str());
381 return volm_io::EXE_ARGUMENT_ERROR;
382 }
383
384 // fetch the ground truth location
385 if (!vul_file::exists(gt_file())) {
386 err_log << " ERROR: can not find ground truth file" << gt_file() << '\n';
387 error_report(err_log_file.str(), err_log.str());
388 return volm_io::EXE_ARGUMENT_ERROR;
389 }
390 std::vector<std::pair<vgl_point_3d<double>, std::pair<std::pair<std::string, int>, std::string> > > samples;
391 unsigned int cnt = volm_io::read_gt_file(gt_file(), samples);
392
393 int img_info_id = -1;
394 for (unsigned kk = 0; kk < samples.size(); kk++) {
395 if (samples[kk].second.first.second == id()) {
396 img_info_id = kk;
397 break;
398 }
399 }
400 //if (query_img_info.size() <= img_id()) {
401 if (img_info_id < 0) {
402 std::cerr << "query image id: " << id() << " cannot be found in the gt loc file: " << gt_file() << "!\n";
403 return volm_io::EXE_ARGUMENT_ERROR;
404 }
405
406 vgl_point_3d<double> gt_loc;
407 gt_loc = samples[img_info_id].first;
408
409 //// create coast tiles
410 //std::vector<volm_tile> tiles = volm_tile::generate_p1_wr2_tiles();
411 std::vector<volm_tile> tiles;
412 if (world_id() == 1) tiles = volm_tile::generate_p1b_wr1_tiles();
413 else if (world_id() == 2) tiles = volm_tile::generate_p1b_wr2_tiles();
414 else if (world_id() == 3) tiles = volm_tile::generate_p1b_wr3_tiles();
415 else if (world_id() == 4) tiles = volm_tile::generate_p1b_wr4_tiles();
416 else if (world_id() == 5) tiles = volm_tile::generate_p1b_wr5_tiles();
417 else {
418 err_log << " ERROR: unknown world id: " << world_id() << " (only 1 to 5 allowed) " << std::endl;
419 error_report(err_log_file.str(), err_log.str());
420 return volm_io::EXE_ARGUMENT_ERROR;
421 }
422
423 // create ex_matcher
424 std::string params_file_pre = desc_index_folder() + "/desc_index_tile_0";
425 volm_buffered_index_params params;
426 if (!params.read_ex_param_file(params_file_pre)) {
427 err_log << " ERROR: fetching parameter failed from file: " << params_file_pre << ".params\n";
428 error_report(err_log_file.str(), err_log.str());
429 return volm_io::EXE_ARGUMENT_ERROR;
430 }
431
432 volm_desc_matcher_sptr ex_matcher;
433 if (is_land_only()) {
434 ex_matcher = new boxm2_volm_desc_ex_land_only_matcher(dms, params.radius, params.nlands, 0);
435 }
436 else if (is_ex_2d()) {
437 ex_matcher = new volm_desc_ex_2d_matcher(dms, weights, params.radius, params.nlands, 0);
438 }
439 else {
440 ex_matcher = new boxm2_volm_desc_ex_matcher(dms, params.radius, params.norients, params.nlands, 0);
441 }
442
443 std::cout << " ex_matcher is " << ex_matcher->get_index_type_str() << std::endl;
444
445 // create query
446 volm_desc_sptr query = ex_matcher->create_query_desc();
447 std::string query_file = out_folder() + "/" + "query_annotation.svg";
448 query->visualize(query_file, 2);
449
450 std::cout << " query = ";
451 query->print();
452 std::cout << std::endl;
453
454 // start the matcher
455 std::cout << " =========== Start to execute existence matcher on tile " << tile_id() << " for image: " << image_name.str() << " ===============" << std::endl;
456 std::cout << " \t Descriptor type : " << ex_matcher->get_index_type_str() << std::endl;
457 std::cout << " \t weight parameters: " << std::endl;
458 for (unsigned i = 0; i < weights.size(); i++) {
459 std::cout << " \t\t" << weights[i].w_name_ << " " << weights[i].w_obj_ << std::endl;
460 }
461 if (tile_id() != 10) {
462 if (!ex_matcher->matcher(query, geo_hypo_folder(), desc_index_folder(), buffer_capacity(), tile_id())) {
463 err_log << " ERROR: matcher for tile " << tile_id() << " failed\n";
464 error_report(err_log_file.str(), err_log.str());
465 return volm_io::EXE_ARGUMENT_ERROR;
466 }
467 // save the score binary
468 if (!ex_matcher->write_out(out_folder(), tile_id())) {
469 err_log << " ERROR: save the score binary file for tile " << tile_id() << " failed\n";
470 error_report(err_log_file.str(), err_log.str());
471 return volm_io::EXE_ARGUMENT_ERROR;
472 }
473 }
474 // create probability map
475 float gt_score = -1.0f;
476 if (!ex_matcher->create_prob_map(geo_hypo_folder(), out_folder(), tile_id(), tiles[tile_id()], gt_loc, gt_score)) {
477 err_log << " ERROR: creating probability map for tile " << tile_id() << " failed\n";
478 error_report(err_log_file.str(), err_log.str());
479 return volm_io::POST_PROCESS_FAILED;
480 }
481 if (gt_score != -1.0f) {
482 // record the ground score
483 std::stringstream gt_log;
484 std::string gt_log_file = out_folder() + "/gt_score.xml";
485 gt_log << " closest geolocation relative to ground truth [" << gt_loc.x() << ", " << gt_loc.y()
486 << "] is in tile " << tile_id() << ", having score = " << gt_score << '\n';
487 volm_io::write_post_processing_log(gt_log_file, gt_log.str());
488 }
489 std::cout << "\t geo hypothesis folder: " << geo_hypo_folder() << std::endl;
490 std::cout << "\t existence index folder: " << desc_index_folder() << std::endl;
491 std::cout << "\t query image has " << query->get_area() << " bins" << std::endl;
492
493 if (gt_score != -1.0f)
494 std::cout << "\t ground truth location is in tile " << tile_id() << " with score = " << gt_score << std::endl;
495
496 // create scaled probability map
497 float thres_value = threshold();
498 //ex_matcher->check_threshold(query, thres_value);
499 if (thres_value != threshold())
500 std::cout << "\t NOTE: the threshold given has changed from " << threshold() << " to " << thres_value << std::endl;
501 std::cout << "\t threshold used for scaling probability maps: " << thres_value << std::endl;
502 if (!volm_desc_matcher::create_scaled_prob_map(out_folder(), tiles[tile_id()], tile_id(), ku(), kl(), thres_value)) {
503 err_log << " ERROR: creating scaled probability map for tile " << tile_id() << " failed\n";
504 error_report(err_log_file.str(), err_log.str());
505 return volm_io::POST_PROCESS_FAILED;
506 }
507 std::cout << " ========================================== Finish ===============================================" << std::endl;
508 }
509 // generate candidate list once we have the scaled_probability_map
510 if (is_cand()) {
511 if (out_folder().compare("") == 0) {
512 std::cerr << " ERROR: output folder and probability map folder can not be empty when creating candidate list. Check input" << std::endl;
513 vul_arg_display_usage_and_exit();
514 return volm_io::EXE_ARGUMENT_ERROR;
515 }
516 std::stringstream log;
517 std::stringstream log_file;
518 log_file << out_folder() << "/error_log_candidate_list.xml";
519
520 std::cout << " =========== Start to create candidate list for image: " << image_name.str() << " ===============" << std::endl;
521 std::stringstream prob_map_folder;
522 prob_map_folder << out_folder() << "/ProbMap_scaled_" << threshold();
523
524 if (!vul_file::exists(prob_map_folder.str())) {
525 log << " can not find the directory for probability map: " << prob_map_folder.str() << '\n';
526 error_report(log_file.str(), log.str());
527 return volm_io::EXE_ARGUMENT_ERROR;
528 }
529
530 std::stringstream cand_folder;
531 cand_folder << out_folder() << "/T_" << thresc() ;
532 if( !vul_file::is_directory(cand_folder.str()))
533 vul_file::make_directory(cand_folder.str());
534
535 std::cout << "\t threshold: " << thresc() << std::endl;
536 std::cout << "\t threshold used for the probability maps: " << threshold() << std::endl;
537 std::cout << "\t probability maps are stored in: " << prob_map_folder.str() << std::endl;
538 std::cout << "\t result stored in: " << cand_folder.str() << std::endl;
539 if (!volm_desc_matcher::create_candidate_list(prob_map_folder.str(), cand_folder.str(), thresc(), top_size(), ku(), kl(), threshold(), test_id(), id(), world_id())) {
540 log << " creating candidate list failed for image " << id() << " at threshold " << thresc() << '\n';
541 error_report(log_file.str(), log.str());
542 std::cout << " ========================================== Failed ========================================" << std::endl;
543 return volm_io::EXE_ARGUMENT_ERROR;
544 }
545 std::cout << " ========================================== Finish ========================================" << std::endl;
546 return volm_io::SUCCESS;
547 }
548
549 return volm_io::SUCCESS;
550 }
551 #endif
552