megadetector 10.0.15__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- megadetector/__init__.py +0 -0
- megadetector/api/__init__.py +0 -0
- megadetector/api/batch_processing/integration/digiKam/setup.py +6 -0
- megadetector/api/batch_processing/integration/digiKam/xmp_integration.py +465 -0
- megadetector/api/batch_processing/integration/eMammal/test_scripts/config_template.py +5 -0
- megadetector/api/batch_processing/integration/eMammal/test_scripts/push_annotations_to_emammal.py +125 -0
- megadetector/api/batch_processing/integration/eMammal/test_scripts/select_images_for_testing.py +55 -0
- megadetector/classification/__init__.py +0 -0
- megadetector/classification/aggregate_classifier_probs.py +108 -0
- megadetector/classification/analyze_failed_images.py +227 -0
- megadetector/classification/cache_batchapi_outputs.py +198 -0
- megadetector/classification/create_classification_dataset.py +626 -0
- megadetector/classification/crop_detections.py +516 -0
- megadetector/classification/csv_to_json.py +226 -0
- megadetector/classification/detect_and_crop.py +853 -0
- megadetector/classification/efficientnet/__init__.py +9 -0
- megadetector/classification/efficientnet/model.py +415 -0
- megadetector/classification/efficientnet/utils.py +608 -0
- megadetector/classification/evaluate_model.py +520 -0
- megadetector/classification/identify_mislabeled_candidates.py +152 -0
- megadetector/classification/json_to_azcopy_list.py +63 -0
- megadetector/classification/json_validator.py +696 -0
- megadetector/classification/map_classification_categories.py +276 -0
- megadetector/classification/merge_classification_detection_output.py +509 -0
- megadetector/classification/prepare_classification_script.py +194 -0
- megadetector/classification/prepare_classification_script_mc.py +228 -0
- megadetector/classification/run_classifier.py +287 -0
- megadetector/classification/save_mislabeled.py +110 -0
- megadetector/classification/train_classifier.py +827 -0
- megadetector/classification/train_classifier_tf.py +725 -0
- megadetector/classification/train_utils.py +323 -0
- megadetector/data_management/__init__.py +0 -0
- megadetector/data_management/animl_to_md.py +161 -0
- megadetector/data_management/annotations/__init__.py +0 -0
- megadetector/data_management/annotations/annotation_constants.py +33 -0
- megadetector/data_management/camtrap_dp_to_coco.py +270 -0
- megadetector/data_management/cct_json_utils.py +566 -0
- megadetector/data_management/cct_to_md.py +184 -0
- megadetector/data_management/cct_to_wi.py +293 -0
- megadetector/data_management/coco_to_labelme.py +284 -0
- megadetector/data_management/coco_to_yolo.py +701 -0
- megadetector/data_management/databases/__init__.py +0 -0
- megadetector/data_management/databases/add_width_and_height_to_db.py +107 -0
- megadetector/data_management/databases/combine_coco_camera_traps_files.py +210 -0
- megadetector/data_management/databases/integrity_check_json_db.py +563 -0
- megadetector/data_management/databases/subset_json_db.py +195 -0
- megadetector/data_management/generate_crops_from_cct.py +200 -0
- megadetector/data_management/get_image_sizes.py +164 -0
- megadetector/data_management/labelme_to_coco.py +559 -0
- megadetector/data_management/labelme_to_yolo.py +349 -0
- megadetector/data_management/lila/__init__.py +0 -0
- megadetector/data_management/lila/create_lila_blank_set.py +556 -0
- megadetector/data_management/lila/create_lila_test_set.py +192 -0
- megadetector/data_management/lila/create_links_to_md_results_files.py +106 -0
- megadetector/data_management/lila/download_lila_subset.py +182 -0
- megadetector/data_management/lila/generate_lila_per_image_labels.py +777 -0
- megadetector/data_management/lila/get_lila_annotation_counts.py +174 -0
- megadetector/data_management/lila/get_lila_image_counts.py +112 -0
- megadetector/data_management/lila/lila_common.py +319 -0
- megadetector/data_management/lila/test_lila_metadata_urls.py +164 -0
- megadetector/data_management/mewc_to_md.py +344 -0
- megadetector/data_management/ocr_tools.py +873 -0
- megadetector/data_management/read_exif.py +964 -0
- megadetector/data_management/remap_coco_categories.py +195 -0
- megadetector/data_management/remove_exif.py +156 -0
- megadetector/data_management/rename_images.py +194 -0
- megadetector/data_management/resize_coco_dataset.py +665 -0
- megadetector/data_management/speciesnet_to_md.py +41 -0
- megadetector/data_management/wi_download_csv_to_coco.py +247 -0
- megadetector/data_management/yolo_output_to_md_output.py +594 -0
- megadetector/data_management/yolo_to_coco.py +984 -0
- megadetector/data_management/zamba_to_md.py +188 -0
- megadetector/detection/__init__.py +0 -0
- megadetector/detection/change_detection.py +840 -0
- megadetector/detection/process_video.py +479 -0
- megadetector/detection/pytorch_detector.py +1451 -0
- megadetector/detection/run_detector.py +1267 -0
- megadetector/detection/run_detector_batch.py +2172 -0
- megadetector/detection/run_inference_with_yolov5_val.py +1314 -0
- megadetector/detection/run_md_and_speciesnet.py +1604 -0
- megadetector/detection/run_tiled_inference.py +1044 -0
- megadetector/detection/tf_detector.py +209 -0
- megadetector/detection/video_utils.py +1379 -0
- megadetector/postprocessing/__init__.py +0 -0
- megadetector/postprocessing/add_max_conf.py +72 -0
- megadetector/postprocessing/categorize_detections_by_size.py +166 -0
- megadetector/postprocessing/classification_postprocessing.py +1943 -0
- megadetector/postprocessing/combine_batch_outputs.py +249 -0
- megadetector/postprocessing/compare_batch_results.py +2110 -0
- megadetector/postprocessing/convert_output_format.py +403 -0
- megadetector/postprocessing/create_crop_folder.py +629 -0
- megadetector/postprocessing/detector_calibration.py +570 -0
- megadetector/postprocessing/generate_csv_report.py +522 -0
- megadetector/postprocessing/load_api_results.py +223 -0
- megadetector/postprocessing/md_to_coco.py +428 -0
- megadetector/postprocessing/md_to_labelme.py +351 -0
- megadetector/postprocessing/md_to_wi.py +41 -0
- megadetector/postprocessing/merge_detections.py +392 -0
- megadetector/postprocessing/postprocess_batch_results.py +2140 -0
- megadetector/postprocessing/remap_detection_categories.py +226 -0
- megadetector/postprocessing/render_detection_confusion_matrix.py +677 -0
- megadetector/postprocessing/repeat_detection_elimination/find_repeat_detections.py +206 -0
- megadetector/postprocessing/repeat_detection_elimination/remove_repeat_detections.py +82 -0
- megadetector/postprocessing/repeat_detection_elimination/repeat_detections_core.py +1665 -0
- megadetector/postprocessing/separate_detections_into_folders.py +795 -0
- megadetector/postprocessing/subset_json_detector_output.py +964 -0
- megadetector/postprocessing/top_folders_to_bottom.py +238 -0
- megadetector/postprocessing/validate_batch_results.py +332 -0
- megadetector/taxonomy_mapping/__init__.py +0 -0
- megadetector/taxonomy_mapping/map_lila_taxonomy_to_wi_taxonomy.py +491 -0
- megadetector/taxonomy_mapping/map_new_lila_datasets.py +211 -0
- megadetector/taxonomy_mapping/prepare_lila_taxonomy_release.py +165 -0
- megadetector/taxonomy_mapping/preview_lila_taxonomy.py +543 -0
- megadetector/taxonomy_mapping/retrieve_sample_image.py +71 -0
- megadetector/taxonomy_mapping/simple_image_download.py +231 -0
- megadetector/taxonomy_mapping/species_lookup.py +1008 -0
- megadetector/taxonomy_mapping/taxonomy_csv_checker.py +159 -0
- megadetector/taxonomy_mapping/taxonomy_graph.py +346 -0
- megadetector/taxonomy_mapping/validate_lila_category_mappings.py +83 -0
- megadetector/tests/__init__.py +0 -0
- megadetector/tests/test_nms_synthetic.py +335 -0
- megadetector/utils/__init__.py +0 -0
- megadetector/utils/ct_utils.py +1857 -0
- megadetector/utils/directory_listing.py +199 -0
- megadetector/utils/extract_frames_from_video.py +307 -0
- megadetector/utils/gpu_test.py +125 -0
- megadetector/utils/md_tests.py +2072 -0
- megadetector/utils/path_utils.py +2872 -0
- megadetector/utils/process_utils.py +172 -0
- megadetector/utils/split_locations_into_train_val.py +237 -0
- megadetector/utils/string_utils.py +234 -0
- megadetector/utils/url_utils.py +825 -0
- megadetector/utils/wi_platform_utils.py +968 -0
- megadetector/utils/wi_taxonomy_utils.py +1766 -0
- megadetector/utils/write_html_image_list.py +239 -0
- megadetector/visualization/__init__.py +0 -0
- megadetector/visualization/plot_utils.py +309 -0
- megadetector/visualization/render_images_with_thumbnails.py +243 -0
- megadetector/visualization/visualization_utils.py +1973 -0
- megadetector/visualization/visualize_db.py +630 -0
- megadetector/visualization/visualize_detector_output.py +498 -0
- megadetector/visualization/visualize_video_output.py +705 -0
- megadetector-10.0.15.dist-info/METADATA +115 -0
- megadetector-10.0.15.dist-info/RECORD +147 -0
- megadetector-10.0.15.dist-info/WHEEL +5 -0
- megadetector-10.0.15.dist-info/licenses/LICENSE +19 -0
- megadetector-10.0.15.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
"""
|
|
2
|
+
|
|
3
|
+
map_classification_categories.py
|
|
4
|
+
|
|
5
|
+
Maps a classifier's output categories to desired target categories.
|
|
6
|
+
|
|
7
|
+
In this file, we use the following terminology:
|
|
8
|
+
* "category": a category output by the classifier
|
|
9
|
+
* "target": name of a desired group, comprising >= 1 classifier categories
|
|
10
|
+
|
|
11
|
+
Takes as input 2 label specification JSON files:
|
|
12
|
+
|
|
13
|
+
1) desired label specification JSON file
|
|
14
|
+
this should not have a target named "other"
|
|
15
|
+
|
|
16
|
+
2) label specification JSON file of trained classifier
|
|
17
|
+
|
|
18
|
+
The mapping is accomplished as follows:
|
|
19
|
+
|
|
20
|
+
1. For each category in the classifier label spec, find all taxon nodes that
|
|
21
|
+
belong to that category.
|
|
22
|
+
|
|
23
|
+
2. Given a target in the desired label spec, find all taxon nodes that belong
|
|
24
|
+
to that target. If there is any classifier category whose nodes are a
|
|
25
|
+
subset of the target nodes, then map the classifier category to that target.
|
|
26
|
+
Any partial intersection between a target's nodes and a category's nodes
|
|
27
|
+
is considered an error.
|
|
28
|
+
|
|
29
|
+
3. If there are any classifier categories that have not yet been assigned a
|
|
30
|
+
target, group them into the "other" target.
|
|
31
|
+
|
|
32
|
+
This script outputs a JSON file that maps each target to a list of classifier
|
|
33
|
+
categories.
|
|
34
|
+
|
|
35
|
+
The taxonomy mapping parts of this script are very similar to json_validator.py.
|
|
36
|
+
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
#%% Imports
|
|
40
|
+
|
|
41
|
+
from __future__ import annotations
|
|
42
|
+
|
|
43
|
+
import argparse
|
|
44
|
+
import json
|
|
45
|
+
import os
|
|
46
|
+
|
|
47
|
+
from collections import defaultdict
|
|
48
|
+
from collections.abc import Mapping
|
|
49
|
+
from typing import Any, Optional
|
|
50
|
+
|
|
51
|
+
import networkx as nx
|
|
52
|
+
import pandas as pd
|
|
53
|
+
from tqdm import tqdm
|
|
54
|
+
|
|
55
|
+
from megadetector.taxonomy_mapping.taxonomy_graph import (
|
|
56
|
+
build_taxonomy_graph, dag_to_tree, TaxonNode)
|
|
57
|
+
from megadetector.utils import ct_utils
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
#%% Example usage
|
|
61
|
+
|
|
62
|
+
"""
|
|
63
|
+
python map_classification_categories.py \
|
|
64
|
+
desired_label_spec.json \
|
|
65
|
+
/path/to/classifier/label_spec.json \
|
|
66
|
+
$HOME/camera-traps-private/camera_trap_taxonomy_mapping.csv
|
|
67
|
+
"""
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
#%% Main function
|
|
71
|
+
|
|
72
|
+
def main(desired_label_spec_json_path: str,
|
|
73
|
+
classifier_label_spec_json_path: str,
|
|
74
|
+
taxonomy_csv_path: str,
|
|
75
|
+
output_json_path: str,
|
|
76
|
+
classifier_label_index_path: Optional[str]) -> None:
|
|
77
|
+
|
|
78
|
+
print('Reading label spec JSON files')
|
|
79
|
+
with open(desired_label_spec_json_path, 'r') as f:
|
|
80
|
+
target_spec = json.load(f)
|
|
81
|
+
with open(classifier_label_spec_json_path, 'r') as f:
|
|
82
|
+
classifier_spec = json.load(f)
|
|
83
|
+
|
|
84
|
+
if classifier_label_index_path is not None:
|
|
85
|
+
with open(classifier_label_index_path, 'r') as f:
|
|
86
|
+
classifier_labels = set(json.load(f).values())
|
|
87
|
+
assert classifier_labels <= set(classifier_spec.keys())
|
|
88
|
+
if len(classifier_labels) < len(classifier_spec):
|
|
89
|
+
classifier_spec = {
|
|
90
|
+
k: v for k, v in classifier_spec.items()
|
|
91
|
+
if k in classifier_labels
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
print('Building taxonomy hierarchy')
|
|
95
|
+
taxonomy_df = pd.read_csv(taxonomy_csv_path)
|
|
96
|
+
graph, taxon_to_node, label_to_node = build_taxonomy_graph(taxonomy_df)
|
|
97
|
+
dag_to_tree(graph, taxon_to_node)
|
|
98
|
+
|
|
99
|
+
print('Mapping label spec to nodes')
|
|
100
|
+
classifier_label_to_nodes = label_spec_to_nodes(
|
|
101
|
+
classifier_spec, taxon_to_node, label_to_node)
|
|
102
|
+
target_label_to_nodes = label_spec_to_nodes(
|
|
103
|
+
target_spec, taxon_to_node, label_to_node)
|
|
104
|
+
|
|
105
|
+
print('Creating mapping from target to classifier categories')
|
|
106
|
+
target_to_classifier_labels = map_target_to_classifier(
|
|
107
|
+
target_label_to_nodes, classifier_label_to_nodes)
|
|
108
|
+
os.makedirs(os.path.dirname(output_json_path), exist_ok=True)
|
|
109
|
+
ct_utils.write_json(output_json_path, target_to_classifier_labels)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
#%% Support functions
|
|
113
|
+
|
|
114
|
+
def map_target_to_classifier(
|
|
115
|
+
target_label_to_nodes: Mapping[str, set[TaxonNode]],
|
|
116
|
+
classifier_label_to_nodes: Mapping[str, set[TaxonNode]]
|
|
117
|
+
) -> dict[str, list[str]]:
|
|
118
|
+
"""
|
|
119
|
+
For each target, if there is any classifier category whose nodes are a
|
|
120
|
+
subset of the target nodes, then assign the classifier category to that
|
|
121
|
+
target. Any partial intersection between a target's nodes and a category's
|
|
122
|
+
nodes is considered an error.
|
|
123
|
+
|
|
124
|
+
Args:
|
|
125
|
+
target_label_to_nodes: dict, maps target to set of nodes,
|
|
126
|
+
all of the sets of nodes should be disjoint
|
|
127
|
+
classifier_label_to_nodes: dict, maps classifier label to set of nodes,
|
|
128
|
+
all of the sets of nodes should be disjoint
|
|
129
|
+
|
|
130
|
+
Returns: dict, maps target label to set of classifier labels
|
|
131
|
+
"""
|
|
132
|
+
|
|
133
|
+
remaining_classifier_labels = set(classifier_label_to_nodes.keys())
|
|
134
|
+
target_to_classifier_labels: defaultdict[str, set[str]] = defaultdict(set)
|
|
135
|
+
for target, target_nodes in tqdm(target_label_to_nodes.items()):
|
|
136
|
+
for label, classifier_nodes in classifier_label_to_nodes.items():
|
|
137
|
+
overlap = classifier_nodes & target_nodes
|
|
138
|
+
if len(overlap) == len(classifier_nodes):
|
|
139
|
+
target_to_classifier_labels[target].add(label)
|
|
140
|
+
remaining_classifier_labels.remove(label)
|
|
141
|
+
elif 0 < len(overlap) < len(classifier_nodes): # partial overlap
|
|
142
|
+
raise ValueError('Only partial overlap between target '
|
|
143
|
+
f'{target} and classifier label {label}')
|
|
144
|
+
if len(remaining_classifier_labels) > 0:
|
|
145
|
+
target_to_classifier_labels['other'] = remaining_classifier_labels
|
|
146
|
+
target_to_sorted_labels = {
|
|
147
|
+
target: sorted(labels_set)
|
|
148
|
+
for target, labels_set in target_to_classifier_labels.items()
|
|
149
|
+
}
|
|
150
|
+
return target_to_sorted_labels
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def parse_spec(spec_dict: Mapping[str, Any],
|
|
154
|
+
taxon_to_node: dict[tuple[str, str], TaxonNode],
|
|
155
|
+
label_to_node: dict[tuple[str, str], TaxonNode]
|
|
156
|
+
) -> set[TaxonNode]:
|
|
157
|
+
"""
|
|
158
|
+
Args:
|
|
159
|
+
spec_dict: dict, contains keys ['taxa', 'dataset_labels', 'exclude']
|
|
160
|
+
{
|
|
161
|
+
"taxa": [
|
|
162
|
+
{'level': 'family', 'name': 'cervidae', 'datasets': ['idfg']},
|
|
163
|
+
{'level': 'genus', 'name': 'meleagris'} ],
|
|
164
|
+
"dataset_labels": { "idfg_swwlf_2019": ["bird"] },
|
|
165
|
+
"exclude": {...}
|
|
166
|
+
}
|
|
167
|
+
taxon_to_node: dict, maps (taxon_level, taxon_name) to a TaxonNode
|
|
168
|
+
label_to_node: dict, maps (dataset_name, dataset_label) to the lowest
|
|
169
|
+
TaxonNode node in the tree that contains the label
|
|
170
|
+
|
|
171
|
+
Returns: set of TaxonNode, nodes selected by the taxa spec
|
|
172
|
+
|
|
173
|
+
Raises: ValueError, if specification does not match any dataset labels
|
|
174
|
+
"""
|
|
175
|
+
|
|
176
|
+
result = set()
|
|
177
|
+
if 'taxa' in spec_dict:
|
|
178
|
+
for taxon in spec_dict['taxa']:
|
|
179
|
+
key = (taxon['level'].lower(), taxon['name'].lower())
|
|
180
|
+
if key in taxon_to_node:
|
|
181
|
+
node = taxon_to_node[key]
|
|
182
|
+
result.add(node)
|
|
183
|
+
result |= nx.descendants(node.graph, node)
|
|
184
|
+
else:
|
|
185
|
+
print(f'Taxon {key} not found in taxonomy graph. Ignoring.')
|
|
186
|
+
if 'dataset_labels' in spec_dict:
|
|
187
|
+
for ds, ds_labels in spec_dict['dataset_labels'].items():
|
|
188
|
+
ds = ds.lower()
|
|
189
|
+
for ds_label in ds_labels:
|
|
190
|
+
node = label_to_node[(ds, ds_label.lower())]
|
|
191
|
+
result.add(node)
|
|
192
|
+
result |= nx.descendants(node.graph, node)
|
|
193
|
+
if 'exclude' in spec_dict:
|
|
194
|
+
result -= parse_spec(spec_dict['exclude'], taxon_to_node, label_to_node)
|
|
195
|
+
if len(result) == 0:
|
|
196
|
+
raise ValueError(f'specification matched no TaxonNode: {spec_dict}')
|
|
197
|
+
return result
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
def label_spec_to_nodes(label_spec_js: dict[str, dict[str, Any]],
|
|
201
|
+
taxon_to_node: dict[tuple[str, str], TaxonNode],
|
|
202
|
+
label_to_node: dict[tuple[str, str], TaxonNode]
|
|
203
|
+
) -> dict[str, set[TaxonNode]]:
|
|
204
|
+
"""
|
|
205
|
+
Convert label spec to a mapping from classification labels to a set of
|
|
206
|
+
nodes.
|
|
207
|
+
|
|
208
|
+
Args:
|
|
209
|
+
label_spec_js: dict, Python dict representation of JSON file
|
|
210
|
+
see classification/README.md
|
|
211
|
+
taxon_to_node: dict, maps (taxon_level, taxon_name) to a TaxonNode
|
|
212
|
+
label_to_node: dict, maps (dataset_name, dataset_label) to the lowest
|
|
213
|
+
TaxonNode node in the tree that contains the label
|
|
214
|
+
|
|
215
|
+
Returns: dict, maps label name to set of TaxonNode
|
|
216
|
+
|
|
217
|
+
Raises: ValueError, if a classification label specification matches no
|
|
218
|
+
TaxonNode, or if a node is included in two or more classification labels
|
|
219
|
+
"""
|
|
220
|
+
|
|
221
|
+
# maps output label name to set of (dataset, dataset_label) tuples
|
|
222
|
+
seen_nodes: set[TaxonNode] = set()
|
|
223
|
+
label_to_nodes: dict[str, set[TaxonNode]] = {}
|
|
224
|
+
for label, spec_dict in label_spec_js.items():
|
|
225
|
+
include_set = parse_spec(spec_dict, taxon_to_node, label_to_node)
|
|
226
|
+
if include_set.isdisjoint(seen_nodes):
|
|
227
|
+
label_to_nodes[label] = include_set
|
|
228
|
+
seen_nodes |= include_set
|
|
229
|
+
else:
|
|
230
|
+
# find which other label (label_b) has intersection
|
|
231
|
+
for label_b, set_b in label_to_nodes.items():
|
|
232
|
+
shared = include_set.intersection(set_b)
|
|
233
|
+
if len(shared) > 0:
|
|
234
|
+
print(f'Labels {label} and {label_b} share images:', shared)
|
|
235
|
+
raise ValueError('Intersection between sets!')
|
|
236
|
+
return label_to_nodes
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
#%% Command-line driver
|
|
240
|
+
|
|
241
|
+
def _parse_args() -> argparse.Namespace:
|
|
242
|
+
|
|
243
|
+
parser = argparse.ArgumentParser(
|
|
244
|
+
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
|
245
|
+
description='Create mapping from target categories to classifier '
|
|
246
|
+
'labels.')
|
|
247
|
+
parser.add_argument(
|
|
248
|
+
'desired_label_spec_json',
|
|
249
|
+
help='path to JSON file containing desired label specification')
|
|
250
|
+
parser.add_argument(
|
|
251
|
+
'classifier_label_spec_json',
|
|
252
|
+
help='path to JSON file containing label specification of a trained '
|
|
253
|
+
'classifier')
|
|
254
|
+
parser.add_argument(
|
|
255
|
+
'taxonomy_csv',
|
|
256
|
+
help='path to taxonomy CSV file')
|
|
257
|
+
parser.add_argument(
|
|
258
|
+
'-o', '--output', required=True,
|
|
259
|
+
help='path to output JSON')
|
|
260
|
+
parser.add_argument(
|
|
261
|
+
'-i', '--classifier-label-index',
|
|
262
|
+
help='(optional) path to label index JSON file for trained classifier, '
|
|
263
|
+
'needed if not all labels from <classifier_label_spec_json> were '
|
|
264
|
+
'actually used (e.g., if some labels were filtered out by the '
|
|
265
|
+
'--min-locs argument for create_classification_dataset.py)')
|
|
266
|
+
return parser.parse_args()
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
if __name__ == '__main__':
|
|
270
|
+
|
|
271
|
+
args = _parse_args()
|
|
272
|
+
main(desired_label_spec_json_path=args.desired_label_spec_json,
|
|
273
|
+
classifier_label_spec_json_path=args.classifier_label_spec_json,
|
|
274
|
+
taxonomy_csv_path=args.taxonomy_csv,
|
|
275
|
+
output_json_path=args.output,
|
|
276
|
+
classifier_label_index_path=args.classifier_label_index)
|