syntax = "proto2";

package object_detection.protos;

// Message for configuring DetectionModel evaluation jobs (eval.py).
// Next id - 35
message EvalConfig {
  optional uint32 batch_size = 25 [default = 1];
  // Number of visualization images to generate.
  optional uint32 num_visualizations = 1 [default = 10];

  // Number of examples to process of evaluation.
  optional uint32 num_examples = 2 [default = 5000, deprecated = true];

  // How often to run evaluation.
  optional uint32 eval_interval_secs = 3 [default = 300];

  // Maximum number of times to run evaluation. If set to 0, will run forever.
  optional uint32 max_evals = 4 [default = 0, deprecated = true];

  // Whether the TensorFlow graph used for evaluation should be saved to disk.
  optional bool save_graph = 5 [default = false];

  // Path to directory to store visualizations in. If empty, visualization
  // images are not exported (only shown on Tensorboard).
  optional string visualization_export_dir = 6 [default = ""];

  // BNS name of the TensorFlow master.
  optional string eval_master = 7 [default = ""];

  // Type of metrics to use for evaluation.
  repeated string metrics_set = 8;

  // Type of metrics to use for evaluation. Unlike `metrics_set` above, this
  // field allows configuring evaluation metric through config files.
  repeated ParameterizedMetric parameterized_metric = 31;

  // Path to export detections to COCO compatible JSON format.
  optional string export_path = 9 [default =''];

  // Option to not read groundtruth labels and only export detections to
  // COCO-compatible JSON file.
  optional bool ignore_groundtruth = 10 [default = false];

  // Use exponential moving averages of variables for evaluation.
  // TODO(rathodv): When this is false make sure the model is constructed
  // without moving averages in restore_fn.
  optional bool use_moving_averages = 11 [default = false];

  // Whether to evaluate instance masks.
  // Note that since there is no evaluation code currently for instance
  // segmentation this option is unused.
  optional bool eval_instance_masks = 12 [default = false];

  // Minimum score threshold for a detected object box to be visualized
  optional float min_score_threshold = 13 [default = 0.5];

  // Maximum number of detections to visualize
  optional int32 max_num_boxes_to_visualize = 14 [default = 20];

  // When drawing a single detection, each label is by default visualized as
  // <label name> : <label score>. One can skip the name or/and score using the
  // following fields:
  optional bool skip_scores = 15 [default = false];
  optional bool skip_labels = 16 [default = false];

  // Whether to show groundtruth boxes in addition to detected boxes in
  // visualizations.
  optional bool visualize_groundtruth_boxes = 17 [default = false];

  // Box color for visualizing groundtruth boxes.
  optional string groundtruth_box_visualization_color = 18 [default = "black"];

  // Whether to keep image identifier in filename when exported to
  // visualization_export_dir.
  optional bool keep_image_id_for_visualization_export = 19 [default = false];

  // Whether to retain original images (i.e. not pre-processed) in the tensor
  // dictionary, so that they can be displayed in Tensorboard.
  optional bool retain_original_images = 23 [default = true];

  // If True, additionally include per-category metrics.
  optional bool include_metrics_per_category = 24 [default = false];

  // Optional super-category definitions: keys are super-category names;
  // values are comma-separated categories (assumed to correspond to category
  // names (`display_name`) in the label map.
  map<string, string> super_categories = 34;

  // Recall range within which precision should be computed.
  optional float recall_lower_bound = 26 [default = 0.0];
  optional float recall_upper_bound = 27 [default = 1.0];

  // Whether to retain additional channels (i.e. not pre-processed) in the
  // tensor dictionary, so that they can be displayed in Tensorboard.
  optional bool retain_original_image_additional_channels = 28
      [default = false];

  // When this flag is set, images are not resized during evaluation.
  // When this flag is not set (default case), image are resized according
  // to the image_resizer config in the model during evaluation.
  optional bool force_no_resize = 29 [default = false];

  // Whether to use a dummy loss in eval so model.loss() is not executed.
  optional bool use_dummy_loss_in_eval = 30 [default = false];

  // Specifies which keypoints should be connected by an edge, which may improve
  // visualization. An example would be human pose estimation where certain
  // joints can be connected.
  repeated KeypointEdge keypoint_edge = 32;

  // The "groundtruth_labeled_classes" field indicates which classes have been
  // labeled on the images. If skip_predictions_for_unlabeled_class is set,
  // detector predictions that do not match to the groundtruth_labeled_classes
  // will be ignored. This is useful for evaluating on test data that are not
  // exhaustively labeled.
  optional bool skip_predictions_for_unlabeled_class = 33 [default = false];
}

// A message to configure parameterized evaluation metric.
message ParameterizedMetric {
  oneof parameterized_metric {
    CocoKeypointMetrics coco_keypoint_metrics = 1;
  }
}

// A message to evaluate COCO keypoint metrics for a specific class.
message CocoKeypointMetrics {
  // Identifies the class of object to which keypoints belong. By default this
  // should use the class's "display_name" in the label map.
  optional string class_label = 1;
  // Keypoint specific standard deviations for COCO keypoint metrics, which
  // controls how OKS is computed.
  // See http://cocodataset.org/#keypoints-eval for details.
  // If your keypoints are similar to the COCO keypoints use the precomputed
  // standard deviations below:
  // "nose": 0.026
  // "left_eye": 0.025
  // "right_eye": 0.025
  // "left_ear": 0.035
  // "right_ear": 0.035
  // "left_shoulder": 0.079
  // "right_shoulder": 0.079
  // "left_elbow": 0.072
  // "right_elbow": 0.072
  // "left_wrist": 0.062
  // "right_wrist": 0.062
  // "left_hip": 0.107
  // "right_hip": 0.107
  // "left_knee": 0.087
  // "right_knee": 0.087
  // "left_ankle": 0.089
  // "right_ankle": 0.089
  map<string, float> keypoint_label_to_sigmas = 2;
}

// Defines an edge that should be drawn between two keypoints.
message KeypointEdge {
  // Index of the keypoint where the edge starts from. Index starts at 0.
  optional int32 start = 1;

  // Index of the keypoint where the edge ends. Index starts at 0.
  optional int32 end = 2;
}
