概述 Oxford5k
是常用的地标检索数据集,包含了5062
张图像,长宽为(1024, 768)
。该数据集来自于牛津大学11
个建筑物的不同视角,其中每个建筑物5
张查询图像,共55
张。
Paris6k
同样是VGG
组出品的地标检索数据集,包含了6412
张图像,长宽为(1024, 768)
。该数据集来自于Flickr ,收集了巴黎的12
个建筑物。
Oxford5k
和Paris6k
使用相同的标注方式、评估标准以及干扰集(共100K
来自于Flickr
)。
标注 存在4
个标签:
Good
- 拍摄的建筑物图像非常清晰无干扰(A nice, clear picture of the object/building
)OK
- 超过25%
的建筑物面积清晰可见(More than 25% of the object is clearly visible
)Bad
- 目标不存在(The object is not present
)Junk
- 少于25%
的建筑物面积可见,或者出现了高度的遮挡或变形(Less than 25% of the object is visible, or there are very high levels of occlusion or distortion
)。在评估计算中,会将Good
和OK
标签设置为GT
,将Junk
标签设置为负样本,忽略Bad
标签。
评估标准 Oxford5k/Paris6k
使用mAP
作为评估标准,并且提供了计算代码(单次查询的AP
计算):
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 #include <fstream> #include <iostream> #include <set> #include <string> #include <vector> #include <cstdlib> using namespace std ;vector <string >load_list(const string & fname) { vector <string > ret; ifstream fobj (fname.c_str()) ; if (!fobj.good()) { cerr << "File " << fname << " not found!\n" ; exit (-1 ); } string line; while (getline(fobj, line)) { ret.push_back(line); } return ret; } template <class T >set <T> vector_to_set (const vector <T>& vec) { return set <T>(vec.begin(), vec.end()); }float compute_ap(const set <string >& pos, const set <string >& amb, const vector <string >& ranked_list) { float old_recall = 0.0 ; float old_precision = 1.0 ; float ap = 0.0 ; size_t intersect_size = 0 ; size_t i = 0 ; size_t j = 0 ; for ( ; i<ranked_list.size(); ++i) { if (amb.count(ranked_list[i])) continue ; if (pos.count(ranked_list[i])) intersect_size++; float recall = intersect_size / (float )pos.size(); float precision = intersect_size / (j + 1.0 ); ap += (recall - old_recall)*((old_precision + precision)/2.0 ); old_recall = recall; old_precision = precision; j++; } return ap; } int main(int argc, char ** argv) { if (argc != 3 ) { cout << "Usage: ./compute_ap [GROUNDTRUTH QUERY] [RANKED LIST]\n" ; return -1 ; } string gtq = argv[1 ]; vector <string > ranked_list = load_list(argv[2 ]); set <string > good_set = vector_to_set( load_list(gtq + "_good.txt" ) ); set <string > ok_set = vector_to_set( load_list(gtq + "_ok.txt" ) ); set <string > junk_set = vector_to_set( load_list(gtq + "_junk.txt" ) ); set <string > pos_set; pos_set.insert(good_set.begin(), good_set.end()); pos_set.insert(ok_set.begin(), ok_set.end()); float ap = compute_ap(pos_set, junk_set, ranked_list); cout << ap << "\n" ; return 0 ; }
mAP
就是多次查询计算得到的AP
均值。
相关阅读