C++/OpenCV - 用于视频稳定的卡尔曼滤波器

2024-04-25

我尝试使用卡尔曼滤波器稳定视频以进行平滑。但我有一些问题

每次,我都有两帧:一帧是当前帧,另一帧是当前帧。 这是我的工作流程:

  • 计算 goodFeaturesToTrack()
  • 使用 calcOpticalFlowPyrLK() 计算光流
  • 只保留优点
  • 估计刚性变换
  • 使用卡尔曼滤波器进行平滑
  • 图片扭曲。

但我认为卡尔曼有问题,因为最后我的视频仍然不稳定,而且一点也不流畅,甚至比原来的还要糟糕......

这是我的卡尔曼代码

void StabilizationTestSimple2::init_kalman(double x, double y)
{

    KF.statePre.at<float>(0) = x;
    KF.statePre.at<float>(1) = y;
    KF.statePre.at<float>(2) = 0;
    KF.statePre.at<float>(3) = 0;

    KF.transitionMatrix = *(Mat_<float>(4,4) << 1,0,1,0,    0,1,0,1,     0,0,1,0,   0,0,0,1);
    KF.processNoiseCov = *(Mat_<float>(4,4) << 0.2,0,0.2,0,  0,0.2,0,0.2,  0,0,0.3,0,
                           0,0,0,0.3);
    setIdentity(KF.measurementMatrix);
    setIdentity(KF.processNoiseCov,Scalar::all(1e-6));
    setIdentity(KF.measurementNoiseCov,Scalar::all(1e-1));
    setIdentity(KF.errorCovPost, Scalar::all(.1));
}

这是我如何使用它的。我只放了有趣的部分。所有这些代码都在 flor 循环内。 cornerPrev2和cornerCurr2包含之前检测到的所有特征点(使用calcOpticalFlowPyrLK())

    /// Transformation
    Mat transformMatrix = estimateRigidTransform(cornersPrev2,cornersCurr2 ,false);

    // in rare cases no transform is found. We'll just use the last known good transform.
    if(transformMatrix.data == NULL) {
        last_transformationmatrix.copyTo(transformMatrix);
    }

    transformMatrix.copyTo(last_transformationmatrix);

    // decompose T
    double dx = transformMatrix.at<double>(0,2);
    double dy = transformMatrix.at<double>(1,2);
    double da = atan2(transformMatrix.at<double>(1,0), transformMatrix.at<double>(0,0));

    // Accumulated frame to frame transform
    x += dx;
    y += dy;
    a += da;
    std::cout << "accumulated x,y: (" << x << "," << y << ")" << endl;

    if (compteur==0){
        init_kalman(x,y);
    }
    else {


          vector<Point2f> smooth_feature_point;
          Point2f smooth_feature=kalman_predict_correct(x,y);
          smooth_feature_point.push_back(smooth_feature);
          std::cout << "smooth x,y: (" << smooth_feature.x << "," << smooth_feature.y << ")" << endl;

          // target - current
          double diff_x = smooth_feature.x - x;//
          double diff_y = smooth_feature.y - y;

          dx = dx + diff_x;
          dy = dy + diff_y;

          transformMatrix.at<double>(0,0) = cos(da);
          transformMatrix.at<double>(0,1) = -sin(da);
          transformMatrix.at<double>(1,0) = sin(da);
          transformMatrix.at<double>(1,1) = cos(da);
          transformMatrix.at<double>(0,2) = dx;
          transformMatrix.at<double>(1,2) = dy;

          warpAffine(currFrame,outImg,transformMatrix,prevFrame.size(), INTER_NEAREST|WARP_INVERSE_MAP, BORDER_CONSTANT);

          namedWindow("stabilized");
          imshow("stabilized",outImg);
          namedWindow("Original");
          imshow("Original",originalFrame);


    }

有人能知道为什么它不起作用吗?

Thank


KF.transitionMatrix = *(Mat_<float>(4,4) << 1,0,1,0,    0,1,0,1,     0,0,1,0,   0,0,0,1);
KF.processNoiseCov = *(Mat_<float>(4,4) << 0.2,0,0.2,0,  0,0.2,0,0.2,  0,0,0.3,0,
                       0,0,0,0.3);
setIdentity(KF.measurementMatrix);
setIdentity(KF.processNoiseCov,Scalar::all(1e-6));
setIdentity(KF.measurementNoiseCov,Scalar::all(1e-1));
setIdentity(KF.errorCovPost, Scalar::all(.1));

Your processNoiseCov不是对称的,我怀疑你是否有正确的非对角线项。我会坚持使用对角矩阵,直到你更好地理解 KF。

另一方面,你似乎立即用它覆盖它setIdentity值很小,这可能是一个错误。也许您在遇到上面的无效矩阵问题后添加了这一点?

如果您描述了帧速率和状态单位(米?像素?),我们可以讨论如何选择合适的值processNoiseCov and measurementNoiseCov.

EDIT:

好的,鉴于您的州是[ x_pixels, y_pixels, dx_pixels, dy_pixels ]这里有一些提示:

  • 你的测量矩阵是I所以你是说你正在测量与你的状态完全相同的东西(这有点不常见:通常你只会测量你的状态的一些子集,例如你在测量中没有速度的估计)。
  • 鉴于您的测量矩阵是I的意义processNoiseCov and measurementNoiseCov类似,所以我将它们放在一起讨论。你的processNoiseCov应该是一个对角矩阵,其中每一项都是variance(标准差的平方)这些值在帧之间如何变化。例如,如果有 68% 的机会(参见正态分布)如果您的像素偏移量在每帧 100 像素以内,则位置的对角线条目应该是100 * 100 = 10000(记住,方差是 stddev 的平方)。您需要对速度如何变化进行类似的估计。 (高级:应该有共变(非对角线)项,因为速度的变化与位置的变化有关,但你可以不用这个,直到你明白为止。我已经在其他答案中解释过)。
  • 您的加性协方差processNoiseCov添加每个frame因此请记住,所表示的变化超过 1/25 秒。
  • Your measurementNoiseCov具有相同类型的单位(同样,测量矩阵是单位),但应反映您的测量与不可知的实际真实值相比的准确程度。
  • 通常,您可以测量过程和测量的实际值,并计算它们的实际协方差(在 excel 或 python 或 Matlab 等中)。
  • Your errorCovPost是您的初始不确定性,就像每帧加性协方差一样表达,但它描述了您对初始状态正确性的确定程度。
  • 正确获得这些协方差矩阵是最重要的事情使用 IF 时。在设计 KF 时,你总是会花更多的时间来解决这些问题,而不是做其他事情。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++/OpenCV - 用于视频稳定的卡尔曼滤波器 的相关文章

随机推荐

  • 使用 ffmpeg 转换真实媒体

    我有许多旧的硬壳真实媒体文件需要转换 并希望编写一个脚本来批量处理它们 我可以使用 FFMpegX 进行 Real Media gt AVI 转换 但是当我尝试使用 ffmpeg 复制转换时 它总是会出现如下错误 avi 0x10084fa
  • 用户状态(秒差距)

    我正在使用秒差距解析一个表达式 并且我想使用秒差距中的用户状态来跟踪这些表达式中的变量 不幸的是我真的不知道该怎么做 给出以下代码 import Data Set as Set inp x y z data Var V String var
  • django 在我的机器上非常慢

    我全新安装了 django 1 0 并提供了一个简单的页面 需要 5 秒才能加载 在我同事的计算机上几乎不需要时间 我使用启动服务器 python manage py testserver 我可以看到每个 GET 请求 PNG 和样式表 大
  • NodeJS 获取承诺回调挂起

    我有这个代码 fetch url then response gt const json response json console log simplest possible fetch json json where 在控制台中我得到
  • Visual Studio 中用于在 Windows 文件资源管理器中打开解决方案的快捷方式?

    Visual Studio 当前使用2013 中是否有键盘快捷键可以在Windows文件资源管理器中打开解决方案 或项目 目前 我通常必须打开解决方案资源管理器 右键单击我的解决方案或项目 然后向下滚动到 在文件资源管理器中打开文件夹 但这
  • 如何使用 printf 自定义自定义类型的输出?

    我已经阅读了很多内容专家 F 并正在致力于构建一个实际的应用程序 在调试时 我已经习惯了传递这样的 fsi 命令 以使 repl 窗口中的内容清晰可见 fsi AddPrinter fun x myType gt myType ToStri
  • 为什么叫彩虹桌呢?

    有人知道为什么叫彩虹桌吗 刚刚记得我们已经了解到有一种称为 字典攻击 的攻击 为什么不叫字典呢 因为它包含了整个可能性的 范围 字典攻击是一种尝试可能性的暴力技术 像这样 python伪代码 mypassworddict dict for
  • 如何在oracle中的字母数字列中使用order by

    在我的表的一列中 我有一个如下所示的值 Y 1 Y 2 Y 3 Y 4 Y 5 Y 6 Y 7 Y 8 Y 9 Y 10 Y 11 Y 12 Y 13 Y 14 当我按此列排序时 如果该行的值高达 Y 9 则它工作正常 否则我的结果是错误的
  • 使用objectid解析ios wherekey

    In my Message Parse 中的表有一个名为对话的字段 它是一个pointer to a Conversation 我的数据库中的另一个表 查询一个Message 我可不可以做 PFQuery messageQuery PFQu
  • MVC 6 中的捆绑和缩小

    看起来捆绑和缩小不再内置于 MVC 6 中 因为不再有App Start and Bundle Config 最终版本发布后会出现这种情况吗 我猜应该使用 Grunt 因为它似乎已融入 Visual Studio 2015 中 UPDATE
  • UIWebView 和 NSURLConnection 共享 cookie 存储吗?

    我正在构建一个使用 Google App Engine 作为后端的 iOS 应用程序 Google 提供了一个存储身份验证 cookie 的 HTML 登录站点 如果我在 UIWebView 中访问该站点并且用户登录 那么这些 cookie
  • XNA 4:导入 FBX 问题

    我在从 FBX 文件导入 3D 模型时遇到问题 源模型包含 575 个对象 1 个相机 如下所示 http habreffect ru files 23d 542fa7f67 source model png http habreffect
  • 如何检查.NET Core中是否存在配置节?

    如何检查配置节是否存在于appsettings json在 NET Core 中 即使某个部分不存在 以下代码也将始终返回一个实例化实例 e g var section this Configuration GetSection
  • Xcode10 - dyld:未加载框架中安装的 pod 的库

    我有一个带有目标框架的项目 主应用程序目标 框架A FrameworkA 是唯一使用某个 pod 的框架 因此在我的 pod 文件中我有类似的内容 target MainAppTarget do end target FrameworkA
  • 从更新面板异步回发后保持滚动位置

    我在使用 ASP NET 和更新面板时遇到一些问题 问题是 每次从更新面板发生部分回发时 页面都会滚动回顶部 在我的大多数页面上 这并不是一个大问题 但在某些页面上可能会变得很长 然后 当用户位于页面底部时 我显示 jQuery 弹出窗口R
  • 在 Sublime Text 3 中,我可以将 do 文件的选择发送到 Stata 吗?

    This SO question https stackoverflow com questions 18361667 is there a command line editor that highlights the stata syn
  • 为什么我删除的函数在 Node.js 中不是 typeof“undefined”?

    我正在使用 Node js 在我的 sum 函数被删除后 我希望 typeof sum 返回 undefined 但事实并非如此 functions are data in Javascript var sum function a b r
  • JQuery 模糊动画

    我使用以下脚本在单击按钮时模糊一个框 但如何使模糊需要 500 毫秒 document ready function attach click event to button button click function when butto
  • oracle sql if条件然后选择语句1 else选择语句2

    我有参数 prmtr我想要的是根据参数输入使用 select 语句 我试过这个 if prmtr A then select from tblA else select from tblB end if 但这是行不通的 还有其他方法可以做到
  • C++/OpenCV - 用于视频稳定的卡尔曼滤波器

    我尝试使用卡尔曼滤波器稳定视频以进行平滑 但我有一些问题 每次 我都有两帧 一帧是当前帧 另一帧是当前帧 这是我的工作流程 计算 goodFeaturesToTrack 使用 calcOpticalFlowPyrLK 计算光流 只保留优点