def parse_params(): # class YOLO defines the default value, so suppress any default HERE parser = arg_params_yolo() parser.add_argument('-i', '--path_image', nargs='*', type=str, required=False, help='Images to be processed (sequence of paths)') parser.add_argument('-v', '--path_video', nargs='*', type=str, required=False, help='Video to be processed (sequence of paths)') arg_params = vars(parser.parse_args()) for k_name in ('path_image', 'path_video'): # if there is only single path still make it as a list if k_name in arg_params and not isinstance(arg_params[k_name], (list, tuple)): arg_params[k_name] = [arg_params[k_name]] # Update paths for k in (k for k in arg_params if 'path' in k): if k in ('path_image', 'path_video'): arg_params[k] = [update_path(path_) for path_ in arg_params[k]] elif arg_params[k]: arg_params[k] = update_path(arg_params[k]) assert os.path.exists( arg_params[k]), 'missing (%s): %s' % (k, arg_params[k]) logging.debug('PARAMETERS: \n %s', repr(arg_params)) return arg_params
def parse_arguments(): parser = argparse.ArgumentParser(description='Darknet To Keras Converter.') parser.add_argument('--config_path', type=str, required=True, help='Path to Darknet cfg file.') parser.add_argument('--weights_path', type=str, required=True, help='Path to Darknet weights file.') parser.add_argument('--output_path', type=str, required=True, help='Path to output Keras model file.') parser.add_argument('-p', '--plot_model', action='store_true', help='Plot generated Keras model and save as image.') parser.add_argument( '-w', '--weights_only', action='store_true', help='Save as Keras weights file instead of model file.') arg_params = vars(parser.parse_args()) for k in (k for k in arg_params if 'path' in k and 'output' not in k): arg_params[k] = update_path(arg_params[k]) assert os.path.exists( arg_params[k]), 'missing (%s): %s' % (k, arg_params[k]) logging.debug('PARAMETERS: \n %s', repr(arg_params)) return arg_params
def parse_arguments(): parser = argparse.ArgumentParser(description='Annotation Converter (VOC).') parser.add_argument('--path_dataset', type=str, required=True, help='Path to VOC dataset.') parser.add_argument('--sets', type=str, required=False, nargs='+', help='List of sets in dataset.', default=('2007,train', '2007,val', '2007,test')) parser.add_argument('--path_output', type=str, required=False, default='.', help='Path to output folder.') parser.add_argument('--classes', type=str, required=False, default=None, nargs='*', help='Use only following classes.') arg_params = vars(parser.parse_args()) for k in (k for k in arg_params if 'path' in k): arg_params[k] = update_path(arg_params[k]) assert os.path.exists( arg_params[k]), 'missing (%s): %s' % (k, arg_params[k]) logging.info( 'PARAMETERS: \n%s', '\n'.join(['"%s": \t\t %r' % (k, arg_params[k]) for k in arg_params])) return arg_params
def load_draw_export_bboxes(img_path, path_bboxes, path_out): img_name, _ = os.path.splitext(os.path.basename(img_path)) image = image_open(img_path) name_visu = '%s_visual.jpg' % img_name path_visu = os.path.join(update_path(path_out), name_visu) path_csv = os.path.join(path_bboxes, '%s.csv' % img_name) if not os.path.isfile(path_csv): return df_boxes = pd.read_csv(path_csv) if 'class' not in df_boxes.columns: df_boxes['class'] = 0 for bb in df_boxes[list(ANNOT_COLUMNS)].values: image = draw_bounding_box(image, bb[4], bb[:4], swap_xy=True, color=(0, 255, 0), thickness=2) # from keras_yolo3.visual import show_augment_data # show_augment_data(image, boxes, image, boxes) image.save(path_visu) return path_visu
def predict_video(yolo, path_video, path_output=None, show_stream=False): try: path_video = int(path_video) except Exception: # not using web cam path_video = update_path(path_video) else: # using the (infinite) stream add option to terminate show_stream = True # Create a video capture object to read videos try: video = cv2.VideoCapture(path_video) except Exception: logging.warning('missing: %s', path_video) return if path_output is not None and os.path.isdir(path_output): video_fps = video.get(cv2.CAP_PROP_FPS) video_size = (int(video.get(cv2.CAP_PROP_FRAME_WIDTH)), int(video.get(cv2.CAP_PROP_FRAME_HEIGHT))) name = os.path.splitext(os.path.basename(path_video))[0] \ if isinstance(path_video, str) else str(path_video) path_out = os.path.join(path_output, name + VISUAL_EXT + '.avi') logging.debug('export video: %s', path_out) out_vid = cv2.VideoWriter(path_out, VIDEO_FORMAT, video_fps, video_size) frame_preds = [] path_json = os.path.join(path_output, name + '.json') else: out_vid, frame_preds, path_json = None, None, None while video.isOpened(): success, frame = video.read() if not success: logging.warning('video read status: %r', success) break image = Image.fromarray(frame) t_start = time.time() image_pred, pred_items = yolo.detect_image(image) frame = np.asarray(image_pred) fps = 'FPS: %f' % (1. / (time.time() - t_start)) cv2.putText(frame, text=fps, org=(3, 15), fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=0.50, color=(255, 0, 0), thickness=2) if out_vid: out_vid.write(frame) frame_preds.append(pred_items) with open(path_json, 'w') as fp: json.dump(frame_preds, fp) if show_stream: cv2.imshow('YOLOv3', frame) if cv2.waitKey(1) & 0xFF == ord('q'): cv2.destroyWindow('YOLOv3') break if out_vid: out_vid.release() logging.debug('exported predictions: %s', path_json)
def parse_draw_export_bboxes(line, path_out): line_elems = line.strip().split() img_path = update_path(line_elems[0]) img_name, _ = os.path.splitext(os.path.basename(img_path)) image = image_open(img_path) name_visu = TEMP_IMAGE_NAME % img_name path_visu = os.path.join(update_path(path_out), name_visu) boxes = [list(map(int, el.split(','))) for el in line_elems[1:]] for bb in boxes: image = draw_bounding_box(image, bb[4], bb[:4], swap_xy=True, color=(0, 255, 0), thickness=2) # from keras_yolo3.visual import show_augment_data # show_augment_data(image, boxes, image, boxes) image.save(path_visu) return path_visu
def parse_arguments(): parser = argparse.ArgumentParser(description='Annotation Converter (RectLabel).') parser.add_argument('--root_annot', type=str, required=True, help='Root path to annotation files.') parser.add_argument('--root_images', type=str, required=True, help='Root folder to images of dataset.') parser.add_argument('--output', type=str, required=False, default='.', help='Output file.') arg_params = vars(parser.parse_args()) for k in (k for k in arg_params if 'path' in k): arg_params[k] = update_path(arg_params[k]) assert os.path.exists(arg_params[k]), 'missing (%s): %s' % (k, arg_params[k]) logging.info('PARAMETERS: \n%s', '\n'.join(['"%s": \t\t %r' % (k, arg_params[k]) for k in arg_params])) return arg_params
def predict_image(yolo, path_image, path_output=None): path_image = update_path(path_image) if not path_image: logging.debug('no image given') elif not os.path.isfile(path_image): logging.warning('missing image: %s', path_image) image = Image.open(path_image) image_pred, pred_items = yolo.detect_image(image) if path_output is None or not os.path.isdir(path_output): image_pred.show() else: name = os.path.splitext(os.path.basename(path_image))[0] path_out_img = os.path.join(path_output, name + VISUAL_EXT + '.jpg') path_out_csv = os.path.join(path_output, name + '.csv') logging.debug('exporting image: "%s" and detection: "%s"', path_out_img, path_out_csv) image_pred.save(path_out_img) pd.DataFrame(pred_items).to_csv(path_out_csv)
def _main(pattern_images, path_csv_folder, path_output, nb_jobs=0.9): pattern_images = os.path.join(update_path(os.path.dirname(pattern_images)), os.path.basename(pattern_images)) assert os.path.isdir(os.path.dirname(pattern_images)) image_paths = sorted(glob.glob(pattern_images)) if not image_paths: logging.warning('Dataset is empty for %s', pattern_images) return nb_jobs = nb_workers(nb_jobs) pool = ProcessPool(nb_jobs) if nb_jobs > 1 else None _wrap_visu = partial(load_draw_export_bboxes, path_bboxes=path_csv_folder, path_out=path_output) # multiprocessing loading of batch data map_process = pool.imap if pool else map _ = list( tqdm.tqdm(map_process(_wrap_visu, image_paths), desc='Visualization'))
def parse_arguments(): parser = argparse.ArgumentParser( description='Annotation Converter (custom CSV).') parser.add_argument('--path_dataset', type=str, required=True, help='Path to custom CSV dataset.') parser.add_argument('--path_output', type=str, required=False, default='.', help='Path to output folder.') arg_params = vars(parser.parse_args()) for k in (k for k in arg_params if 'path' in k): arg_params[k] = update_path(arg_params[k]) assert os.path.exists( arg_params[k]), 'missing (%s): %s' % (k, arg_params[k]) logging.info( 'PARAMETERS: \n%s', '\n'.join(['"%s": \t\t %r' % (k, arg_params[k]) for k in arg_params])) return arg_params
def draw_export_bboxes(img_path, path_out, bboxes_anot, bboxes_pred): img_name, _ = os.path.splitext(os.path.basename(img_path)) image = image_open(img_path) for bb in bboxes_anot: image = draw_bounding_box(image, bb[4], bb[:4], swap_xy=True, color=(0, 255, 0), thickness=2) for bb in bboxes_pred: image = draw_bounding_box(image, bb[4], bb[:4], swap_xy=True, color=(255, 0, 0), thickness=2) name_visu = TEMP_IMAGE_NAME % img_name path_visu = os.path.join(update_path(path_out), name_visu) image.save(path_visu) return path_visu
def parse_params(): # class YOLO defines the default value, so suppress any default HERE parser = arg_params_yolo() parser.add_argument('-d', '--path_dataset', type=str, required=True, help='path to the train source - dataset,' ' with single taining instance per line') parser.add_argument( '--path_config', type=str, required=False, help='path to the train configuration, using YAML format') arg_params = vars(parser.parse_args()) for k in (k for k in arg_params if 'path' in k): if not arg_params[k]: continue arg_params[k] = update_path(arg_params[k]) assert os.path.exists( arg_params[k]), 'missing (%s): %s' % (k, arg_params[k]) logging.debug('PARAMETERS: \n %s', repr(arg_params)) return arg_params
def parse_params(): # class YOLO defines the default value, so suppress any default HERE parser = arg_params_yolo() parser.add_argument('--images', default=False, action='store_true', help='Image detection mode.') parser.add_argument('--videos', default=False, action='store_true', help='Video detection mode.') parser.add_argument('--stream', default=False, action='store_true', help='Detection from stream.') arg_params = vars(parser.parse_args()) for k in (k for k in arg_params if 'path' in k): arg_params[k] = update_path(arg_params[k]) assert os.path.exists( arg_params[k]), 'missing (%s): %s' % (k, arg_params[k]) logging.debug('PARAMETERS: \n %s', repr(arg_params)) return arg_params
def create_model_bottleneck(input_shape, anchors, num_classes, freeze_body=2, weights_path=None, nb_gpu=1): """create the training model""" # K.clear_session() # get a new session cnn_h, cnn_w = input_shape image_input = Input(shape=(cnn_w, cnn_h, 3)) num_anchors = len(anchors) y_true = [Input(shape=(cnn_h // {0: 32, 1: 16, 2: 8}[layer_idx], cnn_w // {0: 32, 1: 16, 2: 8}[layer_idx], num_anchors // 3, num_classes + 5)) for layer_idx in range(3)] _LOSS_ARGUMENTS = { 'anchors': anchors, 'num_classes': num_classes, 'ignore_thresh': 0.5 } if not nb_gpu: # disable all GPUs os.environ["CUDA_VISIBLE_DEVICES"] = "-1" model_body = yolo_body_full(image_input, num_anchors // 3, num_classes) logging.info('Create YOLOv3 model with %i anchors and %i classes.', num_anchors, num_classes) if weights_path is not None: weights_path = update_path(weights_path) if os.path.isfile(weights_path): logging.warning('missing weights: %s', weights_path) else: logging.info('Load weights %s.', weights_path) model_body.load_weights(weights_path, by_name=True, skip_mismatch=True) if freeze_body in [1, 2]: # Freeze darknet53 body or freeze all but 3 output layers. num = (185, len(model_body.layers) - 3)[freeze_body - 1] for i in range(num): model_body.layers[i].trainable = False logging.info('Freeze the first %i layers of total %i layers.', num, len(model_body.layers)) # get output of second last layers and create bottleneck model of it out1 = model_body.layers[246].output out2 = model_body.layers[247].output out3 = model_body.layers[248].output model_bottleneck = Model([model_body.input, *y_true], [out1, out2, out3]) # create last layer model of last layers from yolo model in0 = Input(shape=model_bottleneck.output[0].shape[1:].as_list()) in1 = Input(shape=model_bottleneck.output[1].shape[1:].as_list()) in2 = Input(shape=model_bottleneck.output[2].shape[1:].as_list()) last_out0 = model_body.layers[249](in0) last_out1 = model_body.layers[250](in1) last_out2 = model_body.layers[251](in2) model_last = Model(inputs=[in0, in1, in2], outputs=[last_out0, last_out1, last_out2]) fn_loss = Lambda(yolo_loss, output_shape=(1,), name='yolo_loss', arguments=_LOSS_ARGUMENTS) model_loss_last = fn_loss([*model_last.output, *y_true]) last_layer_model = Model([in0, in1, in2, *y_true], model_loss_last) fn_loss = Lambda(yolo_loss, output_shape=(1,), name='yolo_loss', arguments=_LOSS_ARGUMENTS) model_loss = fn_loss([*model_body.output, *y_true]) model = Model([model_body.input, *y_true], model_loss) if nb_gpu >= 2: model = multi_gpu_model(model, gpus=nb_gpu) model_bottleneck = multi_gpu_model(model_bottleneck, gpus=nb_gpu) return model, model_bottleneck, last_layer_model
def _main(config_path, weights_path, output_path, weights_only, plot_model): assert os.path.isfile(config_path), 'missing "%s"' % config_path assert os.path.isfile(weights_path), 'missing "%s"' % weights_path assert config_path.endswith('.cfg'), \ '"%s" is not a .cfg file' % os.path.basename(config_path) assert weights_path.endswith('.weights'), \ '"%s" is not a .weights file' % os.path.basename(config_path) output_dir = update_path(os.path.dirname(output_path)) assert os.path.isdir(output_dir), 'missing "%s"' % output_dir output_path = os.path.join(output_dir, os.path.basename(output_path)) assert output_path.endswith('.h5'), \ 'output path "%s" is not a .h5 file' % os.path.basename(output_path) # Load weights and config. logging.info('Loading weights: %s', weights_path) weights_file = open(weights_path, 'rb') major, minor, revision = np.ndarray(shape=(3, ), dtype='int32', buffer=weights_file.read(12)) if (major * 10 + minor) >= 2 and major < 1000 and minor < 1000: seen = np.ndarray(shape=(1, ), dtype='int64', buffer=weights_file.read(8)) else: seen = np.ndarray(shape=(1, ), dtype='int32', buffer=weights_file.read(4)) logging.info('Weights Header: %i.%i.%i %s', major, minor, revision, repr(seen.tolist())) logging.info('Parsing Darknet config: %s', config_path) unique_config_file = unique_config_sections(config_path) cfg_parser = configparser.ConfigParser() cfg_parser.read_file(unique_config_file) logging.info('Creating Keras model.') cnn_w = int(cfg_parser['net_0']['width']) cnn_h = int(cfg_parser['net_0']['height']) input_layer = Input(shape=(cnn_h, cnn_w, 3)) prev_layer = input_layer all_layers = [] weight_decay = float(cfg_parser['net_0']['decay']) \ if 'net_0' in cfg_parser.sections() else 5e-4 count = 0 out_index = [] for section in tqdm.tqdm(cfg_parser.sections()): logging.debug('Parsing section "%s"', section) (all_layers, cfg_parser, section, prev_layer, weights_file, count, weight_decay, out_index) = parse_section(all_layers, cfg_parser, section, prev_layer, weights_file, count, weight_decay, out_index) # Create and save model. if len(out_index) == 0: out_index.append(len(all_layers) - 1) model = Model(inputs=input_layer, outputs=[all_layers[i] for i in out_index]) logging.info(model.summary(line_length=120)) if weights_only: model.save_weights(output_path) logging.info('Saved Keras weights to "%s"', output_path) else: model.save(output_path) logging.info('Saved Keras model to "%s"', output_path) # Check to see if all weights have been read. remaining_weights = len(weights_file.read()) / 4 weights_file.close() logging.info('Read %i of %i from Darknet weight.', count, count + remaining_weights) if remaining_weights > 0: logging.warning('there are %i unused weights', remaining_weights) if plot_model: path_img = '%s.png' % os.path.splitext(output_path)[0] plot(model, to_file=path_img, show_shapes=True) logging.info('Saved model plot to %s', path_img)