--- config_files/endpoints.py
+++ config_files/endpoints.py
... | ... | @@ -1,0 +1,3 @@ |
1 |
+INFERENCE_ENDPOINT = "http://localhost:12345/cctv/infer" |
|
2 |
+POSTPROCESS_ENDPOINT = "http://localhost:13579/postprocess/postprocess" |
|
3 |
+MAIN_SYSTEM_ENDPOINT = ""(파일 끝에 줄바꿈 문자 없음) |
--- inference_endpoint.py
+++ inference_endpoint.py
... | ... | @@ -1,15 +1,19 @@ |
1 | 1 |
import numpy as np |
2 |
-from flask import Flask, request |
|
3 |
-from flask_restx import Api, Resource, fields |
|
4 | 2 |
import os |
5 |
-from datetime import datetime |
|
6 |
-from yoloseg.inference_ import Inference, overlay_mask |
|
7 | 3 |
import cv2 |
8 | 4 |
import time |
5 |
+from datetime import datetime |
|
9 | 6 |
from zoneinfo import ZoneInfo |
10 |
-import base64 |
|
7 |
+ |
|
8 |
+from flask import Flask, request |
|
9 |
+from flask_restx import Api, Resource, fields |
|
11 | 10 |
import requests |
12 | 11 |
from requests_toolbelt import MultipartEncoder |
12 |
+import base64 |
|
13 |
+ |
|
14 |
+from yoloseg.inference_ import Inference, overlay_mask |
|
15 |
+from config_files.endpoints import POSTPROCESS_ENDPOINT |
|
16 |
+ |
|
13 | 17 |
# from config_files import API_ENDPOINT_MAIN |
14 | 18 |
|
15 | 19 |
app = Flask(__name__) |
... | ... | @@ -59,9 +63,10 @@ |
59 | 63 |
self.image = None |
60 | 64 |
self.image_type = None |
61 | 65 |
self.seg_image = None |
66 |
+ self.flag_detected = False |
|
62 | 67 |
self.area_percent = 0 |
63 | 68 |
self.time_zone = self.time_zone = ZoneInfo("Asia/Seoul") |
64 |
- self.endpoint = None |
|
69 |
+ self.endpoint = POSTPROCESS_ENDPOINT |
|
65 | 70 |
|
66 | 71 |
@ns.response(200, 'Success') |
67 | 72 |
@ns.response(400, 'Validation Error') |
... | ... | @@ -83,21 +88,24 @@ |
83 | 88 |
|
84 | 89 |
t1 = time.time() |
85 | 90 |
detections, self.mask = inference_engine.run_inference(cv2.resize(image, model_input_shape)) |
86 |
- |
|
87 | 91 |
t2 = time.time() |
88 |
- if len(self.mask) > 0: |
|
89 |
- self.mask = cv2.resize(self.mask, (image.shape[0], image.shape[1])) |
|
90 |
- self.mask_blob = cv2.imencode('.png', self.mask) |
|
91 |
- self.mask_blob = self.mask.tobytes() |
|
92 |
- |
|
93 |
- |
|
94 | 92 |
print(t2 - t1) |
95 | 93 |
|
96 | 94 |
if len(self.mask) != 0: |
95 |
+ self.flag_detected = True |
|
96 |
+ else: |
|
97 |
+ self.flag_detected = False |
|
98 |
+ |
|
99 |
+ if self.flag_detected: |
|
100 |
+ self.mask = cv2.resize(self.mask, (image.shape[0], image.shape[1])) |
|
101 |
+ self.mask_blob = cv2.imencode('.png', self.mask) |
|
102 |
+ self.mask_blob = self.mask.tobytes() |
|
97 | 103 |
self.seg_image = overlay_mask(image, self.mask[0], color=(0, 255, 0), alpha=0.3) |
98 |
- self.area_percent = 0 |
|
99 |
- else : |
|
100 | 104 |
self.area_percent = np.sum(self.mask) / image.shape[0] * image.shape[1] |
105 |
+ else : |
|
106 |
+ self.area_percent = 0 |
|
107 |
+ |
|
108 |
+ |
|
101 | 109 |
|
102 | 110 |
self.send_result() |
103 | 111 |
# write another post request for pushing a detection result |
... | ... | @@ -105,6 +113,7 @@ |
105 | 113 |
|
106 | 114 |
def send_result(self): |
107 | 115 |
time_sent = datetime.now(self.time_zone).strftime("yyyy-MM-dd'T'HH:mm:ss'Z'") |
116 |
+ print(str(self.flag_detected)) |
|
108 | 117 |
header = { |
109 | 118 |
'Content-Type': f'{self.image_type}', |
110 | 119 |
'x-time-sent': time_sent, |
... | ... | @@ -112,54 +121,52 @@ |
112 | 121 |
'x-cctv-latitude': str(self.cctv_latitude), |
113 | 122 |
'x-cctv-longitude': str(self.cctv_longitude), |
114 | 123 |
'x-area-percentage' : str(self.area_percent), |
124 |
+ 'x-flag_detected' : str(self.flag_detected), #"True" or "False" |
|
115 | 125 |
} |
116 | 126 |
session = requests.Session() |
117 | 127 |
|
118 |
- print(type(self.seg_image)) |
|
119 |
- print(type(self.mask)) |
|
120 |
- print(type(self.image)) |
|
121 |
- try: |
|
122 |
- if len(self.mask) != 0: |
|
123 |
- seg_binary = cv2.imencode('.png', self.seg_image) |
|
124 |
- seg_binary = seg_binary[1].tobytes() |
|
125 |
- multipart_data = MultipartEncoder( |
|
126 |
- fields={ |
|
127 |
- 'image': ( |
|
128 |
- f'frame_{self.cctv_name}.{self.image_type}', |
|
129 |
- self.image, |
|
130 |
- f'image/{self.image_type}' |
|
131 |
- ), |
|
132 |
- 'mask' : ( |
|
133 |
- f'frame_mask_{self.cctv_name}.{self.image_type}', |
|
134 |
- self.mask_blob, |
|
135 |
- f'image/{self.image_type}' |
|
136 |
- ), |
|
137 |
- 'seg_mask' : ( |
|
138 |
- f'frame_seg_{self.cctv_name}.{self.image_type}', |
|
139 |
- seg_binary, |
|
140 |
- f'image/{self.image_type}' |
|
141 |
- ) |
|
142 |
- } |
|
143 |
- ) |
|
144 |
- header["Content-Type"] = multipart_data.content_type |
|
145 |
- response = session.post(self.endpoint, headers=header, data=multipart_data) |
|
146 |
- else: |
|
147 |
- multipart_data = MultipartEncoder( |
|
148 |
- fields={ |
|
149 |
- 'image': ( |
|
150 |
- f'frame_{self.cctv_name}.{self.image_type}', |
|
151 |
- self.image, |
|
152 |
- f'image/{self.image_type}' |
|
153 |
- ), |
|
154 |
- } |
|
155 |
- ) |
|
128 |
+ # try: |
|
129 |
+ if self.flag_detected: |
|
130 |
+ seg_binary = cv2.imencode('.png', self.seg_image) |
|
131 |
+ seg_binary = seg_binary[1].tobytes() |
|
132 |
+ multipart_data = MultipartEncoder( |
|
133 |
+ fields={ |
|
134 |
+ 'image': ( |
|
135 |
+ f'frame_{self.cctv_name}.{self.image_type}', |
|
136 |
+ self.image, |
|
137 |
+ f'image/{self.image_type}' |
|
138 |
+ ), |
|
139 |
+ 'mask' : ( |
|
140 |
+ f'frame_mask_{self.cctv_name}.{self.image_type}', |
|
141 |
+ self.mask_blob, |
|
142 |
+ f'image/{self.image_type}' |
|
143 |
+ ), |
|
144 |
+ 'seg_mask' : ( |
|
145 |
+ f'frame_seg_{self.cctv_name}.{self.image_type}', |
|
146 |
+ seg_binary, |
|
147 |
+ f'image/{self.image_type}' |
|
148 |
+ ) |
|
149 |
+ } |
|
150 |
+ ) |
|
151 |
+ header["Content-Type"] = multipart_data.content_type |
|
152 |
+ response = session.post(self.endpoint, headers=header, data=multipart_data) |
|
153 |
+ else: |
|
154 |
+ multipart_data = MultipartEncoder( |
|
155 |
+ fields={ |
|
156 |
+ 'image': ( |
|
157 |
+ f'frame_{self.cctv_name}.{self.image_type}', |
|
158 |
+ self.image, |
|
159 |
+ f'image/{self.image_type}' |
|
160 |
+ ), |
|
161 |
+ } |
|
162 |
+ ) |
|
156 | 163 |
header["Content-Type"] = multipart_data.content_type |
157 | 164 |
response = session.post(self.endpoint, headers=header, data=multipart_data) |
158 | 165 |
|
159 |
- except Exception as e: |
|
160 |
- print(e) |
|
161 |
- print("Can not connect to the postprocessing server. Check the endpoint address or connection.\n" |
|
162 |
- f"Can not connect to : {self.endpoint}") |
|
166 |
+ # except Exception as e: |
|
167 |
+ # print(e) |
|
168 |
+ # print("Can not connect to the postprocessing server. Check the endpoint address or connection.\n" |
|
169 |
+ # f"Can not connect to : {self.endpoint}") |
|
163 | 170 |
|
164 | 171 |
|
165 | 172 |
if __name__ == '__main__': |
--- postprocess_draft.py
+++ postprocess_draft.py
... | ... | @@ -18,14 +18,14 @@ |
18 | 18 |
description='A postprocessing and adaptive rate mainserver pusher') |
19 | 19 |
|
20 | 20 |
# Namespace definition |
21 |
-ns = api.namespace('cctv', description='CCTV operations') |
|
21 |
+ns = api.namespace('postprocess', description='Postprocessing of inference results') |
|
22 | 22 |
|
23 | 23 |
class StreamSources(): |
24 | 24 |
def __init__(self, buffer_size, normal_send_interval, failure_mode_thres, failure_mode_check_past_n, normal_mode_thres, normal_mode_check_past_n): |
25 | 25 |
assert failure_mode_thres <= failure_mode_check_past_n, f"failure_mode checker condition is invaild!, failure_mode needs {failure_mode_thres} fails in {failure_mode_check_past_n}, which is not possible!" |
26 | 26 |
assert normal_mode_thres <= normal_mode_check_past_n, f"normal_mode checker condition is invaild!, normal_mode needs {normal_mode_thres} fails in {normal_mode_check_past_n}, which is not possible!" |
27 |
- assert buffer_size < failure_mode_check_past_n, f"'buffer_size' is smaller then failure_mode_thres! This is not possible! This will cause program to never enter failure mode!! \nPrinting relevent args and shutting down!\n buffer_size : {buffer_size}\n failure_mode_thres : {failure_mode_thres}" |
|
28 |
- assert buffer_size < normal_mode_thres, f"'buffer_size' is smaller then normal_mode_thres! This is will cause the program to never revert back to normal mode!! \nPrinting relevent args and shutting down!\n buffer_size : {buffer_size}\n normal_mode_thres : {normal_mode_thres}" |
|
27 |
+ assert buffer_size >= failure_mode_check_past_n, f"'buffer_size' is smaller then failure_mode_thres! This is not possible! This will cause program to never enter failure mode!! \nPrinting relevent args and shutting down!\n buffer_size : {buffer_size}\n failure_mode_thres : {failure_mode_thres}" |
|
28 |
+ assert buffer_size >= normal_mode_check_past_n, f"'buffer_size' is smaller then normal_mode_thres! This is will cause the program to never revert back to normal mode!! \nPrinting relevent args and shutting down!\n buffer_size : {buffer_size}\n normal_mode_thres : {normal_mode_thres}" |
|
29 | 29 |
|
30 | 30 |
self.sources = {} |
31 | 31 |
self.buffer_size = buffer_size |
... | ... | @@ -66,7 +66,7 @@ |
66 | 66 |
assert status in ["OK", "FAIL"], f"Invalid status was given!, status must be one of 'OK' or 'FAIL', but given '{status}'!" |
67 | 67 |
|
68 | 68 |
if source not in self.sources: |
69 |
- raise f"No key found for source. Did you forgot to add it? \n source : {source}" |
|
69 |
+ raise ValueError(f"No key found for source. Did you forgot to add it? \n source : {source}") |
|
70 | 70 |
|
71 | 71 |
self.sources[source]["status_counts"].append(status) |
72 | 72 |
if len(self.sources[source]["status_counts"]) > self.buffer_size: |
... | ... | @@ -113,6 +113,7 @@ |
113 | 113 |
self.image_type = None |
114 | 114 |
self.seg_image = None |
115 | 115 |
self.area_percent = 0 |
116 |
+ self.detected = False |
|
116 | 117 |
self.memory = StreamSources( |
117 | 118 |
buffer_size=15, |
118 | 119 |
normal_send_interval=10, |
... | ... | @@ -131,8 +132,16 @@ |
131 | 132 |
self.time_sent = request.headers.get('x-time-sent', '') |
132 | 133 |
self.cctv_latitude = request.headers.get('x-cctv-latitude', 'Not provided') |
133 | 134 |
self.cctv_longitude = request.headers.get('x-cctv-longitude', 'Not provided') |
135 |
+ self.detected = request.headers.get('x-flag_detected') |
|
136 |
+ if self.detected == "True": |
|
137 |
+ self.detected = True |
|
138 |
+ elif self.detected == "False": |
|
139 |
+ self.detected = False |
|
140 |
+ else: |
|
141 |
+ raise ValueError(f"Invalided value for x-flag_detected : {self.detected}") |
|
142 |
+ print(self.detected) |
|
134 | 143 |
self.area_percent = request.headers.get('x-area-percentage') |
135 |
- |
|
144 |
+ self.area_percent = float(self.area_percent) |
|
136 | 145 |
self.image = request.files['image'] |
137 | 146 |
self.image_type = request.headers.get('Content-Type') |
138 | 147 |
self.mask = request.files['mask'] |
... | ... | @@ -157,7 +166,12 @@ |
157 | 166 |
thres = 0.1 |
158 | 167 |
#TODO temporal pass_fail threshold |
159 | 168 |
if self.area_percent > thres: |
160 |
- ret = 'Fail' |
|
169 |
+ ret = 'FAIL' |
|
161 | 170 |
else: |
162 | 171 |
ret = 'OK' |
163 |
- return ret(파일 끝에 줄바꿈 문자 없음) |
|
172 |
+ return ret |
|
173 |
+ |
|
174 |
+ |
|
175 |
+if __name__ == "__main__": |
|
176 |
+ print("Postprocess Online") |
|
177 |
+ app.run(debug=True, port=13579)(파일 끝에 줄바꿈 문자 없음) |
--- run_image_anal_backend.sh
+++ run_image_anal_backend.sh
... | ... | @@ -16,6 +16,9 @@ |
16 | 16 |
#gunicorn --workers=6 inference_endpoint:app |
17 | 17 |
pids+=($!) |
18 | 18 |
|
19 |
+#python postprocess_draft.py |
|
20 |
+#pids+=($!) |
|
21 |
+ |
|
19 | 22 |
# Function to kill all processes |
20 | 23 |
cleanup() { |
21 | 24 |
echo "Terminating all processes..." |
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?