记录 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);
    }
   


}
相关推荐
YHHLAI11 小时前
LeetCode 1.两数之和 | 从暴力枚举到线性优化
算法·leetcode·职场和发展
Urbano11 小时前
工装标准缝纫流程及自动化升级提质增产方案
大数据·人工智能·算法
KaMeidebaby12 小时前
卡梅德生物技术快报|biotin 生物素标记抗体全流程
前端·人工智能·算法·数据挖掘·数据分析
阳明山水12 小时前
自下而上 vs 自上而下 vs 最优组合预测策略解析
大数据·人工智能·深度学习·算法·机器学习
keykey6.12 小时前
从逻辑回归到 SVM:不仅仅是“分开“
算法·机器学习·支持向量机
QN1幻化引擎12 小时前
RingBuffer:用"循环缓冲区"干掉KV Cache的O(n)显存膨胀
算法·github
papership12 小时前
【入门级-算法-8、图论算法:泛洪算法 (Flood Fill)】
算法·图论
MartinYeung512 小时前
[论文学习]LLM 情境学习资料的快速精确遗忘技术:基于 In-Context Learning 与量化 K-Means 的 ERASE 方法
学习·算法·kmeans
林森lsjs12 小时前
【日耕一题】5. 青春常数(17届蓝桥杯C++B组第一题)
算法·蓝桥杯
Tisfy12 小时前
LeetCode 3838.带权单词映射:求和、取模、拼接(附python一行版)
python·算法·leetcode·字符串·题解·模拟·取模