// Protocol buffer for configuring DELF feature extraction.

syntax = "proto2";

package delf.protos;

message DelfPcaParameters {
  // Path to PCA mean file.
  optional string mean_path = 1;  // Required.

  // Path to PCA matrix file.
  optional string projection_matrix_path = 2;  // Required.

  // Dimensionality of feature after PCA.
  optional int32 pca_dim = 3;  // Required.

  // If whitening is to be used, this must be set to true.
  optional bool use_whitening = 4 [default = false];

  // Path to PCA variances file, used for whitening. This is used only if
  // use_whitening is set to true.
  optional string pca_variances_path = 5;
}

message DelfLocalFeatureConfig {
  // If PCA is to be used, this must be set to true.
  optional bool use_pca = 1 [default = true];

  // Target layer name for DELF model. This is used to obtain receptive field
  // parameters used for localizing features with respect to the input image.
  optional string layer_name = 2 [default = ""];

  // Intersection over union threshold for the non-max suppression (NMS)
  // operation. If two features overlap by at most this amount, both are kept.
  // Otherwise, the one with largest attention score is kept. This should be a
  // number between 0.0 (no region is selected) and 1.0 (all regions are
  // selected and NMS is not performed).
  optional float iou_threshold = 3 [default = 1.0];

  // Maximum number of features that will be selected. The features with largest
  // scores (eg, largest attention score if score_type is "Att") are the
  // selected ones.
  optional int32 max_feature_num = 4 [default = 1000];

  // Threshold to be used for feature selection: no feature with score lower
  // than this number will be selected).
  optional float score_threshold = 5 [default = 100.0];

  // PCA parameters for DELF local feature. This is used only if use_pca is
  // true.
  optional DelfPcaParameters pca_parameters = 6;

  // If true, the returned keypoint locations are grounded to coordinates of the
  // resized image used for extraction. If false (default), the returned
  // keypoint locations are grounded to coordinates of the original image that
  // is fed into feature extraction.
  optional bool use_resized_coordinates = 7 [default = false];
}

message DelfGlobalFeatureConfig {
  // If PCA is to be used, this must be set to true.
  optional bool use_pca = 1 [default = true];

  // PCA parameters for DELF global feature. This is used only if use_pca is
  // true.
  optional DelfPcaParameters pca_parameters = 2;

  // Denotes indices of DelfConfig's scales that will be used for global
  // descriptor extraction. For example, if DelfConfig's image_scales are
  // [0.25, 0.5, 1.0] and image_scales_ind is [0, 2], global descriptor
  // extraction will use solely scales [0.25, 1.0]. Note that local feature
  // extraction will still use [0.25, 0.5, 1.0] in this case. If empty (default)
  // , all scales are used.
  repeated int32 image_scales_ind = 3;
}

message DelfConfig {
  // Whether to extract local features when using the model.
  // At least one of {use_local_features, use_global_features} must be true.
  optional bool use_local_features = 7 [default = true];
  // Configuration used for local features. Note: this is used only if
  // use_local_features is true.
  optional DelfLocalFeatureConfig delf_local_config = 3;

  // Whether to extract global features when using the model.
  // At least one of {use_local_features, use_global_features} must be true.
  optional bool use_global_features = 8 [default = false];
  // Configuration used for global features. Note: this is used only if
  // use_global_features is true.
  optional DelfGlobalFeatureConfig delf_global_config = 9;

  // Path to DELF model.
  optional string model_path = 1;  // Required.

  // Whether model has been exported using TF version 2+.
  optional bool is_tf2_exported = 10 [default = false];

  // Image scales to be used.
  repeated float image_scales = 2;

  // Image resizing options.
  // - The maximum/minimum image size (in terms of height or width) to be used
  //   when extracting DELF features. If set to -1 (default), no upper/lower
  //   bound for image size. If use_square_images option is false  (default):
  //   * If the height *OR* width is larger than max_image_size, it will be
  //     resized to max_image_size, and the other dimension will be resized by
  //     preserving the aspect ratio.
  //   * If both height *AND* width are smaller than min_image_size, the larger
  //     side is set to min_image_size.
  // - If use_square_images option is true, it needs to be resized to square
  //   resolution. To be more specific:
  //   * If the height *OR* width is larger than max_image_size, it is resized
  //     to square resolution of max_image_size.
  //   * If both height *AND* width are smaller than min_image_size, it is
  //     resized to square resolution of min_image_size.
  //   * Else, if the input image's resolution is not square, it is resized to
  //     square resolution of the larger side.
  // Image resizing is useful when we want to ensure that the input to the image
  // pyramid has a reasonable number of pixels, which could have large impact in
  // terms of image matching performance.
  // When using local features, note that the feature locations and scales will
  // be consistent with the original image input size.
  // Note that when both max_image_size and min_image_size are specified
  // (which is a valid and legit use case), as long as max_image_size >=
  // min_image_size, there's no conflicting scenario (i.e. never triggers both
  // enlarging / shrinking). Bilinear interpolation is used.
  optional int32 max_image_size = 4 [default = -1];
  optional int32 min_image_size = 5 [default = -1];
  optional bool use_square_images = 6 [default = false];
}
