Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
parkpow
GitHub Repository: parkpow/deep-license-plate-recognition
Path: blob/master/benchmark/benchmark_snapshot.py
641 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 [(800, 600), (1280, 720), (1920, 1080), (2560, 1440)]:
82
image.resize(resolution).save("/tmp/platerec-benchmark.jpg")
83
if args.blur:
84
configs = [{}]
85
else:
86
configs = [{}, dict(mode="fast")]
87
88
for config in configs:
89
now = default_timer()
90
stats = list(
91
executor.map(
92
partial(
93
call_duration,
94
sdk_url=args.sdk_url,
95
config=config,
96
mmc=args.mmc,
97
blur=args.blur,
98
),
99
["/tmp/platerec-benchmark.jpg"] * args.iterations,
100
)
101
)
102
duration = (default_timer() - now) * 1000
103
yield dict(
104
resolution="%sx%s" % resolution,
105
mode=config.get("mode", "regular"),
106
min=min(stats),
107
max=max(stats),
108
avg=mean(stats),
109
)
110
111
112
def mem_usage():
113
usage = {}
114
for process in process_iter():
115
try:
116
if "main.py" in process.cmdline() or "start.sh" in process.cmdline():
117
usage[process.pid] = process.memory_info()
118
except psutil.ZombieProcess:
119
pass
120
return usage
121
122
123
def convert_size(size_bytes):
124
if size_bytes == 0:
125
return "0B"
126
sign = ""
127
if size_bytes < 0:
128
size_bytes *= -1
129
sign = "-"
130
size_name = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB")
131
i = int(math.floor(math.log(size_bytes, 1024)))
132
p = math.pow(1024, i)
133
s = round(size_bytes / p, 2)
134
return f"{sign}{s} {size_name[i]}"
135
136
137
def main():
138
args = parse_arguments()
139
initial_mem = mem_usage()
140
cpu_percent() # first time this is called it will return a meaningless 0.0
141
with ThreadPoolExecutor(max_workers=args.threads) as executor:
142
# Warmup
143
list(
144
executor.map(
145
partial(
146
call_duration,
147
sdk_url=args.sdk_url,
148
config={},
149
mmc=args.mmc,
150
blur=args.blur,
151
),
152
[args.image] * 2,
153
)
154
)
155
# Benchmark
156
results = list(benchmark(args, executor))
157
158
# Memory Usage
159
print(f"CPU: {cpu_percent()}%")
160
for pid, mem in mem_usage().items():
161
print(
162
f"PID: {pid:5}, "
163
f"RES {convert_size(mem.rss):10} ({convert_size(mem.rss - initial_mem[pid].rss):10}), "
164
f"SHR {convert_size(mem.shared):10} ({convert_size(mem.shared - initial_mem[pid].shared):10})"
165
)
166
print_table(results)
167
168
169
if __name__ == "__main__":
170
main()
171
172