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


}
相关推荐
ForDreamMusk1 小时前
批量归一化
人工智能·算法·机器学习
Ivanqhz2 小时前
刚体的自由度
人工智能·算法
KaMeidebaby2 小时前
卡梅德生物技术快报|抗体合成:多肽抗体合成工程化方案:Nsp2 保守肽多抗制备与多维度验证
前端·网络·数据库·人工智能·算法
Yang_jie_033 小时前
笔记:数据结构(栈是否使用底指针以及头指针的初始化值)
数据结构·笔记·算法
2301_800895103 小时前
信息安全数学基础复习
算法
爱折腾的小黑牛3 小时前
简记往来批量录入功能的实现:从文本到结构化数据
前端·算法
Starmoon_dhw4 小时前
题解:P17078 夏日甜点
c++·学习·算法·图论
海石4 小时前
【JS击败90%】前缀和+定长滑动窗口
算法·leetcode
Tisfy5 小时前
LeetCode 2685.统计完全连通分量的数量:DFS求每个连通块的边点数
算法·leetcode·深度优先··题解·连通图·全连通分量
海石5 小时前
1次遍历,空间复杂度击败100%,时间复杂度击败85%
算法·leetcode