Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++/用于视频稳定的OpenCV-Kalman滤波器_C++_Opencv_Video_Kalman Filter - Fatal编程技术网

C++ C++/用于视频稳定的OpenCV-Kalman滤波器

C++ C++/用于视频稳定的OpenCV-Kalman滤波器,c++,opencv,video,kalman-filter,C++,Opencv,Video,Kalman Filter,我尝试用卡尔曼滤波器来稳定视频,使其平滑。但是我有一些问题 每次,我有两个帧:一个是当前帧,另一个是当前帧。 以下是我的工作流程: 计算goodFeaturesToTrack() 使用calcOpticalFlowPyrLK()计算光流 只保留好的观点 估计刚性变换 卡尔曼滤波平滑 扭曲图片 但我认为Kalman有点问题,因为最后我的视频仍然不稳定,一点也不平滑,甚至比原来的更糟 这是我的Kalman代码 void StabilizationTestSimple2::init_kalman(

我尝试用卡尔曼滤波器来稳定视频,使其平滑。但是我有一些问题

每次,我有两个帧:一个是当前帧,另一个是当前帧。 以下是我的工作流程:

  • 计算goodFeaturesToTrack()
  • 使用calcOpticalFlowPyrLK()计算光流
  • 只保留好的观点
  • 估计刚性变换
  • 卡尔曼滤波平滑
  • 扭曲图片
但我认为Kalman有点问题,因为最后我的视频仍然不稳定,一点也不平滑,甚至比原来的更糟

这是我的Kalman代码

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));
}
void StabilizationTestSimple2::init_kalman(双x,双y)
{
KF.statePre.at(0)=x;
KF.statePre.at(1)=y;
KF.statePre.at(2)=0;
KF.statePre.at(3)=0;

KF.transitionMatrix=*(Mat_u4,4)
KF.transitionMatrix=*(Mat_4,4)谢谢你的回答。实际上在做这件事之前,我不知道卡尔曼滤波器,所以我试着读了一些关于它的文章,现在我知道了它的工作原理。但这是真的,尽管我知道它是如何工作的,但我真的不知道如何为我的问题设置我自己的参数,因此我没有真正知道。我想我使用的是像素d不是米。那么我的视频的帧速率大约是25-27fps。但是是的,如果你能解释一下你是如何设置processNoisCov、setIdentity和measurementNoiseCov的,它可以帮我很多忙。提前谢谢你!@lilouch:补充了更多。谢谢你的回答。这在我的头脑中变得更清晰了,但仍然有些不理解。实际上我想估计两帧之间的变换(由EstimaterialDigTransform()得到),这就是为什么我不想预测速度。实际上我想预测x,y和teta,但我不知道如何将θ放在我的系统中,这就是为什么我没有将它放在我的系统中(错误)。这只是一个有3行和3列(x,y,theta)的变换矩阵吗否则,如果我没有速度,怎么能“预测”所有协方差矩阵?仅仅通过“猜测”?你所说的“测量中的加性协方差noisecov是每帧相加的,所以请记住所表示的变化超过1/25秒”是什么意思在我的过程中,我必须为每一帧添加一个术语?非常感谢。您的测量值是
z=H*x
,或者用您的术语
meas=measurementMatrix*statePost
。现在您正在将
measurementMatrix
设置为identity,这意味着您测量您的状态变量。如果您只能测量positi在上,您的矩阵应该是非正方形的:
[[1 0 0],[0 1 0]]
这样它会产生一个测量值
[x y]'
您的
测量值noisecov
将仅为2x2。
    /// 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);


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