optimize code in Example app
[ealt-edge.git] / example-apps / ROBO / aPaaS / Obj_Detection_service / detection / obj_detection_service.py
1 #
2 # Copyright 2020 Huawei Technologies Co., Ltd.
3 #
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
7 #
8 #     http://www.apache.org/licenses/LICENSE-2.0
9 #
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.
15 #
16
17
18 import os
19 import cv2
20 import config
21 from flask_sslify import SSLify
22 from flask import Flask, request, jsonify, Response
23 from flask_cors import CORS
24 from werkzeug import secure_filename
25
26
27 class model_info():
28     def __init__(self, model_name):
29         self.model = 'model_info/MobileNetSSD_deploy.caffemodel'
30         self.model_name = model_name
31         self.prototxt = 'model_info/MobileNetSSD_deploy.prototxt'
32         self.confidenceLevel = 80
33
34     def get_model(self):
35         return self.model
36
37     def get_prototxt(self):
38         return self.prototxt
39
40     def get_model_name(self):
41         return self.model_name
42
43     def set_confidence_level(self, confidenceLevel):
44         self.confidenceLevel = confidenceLevel
45
46     def get_confidence_level(self):
47         return self.confidenceLevel
48
49     def update_model(self, model, prototxt, model_name):
50         self.prototxt = prototxt
51         self.model = model
52         self.model_name = model_name
53
54
55 # Labels of Network.
56 classNames = {0: 'background',
57               1: 'aeroplane', 2: 'bicycle', 3: 'bird', 4: 'boat',
58               5: 'bottle', 6: 'bus', 7: 'car', 8: 'cat', 9: 'chair',
59               10: 'cow', 11: 'diningtable', 12: 'dog', 13: 'horse',
60               14: 'motorbike', 15: 'person', 16: 'pottedplant',
61               17: 'sheep', 18: 'sofa', 19: 'train', 20: 'tvmonitor'}
62
63
64 app = Flask(__name__)
65 CORS(app)
66 sslify = SSLify(app)
67 app.config['JSON_AS_ASCII'] = False
68 app.config['UPLOAD_PATH'] = '/usr/app/images/'
69 app.config['supports_credentials'] = True
70 app.config['CORS_SUPPORTS_CREDENTIALS'] = True
71 app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024
72 ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg'])
73 count = 0
74 listOfMsgs = []
75
76
77 def allowed_file(filename):
78     return '.' in filename and filename.rsplit('.', 1)[1].lower() \
79        in ALLOWED_EXTENSIONS
80
81
82 # Obj-detection from input frame
83 def Detection(img):
84
85     modelInfo = model_info("caffe")
86     ConfPercent = modelInfo.get_confidence_level()
87     model = modelInfo.get_model()
88     prototxt = modelInfo.get_prototxt()
89
90     model = '/home/root1/My_Work/Akraino/MEC_BP/Rel4/Retail-apps/aPaaS/' \
91             'src/Obj_Detection_service/' + 'MobileNetSSD_deploy.caffemodel'
92
93     prototxt = '/home/root1/My_Work/Akraino/MEC_BP/Rel4/Retail-apps/aPaaS/' \
94                'src/Obj_Detection_service/' + 'MobileNetSSD_deploy.prototxt'
95     print(ConfPercent)
96     print(model)
97     print(prototxt)
98
99     # Load the Caffe model
100     net = cv2.dnn.readNetFromCaffe(prototxt, model)
101     # Load image fro
102     frame = cv2.imread('/home/root1/My_Work/Akraino/MEC_BP/Rel4/Retail-apps/'
103                        'aPaaS/src/Obj_Detection_service/images/' + img)
104     print('/home/root1/My_Work/Akraino/MEC_BP/Rel4/Retail-apps/aPaaS/'
105           'src/Obj_Detection_service/images/' + img)
106     frame_resized = cv2.resize(frame, (300, 300))  # resize frame for
107     # prediction
108     heightFactor = frame.shape[0]/300.0
109     widthFactor = frame.shape[1]/300.0
110
111     # MobileNet requires fixed dimensions for input image(s)
112     # so we have to ensure that it is resized to 300x300 pixels.
113     # set a scale factor to image because network the objects has
114     # differents size.
115     # We perform a mean subtraction (127.5, 127.5, 127.5)
116     # to normalize the input;
117     # after executing this command our "blob" now has the shape:
118     # (1, 3, 300, 300)
119     blob = cv2.dnn.blobFromImage(frame_resized, 0.007843, (300, 300),
120                                  (127.5, 127.5, 127.5), False)
121     # Set to network the input blob
122     net.setInput(blob)
123     # Prediction of network
124     detections = net.forward()
125
126     frame_copy = frame.copy()
127     # Size of frame resize (300x300)
128     cols = frame_resized.shape[1]
129     rows = frame_resized.shape[0]
130
131     # For get the class and location of object detected,
132     # There is a fix index for class, location and confidence
133     # value in @detections array .
134     for i in range(detections.shape[2]):
135         confidence = detections[0, 0, i, 2]  # Confidence of prediction
136         if confidence > ConfPercent:  # Filter prediction
137             class_id = int(detections[0, 0, i, 1])  # Class label
138
139             # Object location
140             xLeftBottom = int(detections[0, 0, i, 3] * cols)
141             yLeftBottom = int(detections[0, 0, i, 4] * rows)
142             xRightTop = int(detections[0, 0, i, 5] * cols)
143             yRightTop = int(detections[0, 0, i, 6] * rows)
144
145             xLeftBottom_ = int(widthFactor * xLeftBottom)
146             yLeftBottom_ = int(heightFactor * yLeftBottom)
147             xRightTop_ = int(widthFactor * xRightTop)
148             yRightTop_ = int(heightFactor * yRightTop)
149             # Draw location of object
150             cv2.rectangle(frame_resized, (xLeftBottom, yLeftBottom),
151                           (xRightTop, yRightTop),
152                           (0, 255, 0))
153
154             cv2.rectangle(frame_copy, (xLeftBottom_, yLeftBottom_),
155                           (xRightTop_, yRightTop_),
156                           (0, 255, 0), -1)
157     opacity = 0.3
158     cv2.addWeighted(frame_copy, opacity, frame, 1 - opacity, 0, frame)
159
160     count = 0
161     for i in range(detections.shape[2]):
162         confidence = detections[0, 0, i, 2]  # Confidence of prediction
163         if confidence > ConfPercent:  # Filter prediction
164             class_id = int(detections[0, 0, i, 1])  # Class label
165
166             # Object location
167             xLeftBottom = int(detections[0, 0, i, 3] * cols)
168             yLeftBottom = int(detections[0, 0, i, 4] * rows)
169             xRightTop = int(detections[0, 0, i, 5] * cols)
170             yRightTop = int(detections[0, 0, i, 6] * rows)
171
172             xLeftBottom_ = int(widthFactor * xLeftBottom)
173             yLeftBottom_ = int(heightFactor * yLeftBottom)
174             xRightTop_ = int(widthFactor * xRightTop)
175             yRightTop_ = int(heightFactor * yRightTop)
176             cv2.rectangle(frame, (xLeftBottom_, yLeftBottom_),
177                           (xRightTop_, yRightTop_),
178                           (0, 0, 0), 2)
179
180             # Draw label and confidence of prediction in frame resized
181             if class_id in classNames:
182                 label = classNames[class_id] + ": " + str(confidence)
183                 labelSize, baseLine = cv2.getTextSize(label,
184                                                       cv2.FONT_HERSHEY_TRIPLEX,
185                                                       0.8, 1)
186
187                 yLeftBottom_ = max(yLeftBottom_, labelSize[1])
188                 cv2.rectangle(
189                     frame,
190                     (xLeftBottom_, yLeftBottom_ - labelSize[1]),
191                     (xLeftBottom_ + labelSize[0], yLeftBottom_ + baseLine),
192                     (255, 255, 255), cv2.FILLED)
193                 cv2.putText(frame, label, (xLeftBottom_, yLeftBottom_),
194                             cv2.FONT_HERSHEY_TRIPLEX, 0.8, (0, 0, 0))
195                 print(label)
196                 count = count + 1
197
198     print("total item count", count)
199     cv2.namedWindow("frame", cv2.WINDOW_NORMAL)
200     cv2.imwrite("/home/root1/My_Work/Akraino/MEC_BP/tmp/1.jpeg", frame)
201     cv2.imshow("frame", frame)
202     cv2.waitKey(0)
203     cv2.destroyAllWindows()
204     # Detect_result = {'ImposedImage': 'frame', 'ObjCount': count,
205     # 'ObjType': type, 'Time': time}
206     Detect_result = {'ImposedImage': "frame", 'ObjCount': count,
207                      'labels': label}
208     return Detect_result
209
210
211 @app.route('/mep/v1/obj_detection/uploadModel', methods=['POST'])
212 def uploadModel():
213     """
214     upload model
215     :return: html file
216     """
217     app.logger.info("Received message from ClientIP [" + request.remote_addr
218                     + "] Operation [" + request.method + "]" +
219                     " Resource [" + request.url + "]")
220
221     modelInfo = model_info("caffe")
222     modelInfo.update_model("caffe", "mobilenet_ssd", "prototext")
223     return Response("success")
224
225
226 @app.route('/mep/v1/obj_detection/confidencelevel', methods=['POST'])
227 def setConfidenceLevel():
228     """
229     Trigger the video_feed() function on opening "0.0.0.0:5000/video_feed" URL
230     :return:
231     """
232     app.logger.info("Received message from ClientIP [" + request.remote_addr
233                     + "] Operation [" + request.method + "]" +
234                     " Resource [" + request.url + "]")
235
236     confidenceLevel = 80
237     modelInfo = model_info("caffe")
238     modelInfo.set_confidence_level(confidenceLevel)
239     return Response("success")
240
241
242 @app.route('/mep/v1/obj_detection/detect', methods=['GET'])
243 def Obj_Detection():
244     """
245     Trigger the Obj detection on input frame/image
246     Input: frame/image
247     :return: imposed frame, count, Obj type, time taken by detection
248     """
249     app.logger.info("Received message from ClientIP [" + request.remote_addr
250                     + "] Operation [" + request.method + "]" +
251                     " Resource [" + request.url + "]")
252
253     if 'file' not in request.files:
254         raise IOError('No file')
255
256     file = request.files['file']
257     if file.filename == '':
258         app.logger.info('No file selected for uploading')
259         raise IOError('No file')
260     if file and allowed_file(file.filename):
261         filename = secure_filename(file.filename)
262         file.save(os.path.join(app.config['UPLOAD_PATH'], filename))
263         app.logger.info('File successfully uploaded')
264         Detect_result = Detection(filename)
265     else:
266         app.logger.info('Allowed file types are txt, pdf, png, jpg, jpeg, gif')
267         return Response("failure")
268     return jsonify(Detect_result)
269
270
271 def start_server(handler):
272     app.logger.addHandler(handler)
273     if config.ssl_enabled:
274         context = (config.ssl_certfilepath, config.ssl_keyfilepath)
275         app.run(host=config.server_address, debug=True, ssl_context=context,
276                 threaded=True, port=config.server_port)
277     else:
278         app.run(host=config.server_address, debug=True, threaded=True,
279                 port=config.server_port)