example app backend code 49/4049/1
authorkhemendra kumar <khemendra.kumar@huawei.com>
Mon, 11 Jan 2021 11:55:30 +0000 (17:25 +0530)
committerkhemendra kumar <khemendra.kumar@huawei.com>
Mon, 11 Jan 2021 11:55:30 +0000 (17:25 +0530)
Signed-off-by: khemendra kumar <khemendra.kumar@huawei.com>
Change-Id: Ia20a5041dbff08a0e34350c41b86fde8c4f7abd0

example-apps/ROBO/retail_app/Dockerfile
example-apps/ROBO/retail_app/inventry/capture_frame.py [new file with mode: 0644]
example-apps/ROBO/retail_app/inventry/retail_app.py
example-apps/ROBO/retail_app/requirements.txt

index c84560a..3d76af3 100644 (file)
@@ -25,8 +25,9 @@ RUN sed -i "s|umask 022|umask 027|g" /etc/profile
 # Create the home directory for the new app user.
 RUN mkdir -p /usr/app
 RUN mkdir -p /usr/app/bin
-RUN mkdir -p /usr/app/detection
-RUN mkdir -p /usr/app/resources
+RUN mkdir -p /usr/app/inventry
+RUN mkdir -p /usr/app/test/resources
+RUN mkdir -p /usr/app/images
 
 # Set the home directory to our app user's home.
 ENV APP_HOME=/usr/app
@@ -69,9 +70,11 @@ WORKDIR $APP_HOME
 
 # Copy the application & scripts
 COPY config.py requirements.txt run.py $APP_HOME/
-COPY detection $APP_HOME/monitoring/
-COPY resources $APP_HOME/resources/
-COPY configs/*.sh $APP_HOME/bin
+COPY inventry $APP_HOME/inventry/
+COPY test $APP_HOME/test/
+COPY test/resources $APP_HOME/test/resources/
+#COPY configs/*.sh $APP_HOME/bin
+COPY configs/start.sh $APP_HOME/bin
 
 RUN chmod 750 $APP_HOME &&\
     chmod -R 550 $APP_HOME/bin &&\
@@ -80,7 +83,7 @@ RUN chmod 750 $APP_HOME &&\
     chown -R $USER_NAME:$GROUP_NAME $APP_HOME
 
 # Exposed port
-EXPOSE 9997
+EXPOSE 9996
 
 # Change to the app user.
 USER $USER_NAME
diff --git a/example-apps/ROBO/retail_app/inventry/capture_frame.py b/example-apps/ROBO/retail_app/inventry/capture_frame.py
new file mode 100644 (file)
index 0000000..eb66edc
--- /dev/null
@@ -0,0 +1,53 @@
+#
+# Copyright 2020 Huawei Technologies Co., Ltd.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+import cv2
+
+
+class VideoCamera(object):
+    """
+    opneCV to capture frame from a camera
+    """
+    def __init__(self, url):
+        self.video = cv2.VideoCapture(url)
+
+    def delete(self):
+        self.video.release()
+
+    def get_frame(self):
+        """
+        get a frame from camera url
+        """
+        success, image = self.video.read()
+        return success, image
+
+
+class VideoFile(object):
+    """
+    opneCV to capture frame from a video stream
+    """
+    def __init__(self, video_name):
+        self.video = cv2.VideoCapture("./test/resources/" + video_name)
+
+    def delete(self):
+        self.video.release()
+
+    def get_frame(self):
+        """
+        get a frane from stream
+        """
+        success, image = self.video.read()
+        return success, image
index 7de018e..e3f98d3 100644 (file)
@@ -18,11 +18,14 @@ import config
 from flask_sslify import SSLify
 from flask import Flask, request, jsonify, Response
 from flask_cors import CORS
-from camera_driver.capture_frame import VideoCamera, VideoFile
-from influxdb import InfluxDBClient
+# from camera_driver.capture_frame import VideoCamera, VideoFile
+# from capture_frame import VideoCamera, VideoFile
+# from influxdb import InfluxDBClient
 import json
 import time
 import requests
+import os
+import cv2
 
 
 app = Flask(__name__)
@@ -34,18 +37,20 @@ app.config['supports_credentials'] = True
 app.config['CORS_SUPPORTS_CREDENTIALS'] = True
 app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024
 ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg'])
+ALLOWED_VIDEO_EXTENSIONS = {'mp4'}
 count = 0
 listOfMsgs = []
 listOfCameras = []
 listOfVideos = []
+mock_func = 1
 
 
-class inventry_info:
+class inventory_info:
     """
     Store the data and manage multiple input video feeds
     """
     def __init__(self, current_count=0, total_count=0, time=0):
-        self.type = "Shelf_INV"
+        self.type = "Shelf_INV1"
         self.labels = "Bottles"
         self.current_count = current_count
         self.total_count = total_count
@@ -76,32 +81,90 @@ class inventry_info:
         return self.time
 
 
-def store_data(inventry_info):
+# temporary copied capture_frame file to this due to docker issue for module
+# import
+
+class VideoCamera(object):
+    """
+    opneCV to capture frame from a camera
+    """
+    def __init__(self, url):
+        self.video = cv2.VideoCapture(url)
+
+    def delete(self):
+        self.video.release()
+
+    def get_frame(self):
+        """
+        get a frame from camera url
+        """
+        success, image = self.video.read()
+        return success, image
+
+
+class VideoFile(object):
+    """
+    opneCV to capture frame from a video stream
+    """
+    def __init__(self, video_name):
+        self.video = cv2.VideoCapture("./test/resources/" + video_name)
+
+    def delete(self):
+        self.video.release()
+
+    def get_frame(self):
+        """
+        get a frane from stream
+        """
+        success, image = self.video.read()
+        return success, image
+
+
+def store_data(inventory_info):
     """
     store time series data in influx db
     """
     # TODO config, schema table, DB, fill data set
     create_database()
-    store_info_db(inventry_info)
+    store_info_db(inventory_info)
 
 
-def shelf_inventry(video_capture, camera_info):
+def mock_table(inven_info):
+    current_count = 3
+    labels = "Bottles"
+    total_count = 6
+    inven_info.setcurrentcount(current_count)
+    inven_info.settotalcount(total_count)
+    inven_info.setlabel(labels)
+    inven_info.utime = time.time()
+    # store_data(inven_info)
+    local_store(inven_info)
+
+
+def shelf_inventory(video_capture, camera_info, true=None):
     """
-    人脸识别
+    shelf_inventory
     """
     global count
+    global mock_func
+
     labels = "bottles"
     process_this_frame = 0
-    while True:
-        success, frame = video_capture.get_frame()
-        if not success:
-            break
-        if process_this_frame == 0:
-            url = config.detection_url + "/v1/obj_detection/detect"
-            # info1 = cv2.imencode(".jpg", rgb_small_frame)[1].tobytes()
-            data = json.loads(requests.post(url, data=frame,
-                                            verify=config.ssl_cacertpath).text)
-        inven_info = inventry_info()
+    if mock_func == 1:
+        inven_info = inventory_info()
+        mock_table(inven_info)
+    else:
+        while True:
+            success, frame = video_capture.get_frame()
+            if not success:
+                break
+            if process_this_frame == 0:
+                url = config.detection_url + "/v1/obj_detection/detect"
+                # info1 = cv2.imencode(".jpg", rgb_small_frame)[1].tobytes()
+                data = json.loads(requests.post
+                                  (url, data=frame,
+                                   verify=config.ssl_cacertpath).text)
+        inven_info = inventory_info()
         current_count = data[count]
         labels = data[labels]
         total_count = inven_info.current_count + inven_info.total_count
@@ -109,7 +172,24 @@ def shelf_inventry(video_capture, camera_info):
         inven_info.settotalcount(total_count)
         inven_info.setlabel(labels)
         inven_info.utime = time.time()
-        store_data(inven_info)
+        # store_data(inven_info)
+        local_store(inven_info)
+
+
+def local_store(inven_info):
+    """
+    store "shelf" data to array
+
+    :param inven_info: Inventry object
+    :return: None
+    """
+    if len(listOfMsgs) >= 100:
+        listOfMsgs.pop()
+    newdict = {"shelfName": inven_info.type, "ObjType": inven_info.labels,
+               "currentCount": inven_info.current_count,
+               "totalCount": inven_info.total_count,
+               "time": time.time()}
+    listOfMsgs.insert(0, newdict)
 
 
 def store_info_db(inven_info):
@@ -142,11 +222,55 @@ def create_database():
     :return: None
     """
     global db_client
+#    proxy = {"http": "http://{}:{}".format(config.IPADDRESS, config.PORT)}
+#    db_client = InfluxDBClient(host=config.IPADDRESS, port=config.PORT,
+#    proxies=proxy, database=config.DATABASE_NAME)
+#    db_client.create_database(config.DATABASE_NAME)
 
-    proxy = {"http": "http://{}:{}".format(config.IPADDRESS, config.PORT)}
-    db_client = InfluxDBClient(host=config.IPADDRESS, port=config.PORT,
-                               proxies=proxy, database=config.DATABASE_NAME)
-    db_client.create_database(config.DATABASE_NAME)
+
+@app.route('/v1/inventry/table', methods=['GET'])
+def inventry_table():
+    """
+    return inventry table
+
+    :return: inventry table
+    """
+    return jsonify(listOfMsgs)
+
+
+@app.route('/v1/inventry/image', methods=['GET'])
+def detected_image():
+    """
+    return inventry table
+
+    :return: inventry table
+    """
+    return jsonify(listOfMsgs)
+
+
+def allowed_videofile(filename):
+    """
+    File types to upload:mp4
+    param: filename:
+    """
+    return '.' in filename and \
+           filename.rsplit('.', 1)[1].lower() in ALLOWED_VIDEO_EXTENSIONS
+
+
+@app.route('/v1/monitor/video', methods=['POST'])
+def upload_video():
+    app.logger.info("Received message from ClientIP [" + request.remote_addr
+                    + "] Operation [" + request.method + "]" +
+                    " Resource [" + request.url + "]")
+    if 'file' in request.files:
+        files = request.files.getlist("file")
+        for file in files:
+            if allowed_videofile(file.filename):
+                file.save(os.path.join(app.config['VIDEO_PATH'],
+                                       file.filename))
+            else:
+                raise IOError('video format error')
+    return Response("success")
 
 
 @app.route('/v1/monitor/cameras', methods=['POST'])
@@ -175,13 +299,13 @@ def get_camera(name, rtspurl, location):
         video_file = VideoFile(camera_info["rtspurl"])
         video_dict = {camera_info["name"]: video_file}
         listOfVideos.append(video_dict)
-        return Response(shelf_inventry(video_file, camera_info["name"]),
+        return Response(shelf_inventory(video_file, camera_info["name"]),
                         mimetype='multipart/x-mixed-replace; boundary=frame')
     else:
         video_file = VideoCamera(camera_info["rtspurl"])
         video_dict = {camera_info["name"]: video_file}
         listOfVideos.append(video_dict)
-        return Response(shelf_inventry(video_file, camera_info["name"]),
+        return Response(shelf_inventory(video_file, camera_info["name"]),
                         mimetype='multipart/x-mixed-replace; boundary=frame')
 
 
@@ -209,7 +333,14 @@ def query_cameras():
                     + "] Operation [" + request.method + "]" +
                     " Resource [" + request.url + "]")
     return jsonify(listOfCameras)
-    return Response("success")
+
+
+@app.route('/', methods=['GET'])
+def hello_world():
+    app.logger.info("Received message from ClientIP [" + request.remote_addr
+                    + "] Operation [" + request.method + "]" +
+                    " Resource [" + request.url + "]")
+    return Response("Hello MEC Developer")
 
 
 def start_server(handler):
index 9e7cae3..dd037ca 100644 (file)
 # limitations under the License.
 #
 
-flask
-requests
+flask~=1.1.2
+requests~=2.18.4
 flask_sslify
 opencv-python
 flask_cors
+
+influxdb~=5.3.1
\ No newline at end of file