2 # Copyright 2020 Huawei Technologies Co., Ltd.
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
18 from flask_sslify import SSLify
19 from flask import Flask, request, jsonify, Response
20 from flask_cors import CORS
21 # from camera_driver.capture_frame import VideoCamera, VideoFile
22 # from capture_frame import VideoCamera, VideoFile
23 # from influxdb import InfluxDBClient
34 app.config['JSON_AS_ASCII'] = False
35 app.config['UPLOAD_PATH'] = '/usr/app/images/'
36 app.config['supports_credentials'] = True
37 app.config['CORS_SUPPORTS_CREDENTIALS'] = True
38 app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024
39 ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg'])
40 ALLOWED_VIDEO_EXTENSIONS = {'mp4'}
50 Store the data and manage multiple input video feeds
52 def __init__(self, current_count=0, total_count=0, time=0):
53 self.type = "Shelf_INV1"
54 self.labels = "Bottles"
55 self.current_count = current_count
56 self.total_count = total_count
59 def setcurrentcount(self, current_count):
60 self.current_count = current_count
62 def settotalcount(self, total_count):
63 self.total_count = total_count
65 def getcurrentcount(self):
66 return self.current_count
68 def gettotalcount(self):
69 return self.total_count
71 def setlabel(self, labels):
77 def settime(self, time):
84 # temporary copied capture_frame file to this due to docker issue for module
87 class VideoCamera(object):
89 opneCV to capture frame from a camera
91 def __init__(self, url):
92 self.video = cv2.VideoCapture(url)
99 get a frame from camera url
101 success, image = self.video.read()
102 return success, image
105 class VideoFile(object):
107 opneCV to capture frame from a video stream
109 def __init__(self, video_name):
110 self.video = cv2.VideoCapture("./test/resources/" + video_name)
117 get a frane from stream
119 success, image = self.video.read()
120 return success, image
123 def store_data(inventory_info):
125 store time series data in influx db
127 # TODO config, schema table, DB, fill data set
129 store_info_db(inventory_info)
132 def mock_table(inven_info):
136 inven_info.setcurrentcount(current_count)
137 inven_info.settotalcount(total_count)
138 inven_info.setlabel(labels)
139 inven_info.utime = time.time()
140 # store_data(inven_info)
141 local_store(inven_info)
144 def shelf_inventory(video_capture, camera_info, true=None):
152 process_this_frame = 0
154 inven_info = inventory_info()
155 mock_table(inven_info)
158 success, frame = video_capture.get_frame()
161 if process_this_frame == 0:
162 url = config.detection_url + "/v1/obj_detection/detect"
163 # info1 = cv2.imencode(".jpg", rgb_small_frame)[1].tobytes()
164 data = json.loads(requests.post
166 verify=config.ssl_cacertpath).text)
167 inven_info = inventory_info()
168 current_count = data[count]
169 labels = data[labels]
170 total_count = inven_info.current_count + inven_info.total_count
171 inven_info.setcurrentcount(current_count)
172 inven_info.settotalcount(total_count)
173 inven_info.setlabel(labels)
174 inven_info.utime = time.time()
175 # store_data(inven_info)
176 local_store(inven_info)
179 def local_store(inven_info):
181 store "shelf" data to array
183 :param inven_info: Inventry object
186 if len(listOfMsgs) >= 100:
188 newdict = {"shelfName": inven_info.type, "ObjType": inven_info.labels,
189 "currentCount": inven_info.current_count,
190 "totalCount": inven_info.total_count,
192 listOfMsgs.insert(0, newdict)
195 def store_info_db(inven_info):
197 Send "shelf" data to InfluxDB
199 :param inven_info: Inventry object
205 "measurement": inven_info.type,
210 "time": inven_info.time,
211 "Current Count": inven_info.current_count,
212 "Total Count": inven_info.total_count,
215 db_client.write_points(json_body)
218 def create_database():
220 Connect to InfluxDB and create the database
225 # proxy = {"http": "http://{}:{}".format(config.IPADDRESS, config.PORT)}
226 # db_client = InfluxDBClient(host=config.IPADDRESS, port=config.PORT,
227 # proxies=proxy, database=config.DATABASE_NAME)
228 # db_client.create_database(config.DATABASE_NAME)
231 @app.route('/v1/inventry/table', methods=['GET'])
232 def inventry_table():
234 return inventry table
236 :return: inventry table
238 return jsonify(listOfMsgs)
241 @app.route('/v1/inventry/image', methods=['GET'])
242 def detected_image():
244 return inventry table
246 :return: inventry table
248 return jsonify(listOfMsgs)
251 def allowed_videofile(filename):
253 File types to upload:mp4
256 return '.' in filename and \
257 filename.rsplit('.', 1)[1].lower() in ALLOWED_VIDEO_EXTENSIONS
260 @app.route('/v1/monitor/video', methods=['POST'])
262 app.logger.info("Received message from ClientIP [" + request.remote_addr
263 + "] Operation [" + request.method + "]" +
264 " Resource [" + request.url + "]")
265 if 'file' in request.files:
266 files = request.files.getlist("file")
268 if allowed_videofile(file.filename):
269 file.save(os.path.join(app.config['VIDEO_PATH'],
272 raise IOError('video format error')
273 return Response("success")
276 @app.route('/v1/monitor/cameras', methods=['POST'])
278 camera_info = request.json
279 app.logger.info("Received message from ClientIP [" + request.remote_addr
280 + "] Operation [" + request.method + "]" +
281 " Resource [" + request.url + "]")
282 camera_info = {"name": camera_info["name"],
283 "rtspurl": camera_info["rtspurl"],
284 "location": camera_info["location"]}
285 listOfCameras.append(camera_info)
286 return Response("success")
289 @app.route('/v1/monitor/cameras/<name>/<rtspurl>/<location>', methods=['GET'])
290 def get_camera(name, rtspurl, location):
292 register camera with location
294 app.logger.info("Received message from ClientIP [" + request.remote_addr
295 + "] Operation [" + request.method + "]" +
296 " Resource [" + request.url + "]")
297 camera_info = {"name": name, "rtspurl": rtspurl, "location": location}
298 if "mp4" in camera_info["rtspurl"]:
299 video_file = VideoFile(camera_info["rtspurl"])
300 video_dict = {camera_info["name"]: video_file}
301 listOfVideos.append(video_dict)
302 return Response(shelf_inventory(video_file, camera_info["name"]),
303 mimetype='multipart/x-mixed-replace; boundary=frame')
305 video_file = VideoCamera(camera_info["rtspurl"])
306 video_dict = {camera_info["name"]: video_file}
307 listOfVideos.append(video_dict)
308 return Response(shelf_inventory(video_file, camera_info["name"]),
309 mimetype='multipart/x-mixed-replace; boundary=frame')
312 @app.route('/v1/monitor/cameras/<camera_name>', methods=['DELETE'])
313 def delete_camera(camera_name):
314 app.logger.info("Received message from ClientIP [" + request.remote_addr
315 + "] Operation [" + request.method + "]" +
316 " Resource [" + request.url + "]")
317 for video1 in listOfVideos:
318 if camera_name in video1:
319 video_obj = video1[camera_name]
321 for camera in listOfCameras:
322 if camera_name == camera["name"]:
323 listOfCameras.remove(camera)
324 for msg in listOfMsgs:
325 if camera_name in msg["msg"]:
326 listOfMsgs.remove(msg)
327 return Response("success")
330 @app.route('/v1/monitor/cameras')
332 app.logger.info("Received message from ClientIP [" + request.remote_addr
333 + "] Operation [" + request.method + "]" +
334 " Resource [" + request.url + "]")
335 return jsonify(listOfCameras)
338 @app.route('/', methods=['GET'])
340 app.logger.info("Received message from ClientIP [" + request.remote_addr
341 + "] Operation [" + request.method + "]" +
342 " Resource [" + request.url + "]")
343 return Response("Hello MEC Developer")
346 def start_server(handler):
347 app.logger.addHandler(handler)
348 if config.ssl_enabled:
349 context = (config.ssl_certfilepath, config.ssl_keyfilepath)
350 app.run(host=config.server_address, debug=True, ssl_context=context,
351 threaded=True, port=config.server_port)
353 app.run(host=config.server_address, debug=True, threaded=True,
354 port=config.server_port)