Beispiel #1
0
    def get_end2end_latency(self):
        key = "end2end-" + str(self.opt.drone_id)
        value = redis_get(self.rc_latency, key)
        # print("# Key, value = ", value)
        # if self.to_ms:
        #     value = value * 1000
        self.end2end = value

        self.save_to_csv('12_end2end_latency-w=%d.csv' % self.opt.num_workers,
                         [self.end2end])  # X is an array
Beispiel #2
0
    def get_stream_setup_latency(self):
        key = "stream-start-" + str(self.opt.drone_id)
        value = redis_get(self.rc_latency, key)
        # print("# Key, value = ", value)
        if self.to_ms:
            value = value * 1000
        self.stream_setup = value

        self.save_to_csv('01_stream_setup_latency-w=%d.csv' %
                         self.opt.num_workers,
                         [self.stream_setup])  # X is an array
Beispiel #3
0
    def get_yolo_nms_latency(self):
        self.yolo_nms = []
        # for idx in range (1, self.num_frames):
        for idx in range(1, (self.num_frames + 1)):
            key = "nms-" + str(self.opt.drone_id) + "-" + str(idx)
            value = redis_get(self.rc_latency, key)
            if self.to_ms:
                value = value * 1000
            # print("# Key[`%s`], value = " % key, value)
            self.yolo_nms.append(value)

        self.save_to_csv('08_yolo_nms_latency-w=%d.csv' % self.opt.num_workers,
                         self.yolo_nms)  # X is an array
Beispiel #4
0
    def __load_balancing(self, frame_id, ret, frame, save_path):
        # Initially, send process into first worker
        self.worker_id += 1
        # self.worker_id = 1
        stream_channel = common_settings["redis_config"][
            "channel_prefix"] + str(self.worker_id)

        # Check worker status first, please wait while still working
        # print(">>>>>> __worker_status = ", self.__worker_status())
        w = 0
        wait_time = self.wait_time
        if redis_get(self.rc_data, self.worker_id) is None:
            print("This worker is OFF. Nothing to do")
            print(
                "TBD next time: Should skip this worker and move to the next worker instead"
            )
            self.__find_optimal_worker()
        else:
            # None = DISABLED; 1=Ready; 0=Busy
            while self.__worker_status() == 0:
                # print("\nWorker-%d is still processing other image, waiting (%ds) ..." % (self.worker_id, w))
                # print("\nWorker-%d is still processing other image, waiting ... " % self.worker_id)
                # time.sleep(0.005)
                if not self.opt.disable_delay:
                    time.sleep(self.wait_time)
                w += self.wait_time

            # Send multi-process and set the worker as busy (value=False)
            print("### Sending the work into [worker-#%d] @ `%s`" %
                  ((self.worker_id), stream_channel))
            Process(target=frame_producer,
                    args=(
                        self.rc,
                        frame_id,
                        ret,
                        frame,
                        save_path,
                        stream_channel,
                        self.rc_latency,
                        self.opt.drone_id,
                    )).start()
            redis_set(self.rc_data, self.worker_id, 0)

        self.__reset_worker()
Beispiel #5
0
    def get_read_stream_latency(self):
        self.read2stream = []
        # for idx in range (1, self.num_frames):
        for idx in range(1, (self.num_frames + 1)):
            key = "frame-" + str(self.opt.drone_id) + "-" + str(idx)
            value = redis_get(self.rc_latency, key)

            if self.to_ms:
                value = value * 1000

                # Add end-to-end latency
                if self.opt.enable_e2e:
                    value += self.opt.avg_frame

            # print("# Key[`%s`], value = " % key, value)
            self.read2stream.append(value)

        self.save_to_csv('02_read_stream_latency-w=%d.csv' %
                         self.opt.num_workers,
                         self.read2stream)  # X is an array
Beispiel #6
0
    def __iterate_frames(self, this_frame_id=None):
        # Run inference
        self.t0 = time.time()
        # frame_id = 0
        for path, img, im0s, vid_cap in self.dataset:
            self.frame_id += 1
            t = time.time()

            # Get detections
            ts_det = time.time()
            img = torch.from_numpy(img).to(self.device)
            if img.ndimension() == 3:
                img = img.unsqueeze(0)
            self.pred = self.model(img)[0]
            # print('\n # Total Inference time: (%.3fs)' % (time.time() - ts_det))
            t_inference = time.time() - ts_det
            self.time_inference += t_inference
            self.time_inference_list.append(t_inference)

            # Latency: Inference
            print('\nLatency [Inference] of frame-%s: (%.5fs)' %
                  (str(this_frame_id), t_inference))
            t_inference_key = "inference-" + str(
                self.opt.drone_id) + "-" + str(this_frame_id)
            redis_set(self.rc_latency, t_inference_key, t_inference)

            # Default: Disabled
            if self.opt.half:
                self.pred = self.pred.float()

            # Apply NMS: Non-Maximum Suppression
            ts_nms = time.time()
            # to Removes detections with lower object confidence score than 'conf_thres'
            self.pred = non_max_suppression(self.pred,
                                            self.opt.conf_thres,
                                            self.opt.iou_thres,
                                            classes=self.opt.classes,
                                            agnostic=self.opt.agnostic_nms)
            # print('\n # Total Non-Maximum Suppression (NMS) time: (%.3fs)' % (time.time() - ts_nms))
            t_nms = time.time() - ts_nms
            self.time_nms += t_nms
            self.time_nms_list.append(t_nms)

            # Latency: NMS
            print('\nLatency [NMS] of frame-%s: (%.5fs)' %
                  (str(this_frame_id), t_nms))
            t_nms_key = "nms-" + str(
                self.opt.drone_id) + "-" + str(this_frame_id)
            redis_set(self.rc_latency, t_nms_key, t_nms)

            # Apply Classifier: Default DISABLED
            if self.classify:
                self.pred = apply_classifier(self.pred, self.modelc, img, im0s)

            # Process detections
            '''
            p = path
            s = string for printing
            im0 = image (matrix)
            '''

            for i, det in enumerate(self.pred):  # detections per image
                if self.webcam:  # batch_size >= 1
                    p, self.str_output, im0 = path[i], '%g: ' % i, im0s[i]
                else:
                    p, self.str_output, im0 = path, '', im0s

                self.save_path = str(Path(self.out) / Path(p).name)
                self.str_output += '%gx%g ' % img.shape[2:]  # print string
                if det is not None and len(det):
                    # Rescale boxes from img_size to im0 size
                    det[:, :4] = scale_coords(img.shape[2:], det[:, :4],
                                              im0.shape).round()

                    ts_mbbox = time.time()
                    if self.mbbox_algorithm:
                        self.__mbbox_detection(det, im0)  # modifying Mb-box
                    t_mbbox = time.time() - ts_mbbox
                    self.time_mbbox += t_mbbox
                    self.time_mbbox_list.append(t_mbbox)

                    # Latency: MB-Box
                    print('\nLatency [MB-Box Algorithm] of frame-%s: (%.5fs)' %
                          (str(this_frame_id), t_mbbox))
                    t_mbbox_key = "mbbox-" + str(
                        self.opt.drone_id) + "-" + str(this_frame_id)
                    redis_set(self.rc_latency, t_mbbox_key, t_mbbox)

                    ts_default = time.time()
                    if not self.opt.maximize_latency:
                        if self.default_algorithm:
                            self.__default_detection(det, im0)
                    t_default = time.time() - ts_default
                    self.time_default += t_default
                    self.time_default_list.append(t_default)

                    # Latency: Default Detection
                    print(
                        '\nLatency [Default Detection] of frame-%s: (%.5fs)' %
                        (str(this_frame_id), t_default))
                    t_default_key = "draw2bbox-" + str(
                        self.opt.drone_id) + "-" + str(this_frame_id)
                    redis_set(self.rc_latency, t_default_key, t_default)

                    # Print time (inference + NMS)
                    # print('%sDone. (%.3fs)' % (self.str_output, time.time() - t))

                    print(
                        'Done. (%.3fs) --> '
                        'Inference(%.3fs); NMS(%.3fs); MB-Box(%.3fs); Default-Bbox(%.3fs)'
                        % ((time.time() - t), t_inference, t_nms, t_mbbox,
                           t_default))

                    # Save end latency calculation
                    t_end_key = "end-" + str(self.opt.drone_id)
                    redis_set(self.rc_latency, t_end_key, time.time())

                    # Mark last processed frame
                    t_last_frame_key = "last-" + str(self.opt.drone_id)
                    redis_set(self.rc_latency, t_last_frame_key,
                              int(this_frame_id))

                    # latency: End-to-end Latency, each frame
                    t_sframe_key = "start-fi-" + str(
                        self.opt.drone_id
                    )  # to calculate end2end latency each frame.
                    t_end2end_frame = redis_get(
                        self.rc_latency, t_end_key) - redis_get(
                            self.rc_latency, t_sframe_key)
                    t_e2e_frame_key = "end2end-frame-" + str(
                        self.opt.drone_id) + "-" + str(this_frame_id)
                    redis_set(self.rc_latency, t_e2e_frame_key,
                              t_end2end_frame)
                    print(
                        '\nLatency [End2end this frame] of frame-%s: (%.5fs)' %
                        (str(this_frame_id), t_end2end_frame))

                    # latency: End-to-end Latency TOTAL
                    t_start_key = "start-" + str(self.opt.drone_id)
                    t_end2end = redis_get(self.rc_latency,
                                          t_end_key) - redis_get(
                                              self.rc_latency, t_start_key)
                    t_e2e_key = "end2end-" + str(self.opt.drone_id)
                    redis_set(self.rc_latency, t_e2e_key, t_end2end)
                    print('\nLatency [This End2end] of frame-%s: (%.5fs)' %
                          (str(this_frame_id), t_end2end))

                    # Stream results
                    # if self.view_img:
                    #     cv2.imshow(p, im0)
                    #     if cv2.waitKey(1) == ord('q'):  # q to quit
                    #         raise StopIteration

                    self.__save_results(im0, vid_cap, self.frame_id)
Beispiel #7
0
    def waiting_frames(self):
        print("Starting YOLOv3 image detector")
        t0 = time.time()
        self.__load_weight()
        t_load_weight = time.time() - t0
        # print(".. Load `weight` in (%.3fs)" % t_load_weight)

        # Latency: Load YOLOv3 Weight
        t_weight_key = "weight-" + str(self.opt.drone_id)
        redis_set(self.rc_latency, t_weight_key, t_load_weight)
        print('\nLatency [Load `weight`]: (%.5fs)' % (t_load_weight))

        t0 = time.time()
        self.__eval_model()
        t_load_eval_model = time.time() - t0
        # print(".. Load function `eval_model` in (%.3fs)" % t_load_eval_model)

        # Latency: Execute Evaluation Model
        t_eval_model_key = "evalModel-" + str(self.opt.drone_id)
        redis_set(self.rc_latency, t_eval_model_key, t_load_eval_model)
        print('\nLatency [Load `Eval Model`]: (%.5fs)' % (t_load_eval_model))

        self.__get_names_colors()

        # Setup redis subscriber availability
        self.__setup_subscriber()

        # Waiting for get the image information
        stream_ch = "stream_" + self.opt.sub_channel
        print("\n### Waiting for get the image information @ Channel `%s`" %
              stream_ch)
        pubsub = self.rc.pubsub()
        pubsub.subscribe([stream_ch])
        for item in pubsub.listen():
            # noinspection PyPackageRequirements
            try:
                t0_sub2frame = time.time()
                # Start fetching information
                fetch_data = json.loads(item['data'])
                frame_id = fetch_data['frame_id']
                # print('Streamer collects : ', fetch_data)

                # Latency: subscribing frame
                t_sub2frame = time.time() - t0_sub2frame
                t_sub2frame_key = "sub2frame-" + str(
                    self.opt.drone_id) + "-" + str(frame_id)
                redis_set(self.rc_latency, t_sub2frame_key, t_sub2frame)
                print(
                    '\nLatency [Subscriber extracting information] of frame-%s: (%.5fs)'
                    % (str(frame_id), t_sub2frame))

                self.source = fetch_data["img_path"]
                # print('img_path : ', self.source)
                # Load image from pub: get `img_path`
                t0_load_img = time.time()
                self.__set_data_loader()
                t_load_img = time.time() - t0_load_img
                # print(".. load image into variable in (%.3fs)" % (time.time() - t0))
                t_load_img_key = "loadIMG-" + str(
                    self.opt.drone_id) + "-" + str(frame_id)
                redis_set(self.rc_latency, t_load_img_key, t_load_img)
                print(
                    '\nLatency [Loads image into YOLOv3 Worker] of frame-%s: (%.5fs)'
                    % (str(frame_id), t_load_img))

                # # Check worker status first, please wait while still working
                # is_worker_ready = redis_get(self.rc_data, self.opt.sub_channel)
                # print(">>>>>> is_worker_ready = ", is_worker_ready)
                # if is_worker_ready:
                #     print("\nWorker-%d is still running, waiting to finish ..." % self.opt.sub_channel)
                #     time.sleep(0.1)

                # Start processing image
                print("\nStart processing to get MB-Box.")
                redis_set(self.rc_data, self.opt.sub_channel,
                          0)  # set as `Busy`
                # print("Set as busy Done.")
                self.__iterate_frames(
                    frame_id)  # Perform detection in each frame here
                # print(" >>> Hasil MB-Box Img = ", self.mbbox_img)
                # print("Process finished.")

                frame_id = str(fetch_data["frame_id"])
                prev_fid = str(self.opt.drone_id) + "-" + str(
                    (int(frame_id) - 1))

                # # TBD: Start behavior detection in background process, in every 30 frames (FPS=30)
                # behave_det = BehaviorDetection(self.opt, int(frame_id), self.detected_mbbox)
                # if int(frame_id) % self.fps and self.detected_mbbox > 0:
                #     behave_det.run()

                # Preparing to send the frames.
                if self.mbbox_img is not None:
                    # output_path = self.opt.mbbox_output + "frame-%s.jpg" % frame_id
                    output_path = self.opt.mbbox_output + str(
                        self.opt.drone_id) + "/frame-%s.jpg" % frame_id

                    # Try writing synchronously: store ONLY when (frame-1) has been stored
                    # print(" ######## PREV_ID = ", redis_get(self.rc, prev_fid))
                    while redis_get(self.rc,
                                    prev_fid) is None and int(frame_id) > 1:
                        # print(" ######## Waiting previous frame to be stored. PREV_ID = ", redis_get(self.rc, prev_fid))
                        # time.sleep(1)
                        pass

                    t0_save_mbbox_img = time.time()
                    cv2.imwrite(output_path, self.mbbox_img)
                    # print("Saving image in: ", output_path)
                    # print(".. MB-Box image is saved in (%.3fs)" % (time.time() - t0))
                    t_save_mbbox_img = time.time() - t0_save_mbbox_img
                    t_save_mbbox_img_key = "save2mmboxIMG-" + str(
                        self.opt.drone_id) + "-" + str(frame_id)
                    redis_set(self.rc_latency, t_save_mbbox_img_key,
                              t_save_mbbox_img)
                    print(
                        '\nLatency [Save MB-Box Image] of frame-%s: (%.5fs)' %
                        (str(frame_id), t_save_mbbox_img))

                    # Set that this frame has been successfully added
                    expired_at = 20  # in seconds
                    key = str(self.opt.drone_id) + "-" + frame_id
                    redis_set(self.rc, key, True, expired_at)
                else:
                    print("This MB-Box is NONE. nothing to be saved yet.")

                # self.__save_latency_to_csv()

                # Restore availibility
                redis_set(self.rc_data, self.opt.sub_channel,
                          1)  # set as `Ready`
                print("\n### This Worker-%s is ready to serve again. \n\n" %
                      self.opt.sub_channel)

                # Set prev_fid as DONE
                redis_set(self.rc_data, prev_fid, None)  # set as `Ready`

                # if this is latest frame: Set this frame as latest
                # key = "drone_id-latest", value: "drone_id-frame_id"
                # redis_set(self.rc_data, prev_fid, None) # set as `Ready`
            except:
                pass
Beispiel #8
0
 def set_last_frame_id(self):
     key = "last-" + str(self.opt.drone_id)
     self.last_frame_id = redis_get(self.rc_latency, key)
Beispiel #9
0
 def __worker_status(self):
     return redis_get(self.rc_data, self.worker_id)