Yuantao Feng
commited on
Commit
·
0199e9f
1
Parent(s):
18103a9
Decoupling dataloader and benchmark runner (#16)
Browse files* impl dataloader factory
* set a type to init all instances for benchmarks
- benchmark/benchmark.py +35 -58
- benchmark/config/face_detection_yunet.yaml +2 -2
- benchmark/config/face_recognition_sface.yaml +1 -2
- benchmark/config/human_segmentation_pphumanseg.yaml +2 -2
- benchmark/config/image_classification_ppresnet.yaml +2 -2
- benchmark/config/qrcode_wechatqrcode.yaml +2 -2
- benchmark/config/text_detection_db.yaml +2 -2
- benchmark/config/text_recognition_crnn.yaml +1 -2
- benchmark/utils/__init__.py +1 -0
- benchmark/utils/dataloaders/__init__.py +6 -0
- benchmark/utils/dataloaders/base.py +12 -0
- benchmark/utils/dataloaders/base_dataloader.py +67 -0
- benchmark/utils/dataloaders/classification.py +42 -0
- benchmark/utils/dataloaders/recognition.py +30 -0
- benchmark/utils/dataloaders/tracking.py +25 -0
- benchmark/utils/factory.py +8 -1
- benchmark/utils/metrics/base.py +9 -14
- benchmark/utils/metrics/base_metric.py +0 -3
- benchmark/utils/metrics/detection.py +14 -18
- benchmark/utils/metrics/recognition.py +1 -6
benchmark/benchmark.py
CHANGED
@@ -7,17 +7,23 @@ import cv2 as cv
|
|
7 |
|
8 |
# from ..models import MODELS
|
9 |
from models import MODELS
|
10 |
-
from utils import METRICS
|
11 |
|
12 |
parser = argparse.ArgumentParser("Benchmarks for OpenCV Zoo.")
|
13 |
parser.add_argument('--cfg', '-c', type=str,
|
14 |
help='Benchmarking on the given config.')
|
15 |
args = parser.parse_args()
|
16 |
|
17 |
-
def build_from_cfg(cfg, registery, key=
|
18 |
-
|
19 |
-
|
20 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
|
22 |
def prepend_pythonpath(cfg):
|
23 |
for k, v in cfg.items():
|
@@ -27,62 +33,26 @@ def prepend_pythonpath(cfg):
|
|
27 |
if 'path' in k.lower():
|
28 |
cfg[k] = os.path.join(os.environ['PYTHONPATH'], v)
|
29 |
|
30 |
-
class Data:
|
31 |
-
def __init__(self, **kwargs):
|
32 |
-
self._path = kwargs.pop('path', None)
|
33 |
-
assert self._path, 'Benchmark[\'data\'][\'path\'] cannot be empty.'
|
34 |
-
|
35 |
-
self._files = kwargs.pop('files', None)
|
36 |
-
if not self._files:
|
37 |
-
print('Benchmark[\'data\'][\'files\'] is empty, loading all images by default.')
|
38 |
-
self._files = list()
|
39 |
-
for filename in os.listdir(self._path):
|
40 |
-
if filename.endswith('jpg') or filename.endswith('png'):
|
41 |
-
self._files.append(filename)
|
42 |
-
|
43 |
-
self._use_label = kwargs.pop('useLabel', False)
|
44 |
-
if self._use_label:
|
45 |
-
self._labels = self._load_label()
|
46 |
-
|
47 |
-
self._to_rgb = kwargs.pop('toRGB', False)
|
48 |
-
self._resize = tuple(kwargs.pop('resize', []))
|
49 |
-
self._center_crop = kwargs.pop('centerCrop', None)
|
50 |
-
|
51 |
-
def _load_label(self):
|
52 |
-
labels = dict.fromkeys(self._files, None)
|
53 |
-
for filename in self._files:
|
54 |
-
labels[filename] = np.loadtxt(os.path.join(self._path, '{}.txt'.format(filename[:-4])), ndmin=2)
|
55 |
-
return labels
|
56 |
-
|
57 |
-
def __getitem__(self, idx):
|
58 |
-
image = cv.imread(os.path.join(self._path, self._files[idx]))
|
59 |
-
|
60 |
-
if self._to_rgb:
|
61 |
-
image = cv.cvtColor(image, cv.COLOR_BGR2RGB)
|
62 |
-
if self._resize:
|
63 |
-
image = cv.resize(image, self._resize)
|
64 |
-
if self._center_crop:
|
65 |
-
h, w, _ = image.shape
|
66 |
-
w_crop = int((w - self._center_crop) / 2.)
|
67 |
-
assert w_crop >= 0
|
68 |
-
h_crop = int((h - self._center_crop) / 2.)
|
69 |
-
assert h_crop >= 0
|
70 |
-
image = image[w_crop:w-w_crop, h_crop:h-h_crop, :]
|
71 |
-
|
72 |
-
if self._use_label:
|
73 |
-
return self._files[idx], image, self._labels[self._files[idx]]
|
74 |
-
else:
|
75 |
-
return self._files[idx], image
|
76 |
-
|
77 |
class Benchmark:
|
78 |
def __init__(self, **kwargs):
|
|
|
|
|
|
|
|
|
|
|
79 |
self._data_dict = kwargs.pop('data', None)
|
80 |
assert self._data_dict, 'Benchmark[\'data\'] cannot be empty and must have path and files.'
|
81 |
-
|
|
|
|
|
|
|
82 |
|
83 |
self._metric_dict = kwargs.pop('metric', None)
|
84 |
-
|
85 |
-
|
|
|
|
|
|
|
86 |
|
87 |
backend_id = kwargs.pop('backend', 'default')
|
88 |
available_backends = dict(
|
@@ -115,8 +85,15 @@ class Benchmark:
|
|
115 |
model.setBackend(self._backend)
|
116 |
model.setTarget(self._target)
|
117 |
|
118 |
-
|
119 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
120 |
|
121 |
def printResults(self):
|
122 |
for imgName, results in self._benchmark_results.items():
|
@@ -138,7 +115,7 @@ if __name__ == '__main__':
|
|
138 |
benchmark = Benchmark(**cfg['Benchmark'])
|
139 |
|
140 |
# Instantiate model
|
141 |
-
model = build_from_cfg(cfg=cfg['Model'], registery=MODELS)
|
142 |
|
143 |
# Run benchmarking
|
144 |
print('Benchmarking {}:'.format(model.name))
|
|
|
7 |
|
8 |
# from ..models import MODELS
|
9 |
from models import MODELS
|
10 |
+
from utils import METRICS, DATALOADERS
|
11 |
|
12 |
parser = argparse.ArgumentParser("Benchmarks for OpenCV Zoo.")
|
13 |
parser.add_argument('--cfg', '-c', type=str,
|
14 |
help='Benchmarking on the given config.')
|
15 |
args = parser.parse_args()
|
16 |
|
17 |
+
def build_from_cfg(cfg, registery, key=None, name=None):
|
18 |
+
if key is not None:
|
19 |
+
obj_name = cfg.pop(key)
|
20 |
+
obj = registery.get(obj_name)
|
21 |
+
return obj(**cfg)
|
22 |
+
elif name is not None:
|
23 |
+
obj = registery.get(name)
|
24 |
+
return obj(**cfg)
|
25 |
+
else:
|
26 |
+
raise NotImplementedError()
|
27 |
|
28 |
def prepend_pythonpath(cfg):
|
29 |
for k, v in cfg.items():
|
|
|
33 |
if 'path' in k.lower():
|
34 |
cfg[k] = os.path.join(os.environ['PYTHONPATH'], v)
|
35 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
36 |
class Benchmark:
|
37 |
def __init__(self, **kwargs):
|
38 |
+
self._type = kwargs.pop('type', None)
|
39 |
+
if self._type is None:
|
40 |
+
self._type = 'Base'
|
41 |
+
print('Benchmark[\'type\'] is omitted, set to \'Base\' by default.')
|
42 |
+
|
43 |
self._data_dict = kwargs.pop('data', None)
|
44 |
assert self._data_dict, 'Benchmark[\'data\'] cannot be empty and must have path and files.'
|
45 |
+
if 'type' in self._data_dict:
|
46 |
+
self._dataloader = build_from_cfg(self._data_dict, registery=DATALOADERS, key='type')
|
47 |
+
else:
|
48 |
+
self._dataloader = build_from_cfg(self._data_dict, registery=DATALOADERS, name=self._type)
|
49 |
|
50 |
self._metric_dict = kwargs.pop('metric', None)
|
51 |
+
assert self._metric_dict, 'Benchmark[\'metric\'] cannot be empty.'
|
52 |
+
if 'type' in self._metric_dict:
|
53 |
+
self._metric = build_from_cfg(self._metric_dict, registery=METRICS, key='type')
|
54 |
+
else:
|
55 |
+
self._metric = build_from_cfg(self._metric_dict, registery=METRICS, name=self._type)
|
56 |
|
57 |
backend_id = kwargs.pop('backend', 'default')
|
58 |
available_backends = dict(
|
|
|
85 |
model.setBackend(self._backend)
|
86 |
model.setTarget(self._target)
|
87 |
|
88 |
+
if 'video' in self._dataloader.name.lower():
|
89 |
+
model.init(self._dataloader.getROI())
|
90 |
+
|
91 |
+
for data in self._dataloader:
|
92 |
+
filename, img = data[:2]
|
93 |
+
size = [img.shape[1], img.shape[0]]
|
94 |
+
if filename not in self._benchmark_results:
|
95 |
+
self._benchmark_results[filename] = dict()
|
96 |
+
self._benchmark_results[filename][str(size)] = self._metric.forward(model, *data[1:])
|
97 |
|
98 |
def printResults(self):
|
99 |
for imgName, results in self._benchmark_results.items():
|
|
|
115 |
benchmark = Benchmark(**cfg['Benchmark'])
|
116 |
|
117 |
# Instantiate model
|
118 |
+
model = build_from_cfg(cfg=cfg['Model'], registery=MODELS, key='name')
|
119 |
|
120 |
# Run benchmarking
|
121 |
print('Benchmarking {}:'.format(model.name))
|
benchmark/config/face_detection_yunet.yaml
CHANGED
@@ -1,13 +1,13 @@
|
|
1 |
Benchmark:
|
2 |
name: "Face Detection Benchmark"
|
|
|
3 |
data:
|
4 |
path: "benchmark/data/face/detection"
|
5 |
files: ["group.jpg", "concerts.jpg", "dance.jpg"]
|
6 |
-
metric:
|
7 |
-
type: "Detection"
|
8 |
sizes: # [[w1, h1], ...], Omit to run at original scale
|
9 |
- [160, 120]
|
10 |
- [640, 480]
|
|
|
11 |
warmup: 30
|
12 |
repeat: 10
|
13 |
reduction: "median"
|
|
|
1 |
Benchmark:
|
2 |
name: "Face Detection Benchmark"
|
3 |
+
type: "Detection"
|
4 |
data:
|
5 |
path: "benchmark/data/face/detection"
|
6 |
files: ["group.jpg", "concerts.jpg", "dance.jpg"]
|
|
|
|
|
7 |
sizes: # [[w1, h1], ...], Omit to run at original scale
|
8 |
- [160, 120]
|
9 |
- [640, 480]
|
10 |
+
metric:
|
11 |
warmup: 30
|
12 |
repeat: 10
|
13 |
reduction: "median"
|
benchmark/config/face_recognition_sface.yaml
CHANGED
@@ -1,11 +1,10 @@
|
|
1 |
Benchmark:
|
2 |
name: "Face Recognition Benchmark"
|
|
|
3 |
data:
|
4 |
path: "benchmark/data/face/recognition"
|
5 |
files: ["Aaron_Tippin_0001.jpg", "Alvaro_Uribe_0028.jpg", "Alvaro_Uribe_0029.jpg", "Jose_Luis_Rodriguez_Zapatero_0001.jpg"]
|
6 |
-
useLabel: True
|
7 |
metric: # 'sizes' is omitted since this model requires input of fixed size
|
8 |
-
type: "Recognition"
|
9 |
warmup: 30
|
10 |
repeat: 10
|
11 |
reduction: "median"
|
|
|
1 |
Benchmark:
|
2 |
name: "Face Recognition Benchmark"
|
3 |
+
type: "Recognition"
|
4 |
data:
|
5 |
path: "benchmark/data/face/recognition"
|
6 |
files: ["Aaron_Tippin_0001.jpg", "Alvaro_Uribe_0028.jpg", "Alvaro_Uribe_0029.jpg", "Jose_Luis_Rodriguez_Zapatero_0001.jpg"]
|
|
|
7 |
metric: # 'sizes' is omitted since this model requires input of fixed size
|
|
|
8 |
warmup: 30
|
9 |
repeat: 10
|
10 |
reduction: "median"
|
benchmark/config/human_segmentation_pphumanseg.yaml
CHANGED
@@ -1,12 +1,12 @@
|
|
1 |
Benchmark:
|
2 |
name: "Human Segmentation Benchmark"
|
|
|
3 |
data:
|
4 |
path: "benchmark/data/human_segmentation"
|
5 |
files: ["messi5.jpg", "100040721_1.jpg", "detect.jpg"]
|
|
|
6 |
toRGB: True
|
7 |
-
resize: [192, 192]
|
8 |
metric:
|
9 |
-
type: "Base"
|
10 |
warmup: 30
|
11 |
repeat: 10
|
12 |
reduction: "median"
|
|
|
1 |
Benchmark:
|
2 |
name: "Human Segmentation Benchmark"
|
3 |
+
type: "Base"
|
4 |
data:
|
5 |
path: "benchmark/data/human_segmentation"
|
6 |
files: ["messi5.jpg", "100040721_1.jpg", "detect.jpg"]
|
7 |
+
sizes: [[192, 192]]
|
8 |
toRGB: True
|
|
|
9 |
metric:
|
|
|
10 |
warmup: 30
|
11 |
repeat: 10
|
12 |
reduction: "median"
|
benchmark/config/image_classification_ppresnet.yaml
CHANGED
@@ -1,13 +1,13 @@
|
|
1 |
Benchmark:
|
2 |
name: "Image Classification Benchmark"
|
|
|
3 |
data:
|
4 |
path: "benchmark/data/image_classification"
|
5 |
files: ["coffee_mug.jpg", "umbrella.jpg", "wall_clock.jpg"]
|
|
|
6 |
toRGB: True
|
7 |
-
resize: [256, 256]
|
8 |
centerCrop: 224
|
9 |
metric:
|
10 |
-
type: "Base"
|
11 |
warmup: 30
|
12 |
repeat: 10
|
13 |
reduction: "median"
|
|
|
1 |
Benchmark:
|
2 |
name: "Image Classification Benchmark"
|
3 |
+
type: "Classification"
|
4 |
data:
|
5 |
path: "benchmark/data/image_classification"
|
6 |
files: ["coffee_mug.jpg", "umbrella.jpg", "wall_clock.jpg"]
|
7 |
+
sizes: [[256, 256]]
|
8 |
toRGB: True
|
|
|
9 |
centerCrop: 224
|
10 |
metric:
|
|
|
11 |
warmup: 30
|
12 |
repeat: 10
|
13 |
reduction: "median"
|
benchmark/config/qrcode_wechatqrcode.yaml
CHANGED
@@ -1,13 +1,13 @@
|
|
1 |
Benchmark:
|
2 |
name: "QRCode Detection and Decoding Benchmark"
|
|
|
3 |
data:
|
4 |
path: "benchmark/data/qrcode"
|
5 |
files: ["opencv.png", "opencv_zoo.png"]
|
6 |
-
metric:
|
7 |
-
type: "Detection"
|
8 |
sizes:
|
9 |
- [100, 100]
|
10 |
- [300, 300]
|
|
|
11 |
warmup: 30
|
12 |
repeat: 10
|
13 |
reduction: "median"
|
|
|
1 |
Benchmark:
|
2 |
name: "QRCode Detection and Decoding Benchmark"
|
3 |
+
type: "Detection"
|
4 |
data:
|
5 |
path: "benchmark/data/qrcode"
|
6 |
files: ["opencv.png", "opencv_zoo.png"]
|
|
|
|
|
7 |
sizes:
|
8 |
- [100, 100]
|
9 |
- [300, 300]
|
10 |
+
metric:
|
11 |
warmup: 30
|
12 |
repeat: 10
|
13 |
reduction: "median"
|
benchmark/config/text_detection_db.yaml
CHANGED
@@ -1,12 +1,12 @@
|
|
1 |
Benchmark:
|
2 |
name: "Text Detection Benchmark"
|
|
|
3 |
data:
|
4 |
path: "benchmark/data/text"
|
5 |
files: ["1.jpg", "2.jpg", "3.jpg"]
|
6 |
-
metric:
|
7 |
-
type: "Detection"
|
8 |
sizes: # [[w1, h1], ...], Omit to run at original scale
|
9 |
- [640, 480]
|
|
|
10 |
warmup: 30
|
11 |
repeat: 10
|
12 |
reduction: "median"
|
|
|
1 |
Benchmark:
|
2 |
name: "Text Detection Benchmark"
|
3 |
+
type: "Detection"
|
4 |
data:
|
5 |
path: "benchmark/data/text"
|
6 |
files: ["1.jpg", "2.jpg", "3.jpg"]
|
|
|
|
|
7 |
sizes: # [[w1, h1], ...], Omit to run at original scale
|
8 |
- [640, 480]
|
9 |
+
metric:
|
10 |
warmup: 30
|
11 |
repeat: 10
|
12 |
reduction: "median"
|
benchmark/config/text_recognition_crnn.yaml
CHANGED
@@ -1,11 +1,10 @@
|
|
1 |
Benchmark:
|
2 |
name: "Text Recognition Benchmark"
|
|
|
3 |
data:
|
4 |
path: "benchmark/data/text"
|
5 |
files: ["1.jpg", "2.jpg", "3.jpg"]
|
6 |
-
useLabel: True
|
7 |
metric: # 'sizes' is omitted since this model requires input of fixed size
|
8 |
-
type: "Recognition"
|
9 |
warmup: 30
|
10 |
repeat: 10
|
11 |
reduction: "median"
|
|
|
1 |
Benchmark:
|
2 |
name: "Text Recognition Benchmark"
|
3 |
+
type: "Recognition"
|
4 |
data:
|
5 |
path: "benchmark/data/text"
|
6 |
files: ["1.jpg", "2.jpg", "3.jpg"]
|
|
|
7 |
metric: # 'sizes' is omitted since this model requires input of fixed size
|
|
|
8 |
warmup: 30
|
9 |
repeat: 10
|
10 |
reduction: "median"
|
benchmark/utils/__init__.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1 |
from .factory import (METRICS, DATALOADERS)
|
2 |
from .metrics import *
|
|
|
3 |
|
4 |
__all__ = ['METRICS', 'DATALOADERS']
|
|
|
1 |
from .factory import (METRICS, DATALOADERS)
|
2 |
from .metrics import *
|
3 |
+
from .dataloaders import *
|
4 |
|
5 |
__all__ = ['METRICS', 'DATALOADERS']
|
benchmark/utils/dataloaders/__init__.py
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from .base import BaseImageLoader, BaseVideoLoader
|
2 |
+
from .classification import ClassificationImageLoader
|
3 |
+
from .recognition import RecognitionImageLoader
|
4 |
+
from .tracking import TrackingVideoLoader
|
5 |
+
|
6 |
+
__all__ = ['BaseImageLoader', 'BaseVideoLoader', 'ClassificationImageLoader', 'RecognitionImageLoader', 'TrackingVideoLoader']
|
benchmark/utils/dataloaders/base.py
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from .base_dataloader import _BaseImageLoader, _BaseVideoLoader
|
2 |
+
from ..factory import DATALOADERS
|
3 |
+
|
4 |
+
@DATALOADERS.register
|
5 |
+
class BaseImageLoader(_BaseImageLoader):
|
6 |
+
def __init__(self, **kwargs):
|
7 |
+
super().__init__(**kwargs)
|
8 |
+
|
9 |
+
@DATALOADERS.register
|
10 |
+
class BaseVideoLoader(_BaseVideoLoader):
|
11 |
+
def __init__(self, **kwargs):
|
12 |
+
super().__init__(**kwargs)
|
benchmark/utils/dataloaders/base_dataloader.py
ADDED
@@ -0,0 +1,67 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
|
3 |
+
import cv2 as cv
|
4 |
+
|
5 |
+
class _BaseImageLoader:
|
6 |
+
def __init__(self, **kwargs):
|
7 |
+
self._path = kwargs.pop('path', None)
|
8 |
+
assert self._path, 'Benchmark[\'data\'][\'path\'] cannot be empty.'
|
9 |
+
|
10 |
+
self._files = kwargs.pop('files', None)
|
11 |
+
assert self._files, 'Benchmark[\'data\'][\'files\'] cannot be empty'
|
12 |
+
self._len_files = len(self._files)
|
13 |
+
|
14 |
+
self._sizes = kwargs.pop('sizes', [[0, 0]])
|
15 |
+
self._len_sizes = len(self._sizes)
|
16 |
+
|
17 |
+
@property
|
18 |
+
def name(self):
|
19 |
+
return self.__class__.__name__
|
20 |
+
|
21 |
+
def __len__(self):
|
22 |
+
return self._len_files * self._len_sizes
|
23 |
+
|
24 |
+
def __iter__(self):
|
25 |
+
for filename in self._files:
|
26 |
+
image = cv.imread(os.path.join(self._path, filename))
|
27 |
+
if [0, 0] in self._sizes:
|
28 |
+
yield filename, image
|
29 |
+
else:
|
30 |
+
for size in self._sizes:
|
31 |
+
image_r = cv.resize(image, size)
|
32 |
+
yield filename, image_r
|
33 |
+
|
34 |
+
class _VideoStream:
|
35 |
+
def __init__(self, filepath):
|
36 |
+
self._filepath = filepath
|
37 |
+
self._video = cv.VideoCapture(filepath)
|
38 |
+
|
39 |
+
def __iter__(self):
|
40 |
+
while True:
|
41 |
+
has_frame, frame = self._video.read()
|
42 |
+
if has_frame:
|
43 |
+
yield frame
|
44 |
+
else:
|
45 |
+
break
|
46 |
+
|
47 |
+
def reload(self):
|
48 |
+
self._video = cv.VideoCapture(filepath)
|
49 |
+
|
50 |
+
|
51 |
+
class _BaseVideoLoader:
|
52 |
+
def __init__(self, **kwargs):
|
53 |
+
self._path = kwargs.pop('path', None)
|
54 |
+
assert self._path, 'Benchmark[\'data\'][\'path\'] cannot be empty.'
|
55 |
+
|
56 |
+
self._files = kwargs.pop('files', None)
|
57 |
+
assert self._files,'Benchmark[\'data\'][\'files\'] cannot be empty.'
|
58 |
+
|
59 |
+
@property
|
60 |
+
def name(self):
|
61 |
+
return self.__class__.__name__
|
62 |
+
|
63 |
+
def __len__(self):
|
64 |
+
return len(self._files)
|
65 |
+
|
66 |
+
def __getitem__(self, idx):
|
67 |
+
return self._files[idx], _VideoStream(os.path.join(self._path, self._files[idx]))
|
benchmark/utils/dataloaders/classification.py
ADDED
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
|
3 |
+
import numpy as np
|
4 |
+
import cv2 as cv
|
5 |
+
|
6 |
+
from .base_dataloader import _BaseImageLoader
|
7 |
+
from ..factory import DATALOADERS
|
8 |
+
|
9 |
+
@DATALOADERS.register
|
10 |
+
class ClassificationImageLoader(_BaseImageLoader):
|
11 |
+
def __init__(self, **kwargs):
|
12 |
+
super().__init__(**kwargs)
|
13 |
+
|
14 |
+
self._to_rgb = kwargs.pop('toRGB', False)
|
15 |
+
self._center_crop = kwargs.pop('centerCrop', None)
|
16 |
+
|
17 |
+
def _toRGB(self, image):
|
18 |
+
return cv.cvtColor(image, cv.COLOR_BGR2RGB)
|
19 |
+
|
20 |
+
def _centerCrop(self, image):
|
21 |
+
h, w, _ = image.shape
|
22 |
+
w_crop = int((w - self._center_crop) / 2.)
|
23 |
+
assert w_crop >= 0
|
24 |
+
h_crop = int((h - self._center_crop) / 2.)
|
25 |
+
assert h_crop >= 0
|
26 |
+
return image[w_crop:w-w_crop, h_crop:h-h_crop, :]
|
27 |
+
|
28 |
+
def __iter__(self):
|
29 |
+
for filename in self._files:
|
30 |
+
image = cv.imread(os.path.join(self._path, filename))
|
31 |
+
|
32 |
+
if self._to_rgb:
|
33 |
+
image = self._toRGB(image)
|
34 |
+
|
35 |
+
if [0, 0] in self._sizes:
|
36 |
+
yield filename, image
|
37 |
+
else:
|
38 |
+
for size in self._sizes:
|
39 |
+
image = cv.resize(image, size)
|
40 |
+
if self._center_crop:
|
41 |
+
image = self._centerCrop(image)
|
42 |
+
yield filename, image
|
benchmark/utils/dataloaders/recognition.py
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
|
3 |
+
import numpy as np
|
4 |
+
import cv2 as cv
|
5 |
+
|
6 |
+
from .base_dataloader import _BaseImageLoader
|
7 |
+
from ..factory import DATALOADERS
|
8 |
+
|
9 |
+
@DATALOADERS.register
|
10 |
+
class RecognitionImageLoader(_BaseImageLoader):
|
11 |
+
def __init__(self, **kwargs):
|
12 |
+
super().__init__(**kwargs)
|
13 |
+
|
14 |
+
self._labels = self._load_label()
|
15 |
+
|
16 |
+
def _load_label(self):
|
17 |
+
labels = dict.fromkeys(self._files, None)
|
18 |
+
for filename in self._files:
|
19 |
+
labels[filename] = np.loadtxt(os.path.join(self._path, '{}.txt'.format(filename[:-4])), ndmin=2)
|
20 |
+
return labels
|
21 |
+
|
22 |
+
def __iter__(self):
|
23 |
+
for filename in self._files:
|
24 |
+
image = cv.imread(os.path.join(self._path, filename))
|
25 |
+
if [0, 0] in self._sizes:
|
26 |
+
yield filename, image, self._labels[filename]
|
27 |
+
else:
|
28 |
+
for size in self._sizes:
|
29 |
+
image_r = cv.resize(image, size)
|
30 |
+
yield filename, image_r, self._labels[filename]
|
benchmark/utils/dataloaders/tracking.py
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import numpy as np
|
2 |
+
|
3 |
+
from .base_dataloader import _BaseVideoLoader
|
4 |
+
from ..factory import DATALOADERS
|
5 |
+
|
6 |
+
@DATALOADERS.register
|
7 |
+
class TrackingVideoLoader(_BaseVideoLoader):
|
8 |
+
def __init__(self, **kwargs):
|
9 |
+
super().__init__(**kwargs)
|
10 |
+
|
11 |
+
self._rois = self._load_roi()
|
12 |
+
|
13 |
+
unsupported_keys = []
|
14 |
+
for k, _ in kwargs.items():
|
15 |
+
unsupported_keys.append(k)
|
16 |
+
print('Keys ({}) are not supported in Benchmark[\'data\'].'.format(str(unsupported_keys)))
|
17 |
+
|
18 |
+
def _load_roi(self):
|
19 |
+
rois = dict.fromkeys(self._files, None)
|
20 |
+
for filename in self._files:
|
21 |
+
rois[filename] = np.loadtxt(os.path.join(self._path, '{}.txt'.format(filename[:-4])), ndmin=2)
|
22 |
+
return rois
|
23 |
+
|
24 |
+
def getROI(self):
|
25 |
+
return self._rois
|
benchmark/utils/factory.py
CHANGED
@@ -4,10 +4,17 @@ class Registery:
|
|
4 |
self._dict = dict()
|
5 |
|
6 |
def get(self, key):
|
7 |
-
|
|
|
|
|
|
|
8 |
|
9 |
def register(self, item):
|
10 |
self._dict[item.__name__] = item
|
|
|
|
|
|
|
|
|
11 |
|
12 |
METRICS = Registery('Metrics')
|
13 |
DATALOADERS = Registery('DataLoaders')
|
|
|
4 |
self._dict = dict()
|
5 |
|
6 |
def get(self, key):
|
7 |
+
if key in self._dict:
|
8 |
+
return self._dict[key]
|
9 |
+
else:
|
10 |
+
return self._dict['Base']
|
11 |
|
12 |
def register(self, item):
|
13 |
self._dict[item.__name__] = item
|
14 |
+
# renaming *ImageLoader/*VideoLoader
|
15 |
+
if 'ImageLoader' in item.__name__:
|
16 |
+
name = item.__name__.replace('ImageLoader', '')
|
17 |
+
self._dict[name] = item
|
18 |
|
19 |
METRICS = Registery('Metrics')
|
20 |
DATALOADERS = Registery('DataLoaders')
|
benchmark/utils/metrics/base.py
CHANGED
@@ -10,20 +10,15 @@ class Base(BaseMetric):
|
|
10 |
|
11 |
def forward(self, model, *args, **kwargs):
|
12 |
img = args[0]
|
13 |
-
if not self._sizes:
|
14 |
-
h, w, _ = img.shape
|
15 |
-
self._sizes.append([w, h])
|
16 |
|
17 |
-
|
|
|
|
|
|
|
18 |
self._timer.reset()
|
19 |
-
for
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
for _ in range(self._repeat):
|
24 |
-
self._timer.start()
|
25 |
-
model.infer(input_data)
|
26 |
-
self._timer.stop()
|
27 |
-
results[str(size)] = self._getResult()
|
28 |
|
29 |
-
return
|
|
|
10 |
|
11 |
def forward(self, model, *args, **kwargs):
|
12 |
img = args[0]
|
|
|
|
|
|
|
13 |
|
14 |
+
# warmup
|
15 |
+
for _ in range(self._warmup):
|
16 |
+
model.infer(img)
|
17 |
+
# repeat
|
18 |
self._timer.reset()
|
19 |
+
for _ in range(self._repeat):
|
20 |
+
self._timer.start()
|
21 |
+
model.infer(img)
|
22 |
+
self._timer.stop()
|
|
|
|
|
|
|
|
|
|
|
23 |
|
24 |
+
return self._getResult()
|
benchmark/utils/metrics/base_metric.py
CHANGED
@@ -4,9 +4,6 @@ from ..timer import Timer
|
|
4 |
|
5 |
class BaseMetric:
|
6 |
def __init__(self, **kwargs):
|
7 |
-
self._sizes = kwargs.pop('sizes', None)
|
8 |
-
if self._sizes is None:
|
9 |
-
self._sizes = []
|
10 |
self._warmup = kwargs.pop('warmup', 3)
|
11 |
self._repeat = kwargs.pop('repeat', 10)
|
12 |
self._reduction = kwargs.pop('reduction', 'median')
|
|
|
4 |
|
5 |
class BaseMetric:
|
6 |
def __init__(self, **kwargs):
|
|
|
|
|
|
|
7 |
self._warmup = kwargs.pop('warmup', 3)
|
8 |
self._repeat = kwargs.pop('repeat', 10)
|
9 |
self._reduction = kwargs.pop('reduction', 'median')
|
benchmark/utils/metrics/detection.py
CHANGED
@@ -10,24 +10,20 @@ class Detection(BaseMetric):
|
|
10 |
|
11 |
def forward(self, model, *args, **kwargs):
|
12 |
img = args[0]
|
13 |
-
|
14 |
-
|
15 |
-
|
|
|
|
|
16 |
|
17 |
-
|
|
|
|
|
|
|
18 |
self._timer.reset()
|
19 |
-
for
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
except:
|
24 |
-
pass
|
25 |
-
for _ in range(self._warmup):
|
26 |
-
model.infer(input_data)
|
27 |
-
for _ in range(self._repeat):
|
28 |
-
self._timer.start()
|
29 |
-
model.infer(input_data)
|
30 |
-
self._timer.stop()
|
31 |
-
results[str(size)] = self._getResult()
|
32 |
|
33 |
-
return
|
|
|
10 |
|
11 |
def forward(self, model, *args, **kwargs):
|
12 |
img = args[0]
|
13 |
+
size = [img.shape[1], img.shape[0]]
|
14 |
+
try:
|
15 |
+
model.setInputSize(size)
|
16 |
+
except:
|
17 |
+
pass
|
18 |
|
19 |
+
# warmup
|
20 |
+
for _ in range(self._warmup):
|
21 |
+
model.infer(img)
|
22 |
+
# repeat
|
23 |
self._timer.reset()
|
24 |
+
for _ in range(self._repeat):
|
25 |
+
self._timer.start()
|
26 |
+
model.infer(img)
|
27 |
+
self._timer.stop()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
|
29 |
+
return self._getResult()
|
benchmark/utils/metrics/recognition.py
CHANGED
@@ -10,11 +10,7 @@ class Recognition(BaseMetric):
|
|
10 |
|
11 |
def forward(self, model, *args, **kwargs):
|
12 |
img, bboxes = args
|
13 |
-
if not self._sizes:
|
14 |
-
h, w, _ = img.shape
|
15 |
-
self._sizes.append([w, h])
|
16 |
|
17 |
-
results = dict()
|
18 |
self._timer.reset()
|
19 |
for idx, bbox in enumerate(bboxes):
|
20 |
for _ in range(self._warmup):
|
@@ -23,6 +19,5 @@ class Recognition(BaseMetric):
|
|
23 |
self._timer.start()
|
24 |
model.infer(img, bbox)
|
25 |
self._timer.stop()
|
26 |
-
results['bbox{}'.format(idx)] = self._getResult()
|
27 |
|
28 |
-
return
|
|
|
10 |
|
11 |
def forward(self, model, *args, **kwargs):
|
12 |
img, bboxes = args
|
|
|
|
|
|
|
13 |
|
|
|
14 |
self._timer.reset()
|
15 |
for idx, bbox in enumerate(bboxes):
|
16 |
for _ in range(self._warmup):
|
|
|
19 |
self._timer.start()
|
20 |
model.infer(img, bbox)
|
21 |
self._timer.stop()
|
|
|
22 |
|
23 |
+
return self._getResult()
|