public:
virtual ~IMotionStabilizer() {}
- // assumes that [range.first, range.second) is in or equals to [0, size-2]
+ // assumes that [0, size-1) is in or equals to [range.first, range.second)
virtual void stabilize(
int size, const std::vector<Mat> &motions, std::pair<int,int> range,
Mat *stabilizationMotions) const = 0;
};
+class CV_EXPORTS MotionStabilizationPipeline : public IMotionStabilizer
+{
+public:
+ void pushBack(Ptr<IMotionStabilizer> stabilizer) { stabilizers_.push_back(stabilizer); }
+ bool empty() const { return stabilizers_.empty(); }
+
+ virtual void stabilize(
+ int size, const std::vector<Mat> &motions, std::pair<int,int> range,
+ Mat *stabilizationMotions) const;
+
+private:
+ std::vector<Ptr<IMotionStabilizer> > stabilizers_;
+};
+
class CV_EXPORTS MotionFilterBase : public IMotionStabilizer
{
public:
namespace videostab
{
+void MotionStabilizationPipeline::stabilize(
+ int size, const vector<Mat> &motions, pair<int,int> range,
+ Mat *stabilizationMotions) const
+{
+ vector<Mat> updatedMotions(motions);
+ vector<Mat> stabilizationMotions_(size);
+
+ for (int i = 0; i < size; ++i)
+ stabilizationMotions[i] = Mat::eye(3, 3, CV_32F);
+
+ for (size_t i = 0; i < stabilizers_.size(); ++i)
+ {
+ stabilizers_[i]->stabilize(size, updatedMotions, range, &stabilizationMotions_[0]);
+
+ for (int i = 0; i < size; ++i)
+ stabilizationMotions[i] = stabilizationMotions_[i] * stabilizationMotions[i];
+
+ for (int j = 0; j + 1 < size; ++j)
+ {
+ Mat S0 = stabilizationMotions[j];
+ Mat S1 = stabilizationMotions[j+1];
+ at(j, updatedMotions) = S1 * at(j, updatedMotions) * S0.inv();
+ }
+ }
+}
+
+
void MotionFilterBase::stabilize(
int size, const vector<Mat> &motions, pair<int,int> range, Mat *stabilizationMotions) const
{