class Preprocess(): def __init__(self, stream_name, channel, resize_width, resize_height): self._stream_name = str(stream_name) self._channel = int(channel) self._resize_width = resize_width self._resize_height = resize_width self._status = STATUS_PREPROC_INIT self._display = False self._dvpp = None self._cap = None self._context = None self._image_queue = queue.Queue(64) def _start(self): thread_id, ret = acl.util.start_thread(self._thread_entry, []) utils.check_ret("acl.util.start_thread", ret) log_info("Start sub thread ok, wait init...") while self._status == STATUS_PREPROC_INIT: time.sleep(0.001) log_info("Status changed to ", self._status) while self._start == STATUS_PREPROC_RUNNING: if self._image_queue.qsize() > 0: break time.sleep(0.001) return self._status != STATUS_PREPROC_ERROR def _thread_entry(self, args_list): self._context, ret = acl.rt.create_context(0) utils.check_ret("acl.rt.create_context", ret) self._cap = video.AclVideo(self._stream_name) self._dvpp = Dvpp() self._status = STATUS_PREPROC_RUNNING frame_cnt = 0 while self._status == STATUS_PREPROC_RUNNING: ret, image = self._cap.read() if ret or (image is None): if ret == const.VIDEO_DECODE_FINISH: log_info("Video %s decode finish"%(self._stream_name)) self._status = STATUS_PREPROC_EXIT else: log_info("Video %s decode failed"%(self._stream_name)) self._status = STATUS_PREPROC_ERROR break if (int(frame_cnt) % 5 == 0): self._process_frame(image) time.sleep(0.0) self._thread_exit() def _process_frame(self, frame): resized_image = self._dvpp.resize(frame, self._resize_width, self._resize_height) if resized_image is None: log_error("dvpp resize image failed") return jpg_image = None if self._display: jpg_image = self._dvpp.jpege(frame) if jpg_image is None: log_error("dvpp jpege failed") return data = PreProcData(self._channel, frame.width, frame.height, resized_image, jpg_image, self._display) self._image_queue.put(data) def _thread_exit(self): self._status = STATUS_PREPROC_EXIT log_info("Channel %d thread exit..."%(self._channel)) if self._dvpp != None: del self._dvpp self._dvpp = None if self._cap != None: del self._cap self._cap = None if self._context != None: acl.rt.destroy_context(self._context) self._context = None log_info("Channel %d thread exit ok"%(self._channel)) def set_display(self, display): self._display = display def is_finished(self): return self._status > STATUS_PREPROC_RUNNING def get_data(self): ret = True if self._status == STATUS_PREPROC_EXIT: return False, None elif self._status == STATUS_PREPROC_INIT: ret = self._start() if ret == False: log_error("decode channel %d failed"%(self._channel)) return False, None if self._image_queue.empty(): return True, None preproc_data = self._image_queue.get_nowait() if preproc_data is None: ret = False return ret, preproc_data def __del__(self): self._thread_exit()
class VggSsd(object): """vggssd""" def __init__(self, acl_resource, model_width, model_height): self._acl_resource = acl_resource self._model_width = model_width self._model_height = model_height #Use dvpp to process images, when using opencv or PIL, # you don't need to create a dvpp instance self._dvpp = Dvpp(acl_resource) def __del__(self): if self._dvpp: del self._dvpp print("Release yolov3 resource finished") def pre_process(self, image): """Use dvpp to scale the image to the required size of the model""" resized_image = self._dvpp.resize(image, self._model_width, self._model_height) if resized_image is None: print("Resize image failed") return None #Output the scaled image and image information as inference input data return [ resized_image, ] def post_process(self, infer_output, origin_img): """Analyze inference output data""" detection_result_list = self._analyze_inference_output( infer_output, origin_img) #Convert yuv image to jpeg image jpeg_image = self._dvpp.jpege(origin_img) return jpeg_image, detection_result_list def _analyze_inference_output(self, infer_output, origin_img): #vgg ssd has two outputs, the first output # infer_output[0] is the number of detected objects, and the shape is (1,8) box_num = int(infer_output[0][0, 0]) #The second output infer_output[1] is the detected object information, the shape is (1, 200, 8) box_info = infer_output[1][0] detection_result_list = [] for i in range(box_num): #Detected object confidence score = box_info[i, SCORE] if score < 0.9: break detection_item = presenter_datatype.ObjectDetectionResult() detection_item.confidence = score #Person face position frame coordinates, normalized coordinates, # need to be multiplied by the width and height of the picture to convert to the coordinates on the picture detection_item.box.lt.x = int(box_info[i, TOP_LEFT_X] * origin_img.width) detection_item.box.lt.y = int(box_info[i, TOP_LEFT_Y] * origin_img.height) detection_item.box.rb.x = int(box_info[i, BOTTOM_RIGHT_X] * origin_img.width) detection_item.box.rb.y = int(box_info[i, BOTTOM_RIGHT_Y] * origin_img.height) #Organize the confidence into a string detection_item.result_text = str( round(detection_item.confidence * 100, 2)) + "%" detection_result_list.append(detection_item) return detection_result_list