Skip to content

Commit fdfb05f

Browse files
committed
more flexible config
1 parent ab70d39 commit fdfb05f

File tree

2 files changed

+73
-44
lines changed

2 files changed

+73
-44
lines changed

readme.md

Lines changed: 42 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -13,54 +13,58 @@ A Python-based salient object detection and video object segmentation evaluation
1313
## 重要提示
1414

1515
- 2021年03月21日
16-
- 正式删除需要个人定制的评估文件,这部分直接会放到本仓库的Readme中的[Examples](#Examples)中,仅供参考。
17-
- 将格式化输出功能调整,直接使用包`tabulate`处理,更加方便,输出的格式配置更丰富,详见<https://github.com/astanin/python-tabulate>
18-
- 调整原来`cal_sod_matrics``skipped_datasets``get_datasets_info``specific_datasets``drawing_info``specific_methods`
16+
- 正式删除需要个人定制的评估文件,这部分直接会放到本仓库的Readme中的[Examples](#Examples)中,仅供参考。
17+
- 将格式化输出功能调整,直接使用包`tabulate`处理,更加方便,输出的格式配置更丰富,详见<https://github.com/astanin/python-tabulate>
18+
- 调整原来`cal_sod_matrics``skipped_datasets`为:
19+
- `get_datasets_info``exclude_datasets/include_datasets`
20+
- `get_methods_info``exclude_methods/include_methods`
1921
- 2021年03月14日
20-
- 这一版本将数据集和方法的配置方法转换为基于json文件的配置。
21-
- 一些配套的更改与简化。
22+
- 这一版本将数据集和方法的配置方法转换为基于json文件的配置。
23+
- 一些配套的更改与简化。
2224
- 2021年03月12日
23-
- 这一版本正式将sod的评估、绘图代码与配置分离,主要考虑如下
24-
- 用户的配置是需要调整的,这部分不适宜被git严格的监视,也便于提交后续更新的时候,直接忽略关于配置的更改,即后续更新时,
25-
用户配置部分会不再更新,若是添加新功能,直接调整原始的函数,其参数默认关闭新功能,保证用户不会受到影响。
26-
- sod和cosod评估方式有差异,但是绘图方式一致,所以现将评估绘图拆分成独立部分,置于metrics/sod文件夹下,之后或许或调整位置,
27-
但这种拆分策略不变。
28-
- 优化了cosod的评估代码,对sod和cosod的指标recorder部分进行了简化。
29-
- 不再使用独立的sod_metrics代码,由于我已经将PySODMetrics发布到了PyPI上,所以可以直接通过pip安装。
30-
- 使用添加了对于print的一个彩色增强的封装,可见`./utils/misc.py`中的`colored_print`
31-
- git不再跟踪方法配置文件和数据集配置文件,这部分现有的作为示例,仅供使用者独立补充和参考。
32-
- 修复了之前绘制Fm曲线时x的问题,之前取反了。详见<https://github.com/lartpang/Py-SOD-VOS-EvalToolkit/issues/2>
25+
- 这一版本正式将sod的评估、绘图代码与配置分离,主要考虑如下
26+
- 用户的配置是需要调整的,这部分不适宜被git严格的监视,也便于提交后续更新的时候,直接忽略关于配置的更改,即后续更新时,
27+
用户配置部分会不再更新,若是添加新功能,直接调整原始的函数,其参数默认关闭新功能,保证用户不会受到影响。
28+
- sod和cosod评估方式有差异,但是绘图方式一致,所以现将评估绘图拆分成独立部分,置于metrics/sod文件夹下,之后或许或调整位置, 但这种拆分策略不变。
29+
- 优化了cosod的评估代码,对sod和cosod的指标recorder部分进行了简化。
30+
- 不再使用独立的sod_metrics代码,由于我已经将PySODMetrics发布到了PyPI上,所以可以直接通过pip安装。
31+
- 使用添加了对于print的一个彩色增强的封装,可见`./utils/misc.py`中的`colored_print`
32+
- git不再跟踪方法配置文件和数据集配置文件,这部分现有的作为示例,仅供使用者独立补充和参考。
33+
- 修复了之前绘制Fm曲线时x的问题,之前取反了。详见<https://github.com/lartpang/Py-SOD-VOS-EvalToolkit/issues/2>
3334

3435
## 特性
3536

3637
* 提供11项显著性目标检测指标的评估
37-
- F-measure-Threshold Curve
38-
- Precision-Recall Curve
39-
- MAE
40-
- weighted F-measure
41-
- S-measure
42-
- max/mean/adaptive F-measure
43-
- max/mean/adaptive E-measure
38+
- F-measure-Threshold Curve
39+
- Precision-Recall Curve
40+
- MAE
41+
- weighted F-measure
42+
- S-measure
43+
- max/mean/adaptive F-measure
44+
- max/mean/adaptive E-measure
4445
* 测试代码高度优化
45-
- 纯python实现,基于numpy和各种小trick计算各项指标,速度有保障
46-
- 导出特定模型的结果到xlsx文件中(2021年01月04日重新提供支持)
47-
- 导出测试结果到txt文件中
48-
- 评估所有指定的方法,根据评估结果绘制PR曲线和F-measure曲线
46+
- 纯python实现,基于numpy和各种小trick计算各项指标,速度有保障
47+
- 导出特定模型的结果到xlsx文件中(2021年01月04日重新提供支持)
48+
- 导出测试结果到txt文件中
49+
- 评估所有指定的方法,根据评估结果绘制PR曲线和F-measure曲线
4950
* 针对**DAVIS 2016无监督视频目标分割**任务,提供`"J(M)", "J(O)", "J(D)", "F(M)", "F(O)", "F(D)"`等指标的评估(代码借鉴自davis官方的代码,建议使用前验证下)
50-
- 导出对指定的模型预测结果的评估结果
51-
- 表格化展示不同视频上模型预测的性能
51+
- 导出对指定的模型预测结果的评估结果
52+
- 表格化展示不同视频上模型预测的性能
5253

5354
## 使用方法
5455

5556
### General/Co-RGB/RGBD-SOD
5657

57-
由于对于数据集和方法的配置因用户而异,所以在<https://github.com/lartpang/Py-SOD-VOS-EvalToolkit/commit/d7bcc1d74065844fe0483dc3ce3fda7d06d07bc0>之后的版本不在更新`configs`文件夹中的这部分内容,直接给出一个简单的例子,用户可以自行修改。
58+
由于对于数据集和方法的配置因用户而异,所以在<https://github.com/lartpang/Py-SOD-VOS-EvalToolkit/commit/d7bcc1d74065844fe0483dc3ce3fda7d06d07bc0>
59+
之后的版本不在更新`configs`文件夹中的这部分内容,直接给出一个简单的例子,用户可以自行修改。
5860
例子可以参考之前的版本,例如:<https://github.com/lartpang/Py-SOD-VOS-EvalToolkit/tree/f9c1fd5ffeef1a58067e31b9e6d28e9eb0754c46/configs>
5961

6062
先安装指标代码库:
6163

6264
```python
63-
pip install pysodmetrics
65+
pip
66+
install
67+
pysodmetrics
6468
```
6569

6670
可见各自文件中的配置项。
@@ -126,7 +130,6 @@ pip install pysodmetrics
126130
}
127131
```
128132

129-
130133
## Examples
131134

132135
<details>
@@ -236,6 +239,7 @@ draw_curves(
236239
dataset_info=dataset_info,
237240
)
238241
```
242+
239243
</details>
240244

241245
<details>
@@ -287,14 +291,14 @@ output_path = "./output"
287291
# 包含所有数据集信息的字典
288292
dataset_info = get_datasets_info(
289293
datastes_info_json=data_info["dataset"],
290-
specific_datasets=["STERE797"],
294+
exclude_datasets=["STEREO797"],
291295
)
292296
# 包含所有待比较模型结果的信息和绘图配置的字典
293297
drawing_info = get_methods_info(
294298
methods_info_json=data_info["method"],
295299
for_drawing=for_drawing,
296300
our_name="",
297-
specific_methods=["UCNet_ABP", "UCNet_CVAE"],
301+
exclude_methods=["UCNet_ABP", "UCNet_CVAE"],
298302
)
299303

300304
# 用来保存测试结果的文件的路径
@@ -363,6 +367,7 @@ if for_drawing:
363367
dataset_info=dataset_info,
364368
)
365369
```
370+
366371
</details>
367372

368373
<details>
@@ -579,6 +584,7 @@ if __name__ == "__main__":
579584
dataset_info=dataset_info,
580585
)
581586
```
587+
582588
</details>
583589

584590
<details>
@@ -710,6 +716,7 @@ if __name__ == "__main__":
710716
skipped_names = [] # 可以跳过指定的数据集
711717
cal_all_metrics()
712718
```
719+
713720
</details>
714721

715722
<details>
@@ -833,7 +840,7 @@ def get_mean_recall_decay_for_video(per_frame_values):
833840
ids = np.round(np.linspace(1, len(per_frame_values), N_bins + 1) + 1e-10) - 1
834841
ids = ids.astype(np.uint8)
835842

836-
D_bins = [per_frame_values[ids[i] : ids[i + 1] + 1] for i in range(0, 4)]
843+
D_bins = [per_frame_values[ids[i]: ids[i + 1] + 1] for i in range(0, 4)]
837844

838845
with warnings.catch_warnings():
839846
warnings.simplefilter("ignore", category=RuntimeWarning)
@@ -1068,4 +1075,5 @@ if __name__ == "__main__":
10681075
# show_results_from_data_file("./output/HDFNet_WSGNR50_V1.pkl")
10691076
# show_results_from_data_file("./output/matnet_ave.pkl")
10701077
```
1078+
10711079
</details>

utils/generate_info.py

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -58,27 +58,35 @@ def get_methods_info(
5858
methods_info_json: str,
5959
for_drawing: bool = False,
6060
our_name: str = "Ours",
61-
specific_methods: list = None,
61+
include_methods: list = None,
62+
exclude_methods: list = None,
6263
) -> OrderedDict:
6364
"""
6465
在json文件中存储的对应方法的字典的键值会被直接用于绘图
6566
6667
:param methods_info_json: 保存方法信息的json文件
6768
:param for_drawing: 是否用于绘制曲线图,True会补充一些绘图信息
6869
:param our_name: 在绘图时,可以通过指定our_name来使用红色加粗实线强调特定方法的曲线
69-
:param specific_methods: 仅返回列表中指定的方法的信息,为None时,返回所有
70+
:param include_methods: 仅返回列表中指定的方法的信息,为None时,返回所有
71+
:param exclude_methods: 仅返回列表中指定的方法的信息,为None时,返回所有,与include_datasets必须仅有一个非None
7072
:return: methods_full_info
7173
"""
7274

7375
assert os.path.exists(methods_info_json) and os.path.isfile(
7476
methods_info_json
7577
), methods_info_json
78+
if include_methods and exclude_methods:
79+
raise ValueError("include_methods、exclude_methods 不可以同时非None")
7680

7781
with open(methods_info_json, encoding="utf-8", mode="r") as f:
7882
methods_info = json.load(f, object_pairs_hook=OrderedDict) # 有序载入
7983

80-
if specific_methods:
81-
for method_name in specific_methods:
84+
if include_methods:
85+
for method_name in include_methods:
86+
if method_name not in methods_info:
87+
raise ValueError(f"The info of {method_name} is not in the methods_info_json.")
88+
if exclude_methods:
89+
for method_name in exclude_methods:
8290
if method_name not in methods_info:
8391
raise ValueError(f"The info of {method_name} is not in the methods_info_json.")
8492

@@ -92,7 +100,9 @@ def get_methods_info(
92100

93101
methods_full_info = []
94102
for method_name, method_path in methods_info.items():
95-
if specific_methods and (method_name not in specific_methods):
103+
if include_methods and (method_name not in include_methods):
104+
continue
105+
if exclude_methods and (method_name in exclude_methods):
96106
continue
97107

98108
if for_drawing and our_name and our_name == method_name:
@@ -103,30 +113,41 @@ def get_methods_info(
103113
return OrderedDict(methods_full_info)
104114

105115

106-
def get_datasets_info(datastes_info_json: str, specific_datasets: list = None) -> OrderedDict:
116+
def get_datasets_info(
117+
datastes_info_json: str, include_datasets: list = None, exclude_datasets: list = None
118+
) -> OrderedDict:
107119
"""
108120
在json文件中存储的所有数据集的信息会被直接导出到一个字典中
109121
110122
:param datastes_info_json: 保存方法信息的json文件
111-
:param specific_datasets: 指定读取信息的数据集名字,为None时,读取所有
123+
:param include_datasets: 指定读取信息的数据集名字,为None时,读取所有
124+
:param exclude_datasets: 排除读取信息的数据集名字,为None时,读取所有,与include_datasets必须仅有一个非None
112125
:return: datastes_full_info
113126
"""
114127

115128
assert os.path.exists(datastes_info_json) and os.path.isfile(
116129
datastes_info_json
117130
), datastes_info_json
131+
if include_datasets and exclude_datasets:
132+
raise ValueError("include_methods、exclude_methods 不可以同时非None")
118133

119134
with open(datastes_info_json, encoding="utf-8", mode="r") as f:
120135
datasets_info = json.load(f, object_pairs_hook=OrderedDict) # 有序载入
121136

122-
if specific_datasets:
123-
for dataset_name in specific_datasets:
137+
if include_datasets:
138+
for dataset_name in include_datasets:
124139
if dataset_name not in datasets_info:
125140
raise ValueError(f"The info of {dataset_name} is not in the datasets_info_json.")
141+
if exclude_datasets:
142+
for dataset_name in exclude_datasets:
143+
if dataset_name not in datasets_info:
144+
raise ValueError(f"The info of {dataset_name} is not in the methods_info_json.")
126145

127146
datasets_full_info = []
128147
for dataset_name, data_path in datasets_info.items():
129-
if specific_datasets and (dataset_name not in specific_datasets):
148+
if include_datasets and (dataset_name not in include_datasets):
149+
continue
150+
if exclude_datasets and (dataset_name in exclude_datasets):
130151
continue
131152

132153
datasets_full_info.append((dataset_name, data_path))

0 commit comments

Comments
 (0)