def draw_demo_image( image, segmentation_map, display_fps, inf_size=(480, 320), ): # フォント font_path = './utils/font/x12y20pxScanLine.ttf' # ピクセル塗りつぶし image_width, image_height = image.shape[1], image.shape[0] draw_image = copy.deepcopy(image) draw_image = cv.resize(draw_image, inf_size) seg_image = label_to_color_image(segmentation_map).astype(np.uint8) seg_mask = label_to_person_mask(segmentation_map).astype(np.uint8) draw_image = np.where(seg_mask == 255, seg_image, draw_image) draw_image = cv.resize(draw_image, (image_width, image_height)) # FPS描画 fps_string = u"FPS:" + str(display_fps) draw_image = CvDrawText.puttext(draw_image, fps_string, (15, 15), font_path, 32, (0, 0, 0)) return draw_image
def bba_black_ring_wa( image, p1, p2, color=(185, 0, 0), thickness=None, # unused font='utils/font/衡山毛筆フォント.ttf', text=None, fps=None, # unused animation_count=None, # unused ): draw_image = copy.deepcopy(image) x1, y1 = p1[0], p1[1] x2, y2 = p2[0], p2[1] font_size = int((y2 - y1) * (4 / 5)) cv.circle(draw_image, (int((x1 + x2) / 2), int((y1 + y2) / 2)), int((y2 - y1) * (3 / 7)), (255, 255, 255), 20) cv.circle(draw_image, (int((x1 + x2) / 2), int((y1 + y2) / 2)), int((y2 - y1) * (3 / 7)), (0, 0, 0), 10) if (font is not None) and (text is not None): draw_image = CvDrawText.puttext( draw_image, text, (int(((x1 + x2) / 2) - (font_size / 2)), int(((y1 + y2) / 2) - (font_size / 2))), font, font_size, color) return draw_image
def bba_annotation_line( image, p1, p2, color=(255, 255, 255), thickness=None, # unused font='utils/font/mplus-1c-regular.ttf', text=None, fps=None, # unused animation_count=None, # unused ): draw_image = copy.deepcopy(image) x1, y1 = p1[0], p1[1] x2, y2 = p2[0], p2[1] rectangle_width = x2 - x1 rectangle_height = y2 - y1 font_size = int(rectangle_width * (1 / 10)) drawpoint1 = (int((x1 + x2) / 2), int((y1 + y2) / 2)) drawpoint2 = (x2 - int(rectangle_width / 10), y1 + int(rectangle_height / 10)) drawpoint3 = (x2 + int(rectangle_width / 2), y1 + int(rectangle_height / 10)) textpoint = (drawpoint2[0], drawpoint2[1] - int(font_size * 1.5)) if drawpoint3[0] > image.shape[1]: drawpoint2 = (x1 + int(rectangle_width / 10), y1 + int(rectangle_height / 10)) drawpoint3 = (x1 - int(rectangle_width / 2), y1 + int(rectangle_height / 10)) textpoint = (drawpoint3[0], drawpoint2[1] - int(font_size * 1.5)) cv.circle(draw_image, drawpoint1, int(rectangle_width / 40), color, thickness=-1) cv.line(draw_image, drawpoint1, drawpoint2, color, int(rectangle_width / 80)) cv.line(draw_image, drawpoint2, drawpoint3, color, int(rectangle_width / 80)) if (font is not None) and (text is not None): draw_image = CvDrawText.puttext(draw_image, text, textpoint, font, font_size, color) return draw_image
def bba_translucent_rectangle_fill1( image, p1, p2, color=(0, 64, 0), thickness=None, # unused font='utils/font/x12y20pxScanLine.ttf', text=None, fps=None, # unused animation_count=None, # unused ): draw_image = copy.deepcopy(image) image_width, image_height = draw_image.shape[1], draw_image.shape[0] x1, y1 = p1[0], p1[1] x2, y2 = p2[0], p2[1] rectangle_width = x2 - x1 rectangle_height = y2 - y1 font_size = int((y2 - y1) * (2 / 9)) draw_add_image = np.zeros((image_height, image_width, 3), np.uint8) cv.rectangle(draw_add_image, (x1, y1), (x2, y2), color, thickness=10) cv.rectangle( draw_add_image, (x1 + int(rectangle_width / 20), y1 + int(rectangle_height / 20)), (x2 - int(rectangle_width / 20), y2 - int(rectangle_height / 20)), color, thickness=-1) if (font is not None) and (text is not None): draw_add_image = CvDrawText.puttext( draw_add_image, text, (int(((x1 + x2) / 2) - (font_size / 0.9)), int(((y1 + y2) / 2) - (font_size / 2))), font, font_size, (0, 0, 0)) draw_image = cv.add(draw_image, draw_add_image) return draw_image
def draw_demo_image( image, detection_count, classification_string, display_fps, trim_point, ): image_width, image_height = image.shape[1], image.shape[0] # フォント font_path = './utils/font/KosugiMaru-Regular.ttf' # 四隅枠表示 if detection_count < 4: gap_length = int((trim_point[2] - trim_point[0]) / 10) * 9 cv.line(image, (trim_point[0], trim_point[1]), (trim_point[2] - gap_length, trim_point[1]), (255, 255, 255), 3) cv.line(image, (trim_point[0] + gap_length, trim_point[1]), (trim_point[2], trim_point[1]), (255, 255, 255), 3) cv.line(image, (trim_point[2], trim_point[1]), (trim_point[2], trim_point[3] - gap_length), (255, 255, 255), 3) cv.line(image, (trim_point[2], trim_point[1] + gap_length), (trim_point[2], trim_point[3]), (255, 255, 255), 3) cv.line(image, (trim_point[0], trim_point[3]), (trim_point[2] - gap_length, trim_point[3]), (255, 255, 255), 3) cv.line(image, (trim_point[0] + gap_length, trim_point[3]), (trim_point[2], trim_point[3]), (255, 255, 255), 3) cv.line(image, (trim_point[0], trim_point[1]), (trim_point[0], trim_point[3] - gap_length), (255, 255, 255), 3) cv.line(image, (trim_point[0], trim_point[1] + gap_length), (trim_point[0], trim_point[3]), (255, 255, 255), 3) line_x1 = int(image_width / 1.55) line_x2 = int(image_width / 1.1) line_y = int(image_height / 5) # 回転丸表示 if detection_count > 0: draw_angle = int(detection_count * 45) cv.ellipse(image, (int(image_width / 2), int(image_height / 2)), (10, 10), -45, 0, draw_angle, (255, 255, 255), -1) # 斜線表示 if detection_count > 10: cv.line(image, (int(image_width / 2), int(image_height / 2)), (line_x1, line_y), (255, 255, 255), 2) # 横線・分類名・スコア表示 if detection_count > 10: font_size = 32 cv.line(image, (line_x1, line_y), (line_x2, line_y), (255, 255, 255), 2) image = CvDrawText.puttext( image, classification_string, (line_x1 + 10, line_y - int(font_size * 1.25)), font_path, font_size, (255, 255, 255)) # FPS描画 ####################################################### fps_string = u"FPS:" + str(display_fps) image = CvDrawText.puttext(image, fps_string, (30, 30), font_path, 32, (255, 255, 255)) return image
def draw_debug_image( debug_image, font_path, fps_result, labels, result_inference, score_th, erase_bbox, use_display_score, jutsu, sign_display_queue, sign_max_display, jutsu_display_time, jutsu_font_size_ratio, lang_offset, jutsu_index, jutsu_start_time, ): frame_width, frame_height = debug_image.shape[1], debug_image.shape[0] # 印のバウンディングボックスの重畳表示(表示オプション有効時) ################### if not erase_bbox: num_detections = result_inference['num_detections'] for i in range(num_detections): score = result_inference['detection_scores'][i] bbox = result_inference['detection_boxes'][i] class_id = result_inference['detection_classes'][i].astype(np.int) # 検出閾値未満のバウンディングボックスは捨てる if score < score_th: continue x1, y1 = int(bbox[1] * frame_width), int(bbox[0] * frame_height) x2, y2 = int(bbox[3] * frame_width), int(bbox[2] * frame_height) # バウンディングボックス(長い辺にあわせて正方形を表示) x_len = x2 - x1 y_len = y2 - y1 square_len = x_len if x_len >= y_len else y_len square_x1 = int(((x1 + x2) / 2) - (square_len / 2)) square_y1 = int(((y1 + y2) / 2) - (square_len / 2)) square_x2 = square_x1 + square_len square_y2 = square_y1 + square_len cv.rectangle(debug_image, (square_x1, square_y1), (square_x2, square_y2), (255, 255, 255), 4) cv.rectangle(debug_image, (square_x1, square_y1), (square_x2, square_y2), (0, 0, 0), 2) # 印の種類 font_size = int(square_len / 2) debug_image = CvDrawText.puttext( debug_image, labels[class_id][1], (square_x2 - font_size, square_y2 - font_size), font_path, font_size, (185, 0, 0)) # 検出スコア(表示オプション有効時) if use_display_score: font_size = int(square_len / 8) debug_image = CvDrawText.puttext( debug_image, '{:.3f}'.format(score), (square_x1 + int(font_size / 4), square_y1 + int(font_size / 4)), font_path, font_size, (185, 0, 0)) # ヘッダー作成:FPS ######################################################### header_image = np.zeros((int(frame_height / 18), frame_width, 3), np.uint8) header_image = CvDrawText.puttext(header_image, "FPS:" + str(fps_result), (5, 0), font_path, int(frame_height / 20), (255, 255, 255)) # フッター作成:印の履歴、および、術名表示 #################################### footer_image = np.zeros((int(frame_height / 10), frame_width, 3), np.uint8) # 印の履歴文字列生成 sign_display = '' if len(sign_display_queue) > 0: for sign_id in sign_display_queue: sign_display = sign_display + labels[sign_id][1] # 術名表示(指定時間描画) if lang_offset == 0: separate_string = '・' else: separate_string = ':' if (time.time() - jutsu_start_time) < jutsu_display_time: if jutsu[jutsu_index][0] == '': # 属性(火遁等)の定義が無い場合 jutsu_string = jutsu[jutsu_index][2 + lang_offset] else: # 属性(火遁等)の定義が有る場合 jutsu_string = jutsu[jutsu_index][0 + lang_offset] + \ separate_string + jutsu[jutsu_index][2 + lang_offset] footer_image = CvDrawText.puttext( footer_image, jutsu_string, (5, 0), font_path, int(frame_width / jutsu_font_size_ratio), (255, 255, 255)) # 印表示 else: footer_image = CvDrawText.puttext(footer_image, sign_display, (5, 0), font_path, int(frame_width / sign_max_display), (255, 255, 255)) # ヘッダーとフッターをデバッグ画像へ結合 ###################################### debug_image = cv.vconcat([header_image, debug_image]) debug_image = cv.vconcat([debug_image, footer_image]) return debug_image
def main(): # 引数解析 ################################################################# args = get_args() cap_device = args.device cap_width = args.width cap_height = args.height ceil_num = args.ceil image_ratio = args.image_ratio x_offset = args.x_offset y_offset = args.y_offset # カメラ準備 ############################################################### cap = cv.VideoCapture(cap_device) # 重畳画像準備 ############################################################# image_pathlist = sorted(glob.glob('utils/image/*.png')) images = [] for image_path in image_pathlist: images.append(cv.imread(image_path, cv.IMREAD_UNCHANGED)) animation_counter = 0 # CenterFace準備 ########################################################### centerface = CenterFace() # FPS計測モジュール ######################################################## cvFpsCalc = CvFpsCalc() # フォント font_path = './utils/font/x12y20pxScanLine.ttf' while True: # FPS算出 ############################################################# display_fps = cvFpsCalc.get() # カメラキャプチャ ##################################################### ret, frame = cap.read() if not ret: break resize_frame = cv.resize(frame, (int(cap_width), int(cap_height))) frame_height, frame_width = resize_frame.shape[:2] # 顔検出 ############################################################## dets, lms = centerface(resize_frame, frame_height, frame_width, threshold=0.35) # デバッグ表示 ######################################################## # バウンディングボックス for det in dets: bbox, _ = det[:4], det[4] # BBox, Score x1, y1 = int(bbox[0]), int(bbox[1]) x2, y2 = int(bbox[2]), int(bbox[3]) # 顔の立幅に合わせて重畳画像をリサイズ image_height, image_width = images[0].shape[:2] resize_ratio = (y2 - y1) / image_height resize_image_height = int(image_height * resize_ratio) resize_image_width = int(image_width * resize_ratio) resize_image_height = int( (resize_image_height + (ceil_num - 1)) / ceil_num * ceil_num) resize_image_width = int( (resize_image_width + (ceil_num - 1)) / ceil_num * ceil_num) resize_image_height = int(resize_image_height * image_ratio) resize_image_width = int(resize_image_width * image_ratio) resize_image = cv.resize(images[animation_counter], (resize_image_width, resize_image_height)) # 画像描画 overlay_x = int((x2 + x1) / 2) - int(resize_image_width / 2) overlay_y = int((y2 + y1) / 2) - int(resize_image_height / 2) resize_frame = CvOverlayImage.overlay( resize_frame, resize_image, (overlay_x + x_offset, overlay_y + y_offset)) # ランドマーク # for lm in lms: # for i in range(0, 5): # cv.circle(resize_frame, (int(lm[i * 2]), int(lm[i * 2 + 1])), # 3, (0, 0, 255), -1) animation_counter += 1 if animation_counter >= len(images): animation_counter = 0 # 画面反映 fps_string = u"FPS:" + str(display_fps) resize_frame = CvDrawText.puttext(resize_frame, fps_string, (15, 15), font_path, 40, (255, 255, 255)) cv.imshow('Demo', resize_frame) key = cv.waitKey(1) if key == 27: # ESC break cap.release()
def main(): # 引数解析 ################################################################# args = get_args() cap_device = args.device cap_width = args.width cap_height = args.height fps = args.fps model_path = args.model score_th = args.score_th # カメラ準備 ############################################################### cap = cv.VideoCapture(cap_device) cap.set(cv.CAP_PROP_FRAME_WIDTH, cap_width) cap.set(cv.CAP_PROP_FRAME_HEIGHT, cap_height) video = cv.VideoCapture('utils/map.mp4') # FPS計測モジュール ######################################################## cvFpsCalc = CvFpsCalc() # モデルロード ############################################################# DEFAULT_FUNCTION_KEY = 'serving_default' loaded_model = tf.saved_model.load(model_path) inference_func = loaded_model.signatures[DEFAULT_FUNCTION_KEY] buffer_len = 5 deque_x1 = deque(maxlen=buffer_len) deque_y1 = deque(maxlen=buffer_len) deque_x2 = deque(maxlen=buffer_len) deque_y2 = deque(maxlen=buffer_len) # フォント font_path = './utils/font/x12y20pxScanLine.ttf' while True: # FPS算出 ############################################################# display_fps = cvFpsCalc.get() start_time = time.time() # カメラキャプチャ ##################################################### ret, frame = cap.read() if not ret: continue frame_width, frame_height = frame.shape[1], frame.shape[0] debug_image = copy.deepcopy(frame) # 検出実施 ############################################################# frame = frame[:, :, [2, 1, 0]] # BGR2RGB image_np_expanded = np.expand_dims(frame, axis=0) output = run_inference_single_image(image_np_expanded, inference_func) num_detections = output['num_detections'] for i in range(num_detections): score = output['detection_scores'][i] bbox = output['detection_boxes'][i] # class_id = output['detection_classes'][i].astype(np.int) if score < score_th: continue # 検出結果可視化 ################################################### x1, y1 = int(bbox[1] * frame_width), int(bbox[0] * frame_height) x2, y2 = int(bbox[3] * frame_width), int(bbox[2] * frame_height) risize_ratio = 0.15 bbox_width = x2 - x1 bbox_height = y2 - y1 x1 = x1 + int(bbox_width * risize_ratio) y1 = y1 + int(bbox_height * risize_ratio) x2 = x2 - int(bbox_width * risize_ratio) y2 = y2 - int(bbox_height * risize_ratio) x1 = int((x1 - 5) / 10) * 10 y1 = int((y1 - 5) / 10) * 10 x2 = int((x2 + 5) / 10) * 10 y2 = int((y2 + 5) / 10) * 10 deque_x1.append(x1) deque_y1.append(y1) deque_x2.append(x2) deque_y2.append(y2) x1 = int(sum(deque_x1) / len(deque_x1)) y1 = int(sum(deque_y1) / len(deque_y1)) x2 = int(sum(deque_x2) / len(deque_x2)) y2 = int(sum(deque_y2) / len(deque_y2)) ret, video_frame = video.read() if ret is not False: video.grab() video.grab() debug_add_image = np.zeros((frame_height, frame_width, 3), np.uint8) map_resize_image = cv.resize(video_frame, ((x2 - x1), (y2 - y1))) debug_add_image = CvOverlayImage.overlay( debug_add_image, map_resize_image, (x1, y1)) debug_add_image = cv.cvtColor(debug_add_image, cv.COLOR_BGRA2BGR) # cv.imshow('1', debug_add_image) debug_image = cv.addWeighted(debug_image, 1.0, debug_add_image, 2.0, 0) else: video = cv.VideoCapture('map.mp4') # キー処理(ESC:終了) ################################################# key = cv.waitKey(1) if key == 27: # ESC break # FPS調整 ############################################################# elapsed_time = time.time() - start_time sleep_time = max(0, ((1.0 / fps) - elapsed_time)) time.sleep(sleep_time) # 画面反映 ############################################################# fps_string = u"FPS:" + str(display_fps) debug_image = CvDrawText.puttext(debug_image, fps_string, (17, 17), font_path, 32, (255, 255, 255)) fps_string = u"FPS:" + str(display_fps) debug_image = CvDrawText.puttext(debug_image, fps_string, (15, 15), font_path, 32, (0, 56, 86)) cv.imshow('Demo', debug_image) cap.release() cv.destroyAllWindows()