-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathapp.py
102 lines (79 loc) · 3.22 KB
/
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import json
import os
from PIL import Image
from src.digitizer import Digitizer
from src.routing import IdentifierConverter
from src.draw import draw_objects
from src.file_storage import FileStorage
from io import BytesIO
from glob import glob
from flask import Flask, request, send_file
model = os.getenv("MODEL_PATH", "models/yolov8-detect-20240229.onnx")
data_dir = 'data/'
digitizer = Digitizer(model)
storage = FileStorage(data_dir)
app = Flask(__name__)
app.url_map.converters['identifier'] = IdentifierConverter
@app.route('/digitize', methods=['POST'])
def digitize():
decimals = request.args.get('decimals', default=0, type=int)
threshold = request.args.get('threshold', default=0.7, type=float)
image = __request_image()
value, _ = digitizer.detect(image, decimals, threshold)
if value is None:
return 'No reading found', 400
return json.dumps({'value': value}), 200, {'Content-Type': 'application/json'}
@app.route('/meter/<identifier:meter_id>', methods=['POST'])
def update_meter(meter_id):
decimals = request.args.get('decimals', default=0, type=int)
threshold = request.args.get('threshold', default=0.7, type=float)
max_increase = request.args.get('max_increase', default=float('inf'), type=float)
image = __request_image()
value, objects = digitizer.detect(image, decimals, threshold)
if value is None:
return 'No reading found', 400
try:
old_value = storage.read_value(meter_id)
if value < old_value:
return 'Reading is lower than previous', 400
if value - old_value > max_increase:
return 'Reading increased too much', 400
except FileNotFoundError:
# no old value
pass
result_image = image.copy()
draw_objects(result_image, objects)
storage.store(meter_id, value, image, result_image)
return json.dumps({'value': value}), 200, {'Content-Type': 'application/json'}
@app.route('/meter/<identifier:meter_id>', methods=['GET'])
def show_meter(meter_id):
try:
value = storage.read_value(meter_id)
return json.dumps({'value': value}), 200, {'Content-Type': 'application/json'}
except FileNotFoundError:
return 'Meter not found', 404
@app.route('/meter/<identifier:meter_id>/image', methods=['GET'])
def meter_image(meter_id):
try:
data = storage.read_image_data(meter_id)
return data, 200, {'Content-Type': 'image/jpeg'}
except FileNotFoundError:
return 'Meter not found', 404
@app.route('/meter/<identifier:meter_id>/result_image', methods=['GET'])
def meter_result_image(meter_id):
try:
data = storage.read_result_image_data(meter_id)
return data, 200, {'Content-Type': 'image/jpeg'}
except FileNotFoundError:
return 'Meter not found', 404
@app.route('/meter/<identifier:meter_id>/reset', methods=['GET'])
def reset_meter(meter_id):
value = request.args.get('value', default=None, type=float)
storage.remove(meter_id)
if value is not None:
blank_image = Image.new('RGB', (1, 1))
storage.store(meter_id, value, blank_image, blank_image)
return 'Meter reset', 200
def __request_image():
image_data = request.get_data()
return Image.open(BytesIO(image_data))