rewriting of event handling class, StreamSources
@5f24d8f0d2e8818c5de668674d481e215cf53fe8
--- inference_endpoint.py
+++ inference_endpoint.py
... | ... | @@ -97,7 +97,11 @@ |
97 | 97 |
self.flag_detected = False |
98 | 98 |
|
99 | 99 |
if self.flag_detected: |
100 |
- self.mask = cv2.resize(self.mask, (image.shape[0], image.shape[1])) |
|
100 |
+ print(image.shape) |
|
101 |
+ print(self.mask.shape) |
|
102 |
+ self.mask = cv2.resize(self.mask, (image.shape[1], image.shape[0])) # cv2 saves image with w,h order |
|
103 |
+ self.mask = self.mask[..., np.newaxis] |
|
104 |
+ print(self.mask.shape) |
|
101 | 105 |
self.mask_blob = cv2.imencode('.png', self.mask) |
102 | 106 |
self.mask_blob = self.mask.tobytes() |
103 | 107 |
self.seg_image = overlay_mask(image, self.mask[:,:,0], color=(0, 255, 0), alpha=0.3) |
... | ... | @@ -124,50 +128,50 @@ |
124 | 128 |
} |
125 | 129 |
session = requests.Session() |
126 | 130 |
|
127 |
- # try: |
|
128 |
- if self.flag_detected: |
|
129 |
- seg_binary = cv2.imencode('.png', self.seg_image) |
|
130 |
- seg_binary = seg_binary[1].tobytes() |
|
131 |
- multipart_data = MultipartEncoder( |
|
132 |
- fields={ |
|
133 |
- 'image': ( |
|
134 |
- f'frame_{self.cctv_name}.{self.image_type}', |
|
135 |
- self.image, |
|
136 |
- f'image/{self.image_type}' |
|
137 |
- ), |
|
138 |
- 'mask' : ( |
|
139 |
- f'frame_mask_{self.cctv_name}.{self.image_type}', |
|
140 |
- self.mask_blob, |
|
141 |
- f'image/{self.image_type}' |
|
142 |
- ), |
|
143 |
- 'seg_mask' : ( |
|
144 |
- f'frame_seg_{self.cctv_name}.{self.image_type}', |
|
145 |
- seg_binary, |
|
146 |
- f'image/{self.image_type}' |
|
147 |
- ) |
|
148 |
- } |
|
149 |
- ) |
|
150 |
- header["Content-Type"] = multipart_data.content_type |
|
151 |
- response = session.post(self.endpoint, headers=header, data=multipart_data) |
|
152 |
- print(response) |
|
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 |
- ) |
|
163 |
- header["Content-Type"] = multipart_data.content_type |
|
164 |
- response = session.post(self.endpoint, headers=header, data=multipart_data) |
|
165 |
- print(response) |
|
131 |
+ try: |
|
132 |
+ if self.flag_detected: |
|
133 |
+ seg_binary = cv2.imencode('.png', self.seg_image) |
|
134 |
+ seg_binary = seg_binary[1].tobytes() |
|
135 |
+ multipart_data = MultipartEncoder( |
|
136 |
+ fields={ |
|
137 |
+ 'image': ( |
|
138 |
+ f'frame_{self.cctv_name}.{self.image_type}', |
|
139 |
+ self.image, |
|
140 |
+ f'image/{self.image_type}' |
|
141 |
+ ), |
|
142 |
+ 'mask' : ( |
|
143 |
+ f'frame_mask_{self.cctv_name}.{self.image_type}', |
|
144 |
+ self.mask_blob, |
|
145 |
+ f'image/{self.image_type}' |
|
146 |
+ ), |
|
147 |
+ 'seg_mask' : ( |
|
148 |
+ f'frame_seg_{self.cctv_name}.{self.image_type}', |
|
149 |
+ seg_binary, |
|
150 |
+ f'image/{self.image_type}' |
|
151 |
+ ) |
|
152 |
+ } |
|
153 |
+ ) |
|
154 |
+ header["Content-Type"] = multipart_data.content_type |
|
155 |
+ response = session.post(self.endpoint, headers=header, data=multipart_data) |
|
156 |
+ print(response) |
|
157 |
+ else: |
|
158 |
+ multipart_data = MultipartEncoder( |
|
159 |
+ fields={ |
|
160 |
+ 'image': ( |
|
161 |
+ f'frame_{self.cctv_name}.{self.image_type}', |
|
162 |
+ self.image, |
|
163 |
+ f'image/{self.image_type}' |
|
164 |
+ ), |
|
165 |
+ } |
|
166 |
+ ) |
|
167 |
+ header["Content-Type"] = multipart_data.content_type |
|
168 |
+ response = session.post(self.endpoint, headers=header, data=multipart_data) |
|
169 |
+ print(response) |
|
166 | 170 |
|
167 |
- # except Exception as e: |
|
168 |
- # print(e) |
|
169 |
- # print("Can not connect to the postprocessing server. Check the endpoint address or connection.\n" |
|
170 |
- # f"Can not connect to : {self.endpoint}") |
|
171 |
+ except Exception as e: |
|
172 |
+ print(e) |
|
173 |
+ print("Can not connect to the postprocessing server. Check the endpoint address or connection.\n" |
|
174 |
+ f"Can not connect to : {self.endpoint}") |
|
171 | 175 |
|
172 | 176 |
|
173 | 177 |
if __name__ == '__main__': |
--- postprocess_draft.py
+++ postprocess_draft.py
... | ... | @@ -13,6 +13,8 @@ |
13 | 13 |
|
14 | 14 |
# from config_files import API_ENDPOINT_MAIN |
15 | 15 |
|
16 |
+debug = True |
|
17 |
+ |
|
16 | 18 |
app = Flask(__name__) |
17 | 19 |
api = Api(app, version='1.0', title='CCTV Image Upload API', |
18 | 20 |
description='A postprocessing and adaptive rate mainserver data pusher') |
... | ... | @@ -52,8 +54,11 @@ |
52 | 54 |
self.failure_mode_thres = failure_mode_thres |
53 | 55 |
self.failure_mode_check_past_n = failure_mode_check_past_n |
54 | 56 |
self.normal_mode_thres = normal_mode_thres |
57 |
+ self.normal_mode_check_past_n = normal_mode_check_past_n |
|
58 |
+ |
|
55 | 59 |
|
56 | 60 |
def __setitem__(self, key, value): |
61 |
+ print(self.sources.keys) |
|
57 | 62 |
if key not in self.sources: |
58 | 63 |
self.sources[key] = { |
59 | 64 |
"status_counts": [], |
... | ... | @@ -62,7 +67,10 @@ |
62 | 67 |
"most_recent_image" : None, |
63 | 68 |
"most_recent_mask" : None, |
64 | 69 |
"most_recent_seg_iamge" : None, |
65 |
- "cctv_name" : value, |
|
70 |
+ "cctv_info" : value, |
|
71 |
+ "last_send_before" : 0, |
|
72 |
+ "normal_to_failure_mode_change_alert" : False, |
|
73 |
+ "failure_to_normal_mode_change_alert" : False |
|
66 | 74 |
} |
67 | 75 |
else : |
68 | 76 |
raise KeyError(f"Error! Source {key} already initialized.") |
... | ... | @@ -71,42 +79,78 @@ |
71 | 79 |
def __getitem__(self, key): |
72 | 80 |
return self.sources[key] |
73 | 81 |
|
82 |
+ def __call__(self): |
|
83 |
+ return self.sources |
|
84 |
+ |
|
74 | 85 |
def add_status(self, source, status): |
75 | 86 |
assert status in ["OK", "FAIL"], f"Invalid status was given!, status must be one of 'OK' or 'FAIL', but given '{status}'!" |
76 | 87 |
|
77 | 88 |
if source not in self.sources: |
78 | 89 |
raise ValueError(f"No key found for source. Did you forgot to add it? \n source : {source}") |
79 | 90 |
|
80 |
- self.sources[source]["status_counts"].append(status) |
|
91 |
+ flag_send_event = False |
|
92 |
+ |
|
93 |
+ status_value = 1 if status == "OK" else 0 |
|
94 |
+ self.sources[source]["status_counts"].append(status_value) |
|
81 | 95 |
if len(self.sources[source]["status_counts"]) > self.buffer_size: |
82 | 96 |
self.sources[source]["status_counts"].pop(0) |
83 |
- |
|
84 |
- # Your existing logic for updating counts and checking statuses |
|
85 |
- if status == 'OK': |
|
86 |
- self.sources[source]["ok_counts"] += 1 |
|
87 |
- if self.sources[source]["force_send_mode"] and self.sources[source]["ok_counts"] >= self.normal_mode_thres: |
|
97 |
+ |
|
98 |
+ |
|
99 |
+ if self.sources[source]["force_send_mode"]: |
|
100 |
+ seek_n_recent_memory = min(len(self.sources[source]["status_counts"]), self.failure_mode_check_past_n) |
|
101 |
+ failure_counts = (self.failure_mode_check_past_n |
|
102 |
+ - sum(self.sources[source]["status_counts"][seek_n_recent_memory])) |
|
103 |
+ ok_counts = self.failure_mode_check_past_n - failure_counts |
|
104 |
+ flag_send_event = True |
|
105 |
+ |
|
106 |
+ # mode switching condition check |
|
107 |
+ if ok_counts >= self.normal_mode_thres: |
|
88 | 108 |
self.sources[source]["force_send_mode"] = False |
89 |
- self.send_message(source, "NORMAL SEND") |
|
109 |
+ flag_send_event = False |
|
110 |
+ self.sources[source]["failure_to_normal_mode_change_alert"] = True |
|
111 |
+ |
|
112 |
+ |
|
90 | 113 |
else: |
91 |
- self.sources[source]["ok_counts"] = 0 # Reset on FAIL |
|
92 |
- self.check_failures(source) |
|
114 |
+ seek_n_recent_memory = min(len(self.sources[source]["status_counts"]), self.normal_mode_check_past_n) |
|
115 |
+ failure_counts = (self.normal_mode_check_past_n |
|
116 |
+ - sum(self.sources[source]["status_counts"][:seek_n_recent_memory])) |
|
117 |
+ # ok_counts = self.normal_mode_check_past_n - failure_counts |
|
93 | 118 |
|
94 |
- def check_failures(self, source): |
|
95 |
- if self.switching_fail_consecutive_mode: |
|
96 |
- if (len(self.sources[source]["status_counts"]) >= self.failure_mode_thres |
|
97 |
- and all(status == 'FAIL' for status in self.sources[source]["status_counts"][-self.failure_mode_thres:])): |
|
98 |
- print(f"Source {source} has 5 consecutive FAILs!") |
|
119 |
+ # mode switching condition check |
|
120 |
+ if failure_counts >= self.normal_mode_thres: |
|
99 | 121 |
self.sources[source]["force_send_mode"] = True |
100 |
- self.send_message(source, "FORCE SEND") |
|
101 |
- else : |
|
102 |
- pass |
|
122 |
+ flag_send_event = True |
|
123 |
+ self.sources[source]["normal_to_failure_mode_change_alert"] = True |
|
103 | 124 |
|
104 |
- def send_message(self, source, message_type): |
|
105 |
- print(f"Sending message for {source} - Status: {message_type}") |
|
106 |
- # Reset the count after sending message |
|
107 |
- self.sources[source]["ok_counts"] = 0 |
|
125 |
+ if self.sources[source]["last_send_before"] > self.normal_send_interval: |
|
126 |
+ flag_send_event =True |
|
127 |
+ else : |
|
128 |
+ self.sources[source]["last_send_before"] += 1 |
|
129 |
+ |
|
130 |
+ if flag_send_event: |
|
131 |
+ self.send_event(source) |
|
132 |
+ |
|
133 |
+ # alert only alarms once |
|
134 |
+ if self.sources[source]["failure_to_normal_mode_change_alert"]: |
|
135 |
+ self.sources[source]["failure_to_normal_mode_change_alert"] = False |
|
136 |
+ |
|
137 |
+ if self.sources[source]["normal_to_failure_mode_change_alert"]: |
|
138 |
+ self.sources[source]["normal_to_failure_mode_change_alert"] = False |
|
139 |
+ |
|
140 |
+ def send_event(self, source): |
|
141 |
+ self.sources[source]["last_send_before"] = 0 |
|
142 |
+ print(f"EVENT : SENDING {source}!!") |
|
143 |
+ pass |
|
108 | 144 |
|
109 | 145 |
|
146 |
+memory = StreamSources( |
|
147 |
+ buffer_size=15, |
|
148 |
+ normal_send_interval=10, |
|
149 |
+ failure_mode_thres=8, |
|
150 |
+ failure_mode_check_past_n=12, |
|
151 |
+ normal_mode_thres=8, |
|
152 |
+ normal_mode_check_past_n=12, |
|
153 |
+ ) |
|
110 | 154 |
@ns.route('/postprocess', ) |
111 | 155 |
class PostProcesser(Resource): |
112 | 156 |
def __init__(self, *args, **kargs): |
... | ... | @@ -123,14 +167,6 @@ |
123 | 167 |
self.seg_image = None |
124 | 168 |
self.area_percent = 0 |
125 | 169 |
self.detected = False |
126 |
- self.memory = StreamSources( |
|
127 |
- buffer_size=15, |
|
128 |
- normal_send_interval=10, |
|
129 |
- failure_mode_thres=8, |
|
130 |
- failure_mode_check_past_n=12, |
|
131 |
- normal_mode_thres=8, |
|
132 |
- normal_mode_check_past_n=12, |
|
133 |
- ) |
|
134 | 170 |
pass |
135 | 171 |
|
136 | 172 |
@ns.response(200, 'Success') |
... | ... | @@ -160,12 +196,12 @@ |
160 | 196 |
self.image = request.files.get('image') |
161 | 197 |
self.mask = request.files.get('mask') |
162 | 198 |
self.seg_image = request.files.get('seg_mask') |
163 |
- self.image.save(f"network_test/image_p{time.time()}.png") |
|
164 |
- self.mask.save(f"network_test/mask_p{time.time()}.png") |
|
165 |
- self.seg_image.save(f"network_test/seg_p{time.time()}.png") |
|
166 | 199 |
|
167 |
- if not self.image or not self.mask or not self.seg_image: |
|
168 |
- raise ValueError("Missing one or more required files: 'image', 'mask', 'seg_mask'") |
|
200 |
+ if debug: |
|
201 |
+ self.image.save(f"network_test/image_p{time.time()}.png") |
|
202 |
+ if self.detected : |
|
203 |
+ self.mask.save(f"network_test/mask_p{time.time()}.png") |
|
204 |
+ self.seg_image.save(f"network_test/seg_p{time.time()}.png") |
|
169 | 205 |
|
170 | 206 |
self.time_sent = time.time() |
171 | 207 |
|
... | ... | @@ -178,10 +214,15 @@ |
178 | 214 |
'seg_frame': self.seg_image, |
179 | 215 |
'time_sent': self.time_sent |
180 | 216 |
} |
181 |
- |
|
182 |
- self.memory[self.cctv_info['cctv_name']] = self.cctv_info |
|
217 |
+ # if self.cctv_name in memory: |
|
218 |
+ try : |
|
219 |
+ memory[self.cctv_info['cctv_name']] = self.cctv_info |
|
220 |
+ except : |
|
221 |
+ pass |
|
183 | 222 |
pass_fail = self.pass_fail() |
184 |
- self.memory.add_status(self.cctv_name, pass_fail) |
|
223 |
+ memory.add_status(self.cctv_name, pass_fail) |
|
224 |
+ if debug: |
|
225 |
+ print(memory()) |
|
185 | 226 |
|
186 | 227 |
except ValueError as e: |
187 | 228 |
print(e) |
--- yoloseg/inference_.py
+++ yoloseg/inference_.py
... | ... | @@ -12,7 +12,7 @@ |
12 | 12 |
self.cuda_enabled = run_with_cuda |
13 | 13 |
self.letter_box_for_square = True |
14 | 14 |
self.model_score_threshold = 0.3 |
15 |
- self.model_nms_threshold = 0.5 |
|
15 |
+ self.model_nms_threshold = 0.6 |
|
16 | 16 |
self.classes = [] |
17 | 17 |
|
18 | 18 |
self.load_onnx_network() |
... | ... | @@ -222,7 +222,8 @@ |
222 | 222 |
# Path to your ONNX model and classes text file |
223 | 223 |
model_path = 'yoloseg/weight/best.onnx' |
224 | 224 |
classes_txt_file = 'config_files/yolo_config.txt' |
225 |
- image_path = 'yoloseg/img3.jpg' |
|
225 |
+ # image_path = 'yoloseg/img3.jpg' |
|
226 |
+ image_path = 'testing.png' |
|
226 | 227 |
|
227 | 228 |
model_input_shape = (640, 640) |
228 | 229 |
inference_engine = Inference( |
... | ... | @@ -261,7 +262,7 @@ |
261 | 262 |
|
262 | 263 |
# If you also want to display segmentation maps, you would need additional handling here |
263 | 264 |
# Example for displaying first mask if available: |
264 |
- if mask_maps is not None: |
|
265 |
+ if len(mask_maps) != 0: |
|
265 | 266 |
|
266 | 267 |
seg_image = overlay_mask(img, mask_maps[:,:,0], color=(0, 255, 0), alpha=0.3) |
267 | 268 |
cv2.imshow("segmentation", seg_image) |
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?