Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
parkpow
GitHub Repository: parkpow/deep-license-plate-recognition
Path: blob/master/benchmark/benchmark_snapshot.py
1089 views
1
import argparse
2
import math
3
from concurrent.futures import ThreadPoolExecutor
4
from functools import partial
5
from statistics import mean
6
from timeit import default_timer
7
8
import psutil
9
import requests
10
from PIL import Image
11
from psutil import cpu_percent, process_iter
12
13
from plate_recognition import recognition_api
14
15
16
def parse_arguments():
17
parser = argparse.ArgumentParser(description="Benchmark SDK.")
18
parser.add_argument(
19
"--sdk-url",
20
help="Url to self hosted sdk For example, http://localhost:8080",
21
default="http://localhost:8080",
22
)
23
parser.add_argument(
24
"--threads", help="Use thread to parallelize API calls", default=4, type=int
25
)
26
parser.add_argument("--image", default="assets/car-4k.jpg")
27
parser.add_argument("--mmc", action="store_true")
28
parser.add_argument("--iterations", default=50, type=int)
29
parser.add_argument("--blur", action="store_true")
30
return parser.parse_args()
31
32
33
def print_table(results):
34
if not results:
35
return
36
print("| Mode | Resolution | Speed | l_min | l_max |")
37
print("| -------- | ---------- | ------- | ------ | ------ |")
38
for result in results:
39
print(
40
"| {mode:8s} | {resolution:10s} | {avg:7.1f} | {min:6.1f} | {max:6.1f} |".format(
41
**result
42
)
43
)
44
45
46
def blur_api(url, fp):
47
"""
48
Upload an Image to url for burring
49
"""
50
response = requests.post(url, files={"upload": fp})
51
if response.status_code < 200 or response.status_code > 300:
52
if response.status_code == 400:
53
msg = response.json().get("error")
54
else:
55
msg = response.text
56
raise Exception(f"Error performing blur: {msg}")
57
58
blur_data = response.json().get("blur")
59
if blur_data is None:
60
raise Exception(
61
"Error - ensure blurring on server is enabled - "
62
"https://guides.platerecognizer.com/docs/blur/api-reference#post-parameters"
63
)
64
return blur_data
65
66
67
def call_duration(path, sdk_url, config, mmc, blur):
68
now = default_timer()
69
with open(path, "rb") as fp:
70
if blur:
71
blur_api(sdk_url, fp)
72
else:
73
recognition_api(
74
fp, sdk_url=sdk_url, config=config, mmc="true" if mmc else "false"
75
)
76
return (default_timer() - now) * 1000
77
78
79
def benchmark(args, executor):
80
image = Image.open(args.image)
81
for resolution in [
82
(800, 600),
83
(1280, 720),
84
(1920, 1080),
85
(2560, 1440),
86
(3840, 2160),
87
]:
88
image.resize(resolution).save("/tmp/platerec-benchmark.jpg")
89
configs = [{}] if args.blur else [{}, dict(mode="fast")]
90
91
for config in configs:
92
stats = list(
93
executor.map(
94
partial(
95
call_duration,
96
sdk_url=args.sdk_url,
97
config=config,
98
mmc=args.mmc,
99
blur=args.blur,
100
),
101
["/tmp/platerec-benchmark.jpg"] * args.iterations,
102
)
103
)
104
yield dict(
105
resolution=f"{resolution[0]}x{resolution[1]}",
106
mode=config.get("mode", "regular"),
107
min=min(stats),
108
max=max(stats),
109
avg=mean(stats),
110
)
111
112
113
def mem_usage():
114
usage = {}
115
for process in process_iter():
116
try:
117
if "main.py" in process.cmdline() or "start.sh" in process.cmdline():
118
usage[process.pid] = process.memory_info()
119
except psutil.ZombieProcess:
120
pass
121
return usage
122
123
124
def convert_size(size_bytes):
125
if size_bytes == 0:
126
return "0B"
127
sign = ""
128
if size_bytes < 0:
129
size_bytes *= -1
130
sign = "-"
131
size_name = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB")
132
i = int(math.floor(math.log(size_bytes, 1024)))
133
p = math.pow(1024, i)
134
s = round(size_bytes / p, 2)
135
return f"{sign}{s} {size_name[i]}"
136
137
138
def main():
139
args = parse_arguments()
140
initial_mem = mem_usage()
141
cpu_percent() # first time this is called it will return a meaningless 0.0
142
with ThreadPoolExecutor(max_workers=args.threads) as executor:
143
# Warmup
144
list(
145
executor.map(
146
partial(
147
call_duration,
148
sdk_url=args.sdk_url,
149
config={},
150
mmc=args.mmc,
151
blur=args.blur,
152
),
153
[args.image] * 2,
154
)
155
)
156
# Benchmark
157
results = list(benchmark(args, executor))
158
159
# Memory Usage
160
print(f"CPU: {cpu_percent()}%")
161
for pid, mem in mem_usage().items():
162
print(
163
f"PID: {pid:5}, "
164
f"RES {convert_size(mem.rss):10} ({convert_size(mem.rss - initial_mem[pid].rss):10}), "
165
f"SHR {convert_size(mem.shared):10} ({convert_size(mem.shared - initial_mem[pid].shared):10})"
166
)
167
print_table(results)
168
169
170
if __name__ == "__main__":
171
main()
172
173