// Copyright 2019 The MediaPipe Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Motion models, that are supported and estimated by MotionStabilization.
// Note, that transformations represent the motion of the
// feature points from the previous frame to the current one.
// Note that the actual camera movement, is the inverse of this
// transformation.
// Check carefully, which movement (feature or camera) is required.
// Note that for each model the default values always specify an identity
// transform. Follow this rule when adding new models.

syntax = "proto2";

package mediapipe;

// Here x represents a 2D point in the image plane, in the following
// coordinate system:
// *----> x
// |
// |
// v  y

// Simple translational model:
// I * x + [dx; dy]   with I being 2x2 identity transform.
message TranslationModel {
  optional float dx = 1 [default = 0];
  optional float dy = 2 [default = 0];
}

// Non-linear similarity model (w.r.t. to its parametrization).
// c_r := cos(rotation);
// s_r := sin(rotation);
// Transformation applied to x:
// [scale 0;      * [c_r  -s_r;   * x  + [dx;
//  0     scale]     s_r   c_r]           dy]
message SimilarityModel {
  optional float dx = 1 [default = 0];
  optional float dy = 2 [default = 0];
  optional float scale = 3 [default = 1];
  optional float rotation = 4 [default = 0];  // angle in [-pi, pi].
}

// Linear similarity model:
//  [a -b;   * x + [dx;
//   b  a]          dy]
message LinearSimilarityModel {
  optional float dx = 1 [default = 0];
  optional float dy = 2 [default = 0];
  optional float a = 3 [default = 1];
  optional float b = 4 [default = 0];
}

// Affine according to
//  (  [a b  * x + [dx;
//  (   c d]        dy]
message AffineModel {
  optional float dx = 1 [default = 0];
  optional float dy = 2 [default = 0];
  optional float a = 3 [default = 1];
  optional float b = 4 [default = 0];
  optional float c = 5 [default = 0];
  optional float d = 6 [default = 1];
}

// Homography according to
// [h_00 h_01 h_02;
//  h_10 h_11 h_12;
//  h_20 h_21 1];
//  Note: The parametrization with h_22 = 1 does not always hold, e.g.
//        if the origin (0, 0, 1) gets mapped to the line at infinity
//        (0, 0, 1). However for video we expect small perspective
//        changes between frames and this parametrization improves
//        robustness greatly as it removes an additional DOF.
//        Therefore, all methods in motion_stabilization should not be
//        used for general wide-baseline matching of frames.
message Homography {
  optional float h_00 = 1 [default = 1];
  optional float h_01 = 2 [default = 0];
  optional float h_02 = 3 [default = 0];
  optional float h_10 = 4 [default = 0];
  optional float h_11 = 5 [default = 1];
  optional float h_12 = 6 [default = 0];
  optional float h_20 = 7 [default = 0];
  optional float h_21 = 8 [default = 0];
}

// Mixture models with higher degrees of freedom, according to
// \sum_i model(i) * weight(i), where weights are passed during transform and
// are expected to sum to one.
message MixtureLinearSimilarity {
  repeated LinearSimilarityModel model = 1;
}

message MixtureAffine {
  repeated AffineModel model = 1;
}

message MixtureHomography {
  repeated Homography model = 1;
  // Specifies which degree of freedom vary across mixture.
  // Can be used to implement several transformation functions quicker.
  enum VariableDOF {
    ALL_DOF = 0;            // All dof are variable.
    TRANSLATION_DOF = 1;    // Only translation (h_02, h_12) varies.
    SKEW_ROTATION_DOF = 2;  // Translation (h_02, h_12), and skew-rotation
                            // (h_01, h_10) vary.
    CONST_DOF = 3;          // Mixture is constant.
  }
  optional VariableDOF dof = 2 [default = ALL_DOF];
}
