记录 MeshFlow-Online-Video-Stabilization 在线稳像

MeshFlow-Online-Video-Stabilization

src/Optimization.cpp

cpp 复制代码
double Optimizer::computeDefaultLambda(int windowSize, int bufferSize) {
    int half = windowSize / 2;
    double totalRowSum = 0.0;
    for (int t = 0; t < bufferSize; ++t) {
        double rowSum = 0.0;
        for (int d = -half; d <= half; ++d) {
            if (d == 0) continue;
            int r = t + d;
            if (r < 0 || r >= bufferSize) continue;
            double w = exp(-9.0 * d * d / (windowSize * windowSize));
            rowSum += w;
        }
        totalRowSum += rowSum;
    }
    double avgRowSum = totalRowSum / bufferSize;
    double lambda = 10.0 / avgRowSum;
    // 限制范围
    lambda = std::max(2.0, std::min(20.0, lambda));
    return lambda;
}
void Optimizer::onlinePathOptimization(const vector<Mat>& cameraPath,
    vector<Mat>& optimizedPath,
    int bufferSize,
    int iterations,
    int windowSize,
    int beta) {

    double lambda_t = 100; // TODO: make lambda adaptive
    //double lambda_t = computeDefaultLambda(windowSize, bufferSize);
    optimizedPath.reserve(cameraPath.size());
    for (int i = 0; i < cameraPath.size(); ++i) {
        optimizedPath.push_back(Mat::zeros(cameraPath.back().rows, cameraPath.back().cols, CV_64F));
    }

    /// Fill in the weights
    Mat W(bufferSize, bufferSize, CV_64F);
    for (int i = 0; i < W.rows; ++i) {
        for (int j = 0; j < W.cols; ++j) {
            W.at<double>(i, j) = gauss(i, j, windowSize);
        }
    }




    /// Iterative optimization process



    for (int i = 0; i < cameraPath.back().rows; ++i) {
        for (int j = 0; j < cameraPath.back().cols; ++j) {
            // y = []; d = None
            vector<double> y;
            Mat d, P;
            // Real-time optimization
            for (int t = 1; t < cameraPath.size() + 1; ++t) {
                if (t < bufferSize + 1) {
                    Mat camPath = getCamPath(cameraPath, i, j, t);
                    camPath.copyTo(P);

                    if (!d.empty()) {
                        for (int k = 0; k < iterations; ++k) {
                            Mat Wt = getW(W, t);
                            Mat alpha = camPath + lambda_t * Wt * P;
                            Mat gamma = 1 + lambda_t * getW(W, t) * Mat::ones(t, 1, CV_64F);

                            for (int m = 0; m < alpha.cols - 1; ++m) {
                                alpha.at<double>(m) += beta * d.at<double>(m);
                                gamma.at<double>(m) += beta;
                            }
                            P = alpha / gamma;
                        }
                    }
                }
                else {
                    Mat camPath = getCamPath(cameraPath, i, j, t - bufferSize, t);
                    camPath.copyTo(P);

                    for (int k = 0; k < iterations; ++k) {
                        Mat alpha = camPath + lambda_t * W * P;
                        Mat gamma = 1 + lambda_t * W * Mat::ones(bufferSize, 1, CV_64F);

                        for (int m = 0; m < alpha.cols - 1; ++m) {
                            alpha.at<double>(m) += beta * d.at<double>(m + 1);
                            gamma.at<double>(m) += beta;
                        }
                        P = alpha / gamma;
                    }
                }
                d = P;
                y.push_back(P.at<double>(P.rows - 1));
            }
            for (int m = 0; m < y.size(); ++m) {
                optimizedPath[m].at<double>(i, j) = y[m];
            }
        }
    }




    vector<Mat> cameraPath2;
    vector<Mat> optimizedPath2;
    optimizedPath2.reserve(cameraPath.size());
    cameraPath2.reserve(cameraPath.size());
    for (int i = 0; i < cameraPath.size(); ++i) {
        cameraPath2.push_back(cameraPath[i].clone());
        optimizedPath2.push_back(Mat::zeros(cameraPath.back().rows, cameraPath.back().cols, CV_64F));
    }

    for (int i = 0; i < cameraPath.back().rows; ++i) {
        for (int j = 0; j < cameraPath.back().cols; ++j) {
            // y = []; d = None
            vector<double> y;
            Mat d, P;
            // Real-time optimization
            for (int t = 1; t < cameraPath.size() + 1; ++t) {
                if (t < bufferSize + 1) {
                    Mat camPath = getCamPath(cameraPath, i, j, t);
                    camPath.copyTo(P);

                    if (!d.empty()) {
                        for (int k = 0; k < iterations; ++k) {
                            Mat Wt = getW(W, t);
                            Mat alpha = camPath + lambda_t * Wt * P;
                            Mat gamma = 1 + lambda_t * getW(W, t) * Mat::ones(t, 1, CV_64F);

                            for (int m = 0; m < alpha.cols - 1; ++m) {
                                alpha.at<double>(m) += beta * d.at<double>(m);
                                gamma.at<double>(m) += beta;
                            }
                            P = alpha / gamma;
                        }
                    }
                }
                else {

                    auto refV = cameraPath[t - bufferSize].at<double>(i, j);
                    auto prevRefV = cameraPath[t - bufferSize - 1].at<double>(i, j);

                    for (int kk = t - bufferSize, jj = 0; kk < t; ++kk, ++jj) {
                        cameraPath2[kk].at<double>(i, j) = cameraPath[t - bufferSize + jj].at<double>(i, j) - refV;
                    }
                    /*Mat camPath(bufferSize, 1, CV_64F);
                    for (int kk = 0; kk < bufferSize; ++kk) {
                        camPath.at<double>(kk) = cameraPath[t - bufferSize + kk].at<double>(i, j) - refV;
                    }*/

                    double deltaRef = refV - prevRefV;
                    for (int kk = 0; kk < d.rows; ++kk) {
                        d.at<double>(kk) -= deltaRef;
                    }


                    /*for (int kk = 0;kk < d.rows;++kk)
                    {
                        d.at<double>(kk) -= refVPrev;
                    }*/

                    Mat camPath = getCamPath(cameraPath2, i, j, t - bufferSize, t);
                    camPath.copyTo(P);

                    //P = camPath.clone();

                    for (int k = 0; k < iterations; ++k) {
                        Mat alpha = camPath + lambda_t * W * P;
                        Mat gamma = 1 + lambda_t * W * Mat::ones(bufferSize, 1, CV_64F);

                        for (int m = 0; m < alpha.cols - 1; ++m) {
                            alpha.at<double>(m) += beta * d.at<double>(m + 1);
                            gamma.at<double>(m) += beta;
                        }
                        P = alpha / gamma;
                    }


                }
                d = P;
                y.push_back(P.at<double>(P.rows - 1));
            }
            for (int m = 0; m < y.size(); ++m) {
                optimizedPath2[m].at<double>(i, j) = y[m];
            }
        }
    }
    vector<std::pair<double, double>> OPathA(cameraPath.size());
    vector<std::pair<double, double>> OPathB(cameraPath.size());
    vector<std::pair<double, double>> OPathC(cameraPath.size());
    cv::Point pos(cameraPath[0].cols/2, cameraPath[0].rows / 2);
    for (int i = 0;i < OPathA.size();i++) {
       
        OPathA[i] = std::make_pair<>(i, cameraPath[i].at<double>(pos));

        OPathB[i] = std::make_pair<>(i, optimizedPath[i].at<double>(pos));
        OPathC[i] = std::make_pair<>(i, optimizedPath2[i].at<double>(pos));
        if(i>=bufferSize)
            OPathC[i].second+= cameraPath[i- bufferSize+1].at<double>(pos);
    }
   


}
相关推荐
code_pgf1 小时前
Octo 算法详解-开源通用机器人策略模型技术报告
算法·机器人·开源
嘻嘻哈哈樱桃1 小时前
牛客经典101题题解集--动态规划
java·数据结构·python·算法·职场和发展·动态规划
脱氧核糖核酸__1 小时前
LeetCode热题100——234.回文链表(两种解法)
c++·算法·leetcode·链表
IronMurphy1 小时前
【算法四十二】118. 杨辉三角 198. 打家劫舍
算法
电科一班林耿超1 小时前
第 16 课:动态规划专题(二)—— 子序列与子数组问题:面试最高频的 DP 题型
数据结构·算法·动态规划
生信研究猿2 小时前
leetcode 416. 分割等和子集
算法·leetcode·职场和发展
狗哥哥2 小时前
面包屑自动推导的算法设计:从“最短路径匹配”到工程可落地
算法·架构
隔壁大炮3 小时前
Day07-RNN介绍
人工智能·pytorch·rnn·深度学习·神经网络·算法·numpy
WL_Aurora3 小时前
Python 算法基础篇之什么是算法
python·算法