class BackgroundSubtractorPerfTest:
public TestPerfParams<tuple<cv::gapi::video::BackgroundSubtractorType, std::string,
bool, double, std::size_t, cv::GCompileArgs, CompareMats>> {};
+
+class KalmanFilterControlPerfTest :
+ public TestPerfParams<tuple<MatType2, int, int, size_t, bool, cv::GCompileArgs>> {};
+class KalmanFilterNoControlPerfTest :
+ public TestPerfParams<tuple<MatType2, int, int, size_t, bool, cv::GCompileArgs>> {};
+
} // opencv_test
#endif // OPENCV_GAPI_VIDEO_PERF_TESTS_HPP
//------------------------------------------------------------------------------
+inline void generateInputKalman(const int mDim, const MatType2& type,
+ const size_t testNumMeasurements, const bool receiveRandMeas,
+ std::vector<bool>& haveMeasurements,
+ std::vector<cv::Mat>& measurements)
+{
+ cv::RNG& rng = cv::theRNG();
+ measurements.clear();
+ haveMeasurements = std::vector<bool>(testNumMeasurements, true);
+ for (size_t i = 0; i < testNumMeasurements; i++)
+ {
+ if (receiveRandMeas)
+ {
+ haveMeasurements[i] = rng(2u) == 1; // returns 0 or 1 - whether we have measurement
+ // at this iteration or not
+ } // if not - testing the slowest case in which we have measurements at every iteration
+
+ cv::Mat measurement = cv::Mat::zeros(mDim, 1, type);
+ if (haveMeasurements[i])
+ {
+ cv::randu(measurement, cv::Scalar::all(-1), cv::Scalar::all(1));
+ }
+ measurements.push_back(measurement.clone());
+ }
+}
+
+inline void generateInputKalman(const int mDim, const int cDim, const MatType2& type,
+ const size_t testNumMeasurements, const bool receiveRandMeas,
+ std::vector<bool>& haveMeasurements,
+ std::vector<cv::Mat>& measurements,
+ std::vector<cv::Mat>& ctrls)
+{
+ generateInputKalman(mDim, type, testNumMeasurements, receiveRandMeas,
+ haveMeasurements, measurements);
+ ctrls.clear();
+ cv::Mat ctrl(cDim, 1, type);
+ for (size_t i = 0; i < testNumMeasurements; i++)
+ {
+ cv::randu(ctrl, cv::Scalar::all(-1), cv::Scalar::all(1));
+ ctrls.push_back(ctrl.clone());
+ }
+}
+
+PERF_TEST_P_(KalmanFilterControlPerfTest, TestPerformance)
+{
+ MatType2 type = -1;
+ int dDim = -1, mDim = -1;
+ size_t testNumMeasurements = 0;
+ bool receiveRandMeas = true;
+ cv::GCompileArgs compileArgs;
+ std::tie(type, dDim, mDim, testNumMeasurements, receiveRandMeas, compileArgs) = GetParam();
+
+ const int cDim = 2;
+ cv::gapi::KalmanParams kp;
+ initKalmanParams(type, dDim, mDim, cDim, kp);
+
+ // Generating input
+ std::vector<bool> haveMeasurements;
+ std::vector<cv::Mat> measurements, ctrls;
+ generateInputKalman(mDim, cDim, type, testNumMeasurements, receiveRandMeas,
+ haveMeasurements, measurements, ctrls);
+
+ // G-API graph declaration
+ cv::GMat m, ctrl;
+ cv::GOpaque<bool> have_m;
+ cv::GMat out = cv::gapi::KalmanFilter(m, have_m, ctrl, kp);
+ cv::GComputation c(cv::GIn(m, have_m, ctrl), cv::GOut(out));
+ auto cc = c.compile(
+ cv::descr_of(cv::gin(cv::Mat(mDim, 1, type), true, cv::Mat(cDim, 1, type))),
+ std::move(compileArgs));
+
+ cv::Mat gapiKState(dDim, 1, type);
+ TEST_CYCLE()
+ {
+ cc.prepareForNewStream();
+ for (size_t i = 0; i < testNumMeasurements; i++)
+ {
+ bool hvMeas = haveMeasurements[i];
+ cc(cv::gin(measurements[i], hvMeas, ctrls[i]), cv::gout(gapiKState));
+ }
+ }
+
+ // OpenCV reference KalmanFilter initialization
+ cv::KalmanFilter ocvKalman(dDim, mDim, cDim, type);
+ initKalmanFilter(kp, true, ocvKalman);
+
+ cv::Mat ocvKState(dDim, 1, type);
+ for (size_t i = 0; i < testNumMeasurements; i++)
+ {
+ ocvKState = ocvKalman.predict(ctrls[i]);
+ if (haveMeasurements[i])
+ ocvKState = ocvKalman.correct(measurements[i]);
+ }
+ // Validation
+ EXPECT_TRUE(AbsExact().to_compare_f()(gapiKState, ocvKState));
+ SANITY_CHECK_NOTHING();
+}
+
+PERF_TEST_P_(KalmanFilterNoControlPerfTest, TestPerformance)
+{
+ MatType2 type = -1;
+ int dDim = -1, mDim = -1;
+ size_t testNumMeasurements = 0;
+ bool receiveRandMeas = true;
+ cv::GCompileArgs compileArgs;
+ std::tie(type, dDim, mDim, testNumMeasurements, receiveRandMeas, compileArgs) = GetParam();
+
+ const int cDim = 0;
+ cv::gapi::KalmanParams kp;
+ initKalmanParams(type, dDim, mDim, cDim, kp);
+
+ // Generating input
+ std::vector<bool> haveMeasurements;
+ std::vector<cv::Mat> measurements;
+ generateInputKalman(mDim, type, testNumMeasurements, receiveRandMeas,
+ haveMeasurements, measurements);
+
+ // G-API graph declaration
+ cv::GMat m;
+ cv::GOpaque<bool> have_m;
+ cv::GMat out = cv::gapi::KalmanFilter(m, have_m, kp);
+ cv::GComputation c(cv::GIn(m, have_m), cv::GOut(out));
+ auto cc = c.compile(cv::descr_of(cv::gin(cv::Mat(mDim, 1, type), true)),
+ std::move(compileArgs));
+
+ cv::Mat gapiKState(dDim, 1, type);
+ TEST_CYCLE()
+ {
+ cc.prepareForNewStream();
+ for (size_t i = 0; i < testNumMeasurements; i++)
+ {
+ bool hvMeas = haveMeasurements[i];
+ cc(cv::gin(measurements[i], hvMeas), cv::gout(gapiKState));
+ }
+ }
+
+ // OpenCV reference KalmanFilter declaration
+ cv::KalmanFilter ocvKalman(dDim, mDim, cDim, type);
+ initKalmanFilter(kp, false, ocvKalman);
+
+ cv::Mat ocvKState(dDim, 1, type);
+ for (size_t i = 0; i < testNumMeasurements; i++)
+ {
+ ocvKState = ocvKalman.predict();
+ if (haveMeasurements[i])
+ ocvKState = ocvKalman.correct(measurements[i]);
+ }
+ // Validation
+ EXPECT_TRUE(AbsExact().to_compare_f()(gapiKState, ocvKState));
+ SANITY_CHECK_NOTHING();
+}
#endif // HAVE_OPENCV_VIDEO
} // opencv_test
Values(5),
Values(cv::compile_args(VIDEO_CPU)),
Values(AbsExact().to_compare_obj())));
+
+INSTANTIATE_TEST_CASE_MACRO_P(WITH_VIDEO(KalmanFilterControlPerfTestCPU),
+ KalmanFilterControlPerfTest,
+ Combine(Values(CV_32FC1, CV_64FC1),
+ Values(2, 5),
+ Values(2, 5),
+ Values(5),
+ testing::Bool(),
+ Values(cv::compile_args(VIDEO_CPU))));
+
+INSTANTIATE_TEST_CASE_MACRO_P(WITH_VIDEO(KalmanFilterNoControlPerfTestCPU),
+ KalmanFilterNoControlPerfTest,
+ Combine(Values(CV_32FC1, CV_64FC1),
+ Values(2, 5),
+ Values(2, 5),
+ Values(5),
+ testing::Bool(),
+ Values(cv::compile_args(VIDEO_CPU))));
} // opencv_test
kfParams.controlMatrix.cols, kfParams.transitionMatrix.type());
// initial state
- state->statePost = kfParams.state;
- state->errorCovPost = kfParams.errorCov;
+ kfParams.state.copyTo(state->statePost);
+ kfParams.errorCov.copyTo(state->errorCovPost);
// dynamic system initialization
- state->controlMatrix = kfParams.controlMatrix;
- state->measurementMatrix = kfParams.measurementMatrix;
- state->transitionMatrix = kfParams.transitionMatrix;
- state->processNoiseCov = kfParams.processNoiseCov;
- state->measurementNoiseCov = kfParams.measurementNoiseCov;
+ kfParams.controlMatrix.copyTo(state->controlMatrix);
+ kfParams.measurementMatrix.copyTo(state->measurementMatrix);
+ kfParams.transitionMatrix.copyTo(state->transitionMatrix);
+ kfParams.processNoiseCov.copyTo(state->processNoiseCov);
+ kfParams.measurementNoiseCov.copyTo(state->measurementNoiseCov);
}
static void run(const cv::Mat& measurements, bool haveMeasurement,
state = std::make_shared<cv::KalmanFilter>(kfParams.transitionMatrix.rows, kfParams.measurementMatrix.rows,
0, kfParams.transitionMatrix.type());
// initial state
- state->statePost = kfParams.state;
- state->errorCovPost = kfParams.errorCov;
+ kfParams.state.copyTo(state->statePost);
+ kfParams.errorCov.copyTo(state->errorCovPost);
// dynamic system initialization
- state->measurementMatrix = kfParams.measurementMatrix;
- state->transitionMatrix = kfParams.transitionMatrix;
- state->processNoiseCov = kfParams.processNoiseCov;
- state->measurementNoiseCov = kfParams.measurementNoiseCov;
+ kfParams.measurementMatrix.copyTo(state->measurementMatrix);
+ kfParams.transitionMatrix.copyTo(state->transitionMatrix);
+ kfParams.processNoiseCov.copyTo(state->processNoiseCov);
+ kfParams.measurementNoiseCov.copyTo(state->measurementNoiseCov);
}
static void run(const cv::Mat& measurements, bool haveMeasurement,
EXPECT_FALSE(gapiBackSub.running());
}
+inline void initKalmanParams(const int type, const int dDim, const int mDim, const int cDim,
+ cv::gapi::KalmanParams& kp)
+{
+ kp.state = Mat::zeros(dDim, 1, type);
+ cv::randu(kp.state, Scalar::all(0), Scalar::all(0.1));
+ kp.errorCov = Mat::eye(dDim, dDim, type);
+
+ kp.transitionMatrix = Mat::ones(dDim, dDim, type) * 2;
+ kp.processNoiseCov = Mat::eye(dDim, dDim, type) * (1e-5);
+ kp.measurementMatrix = Mat::eye(mDim, dDim, type) * 2;
+ kp.measurementNoiseCov = Mat::eye(mDim, mDim, type) * (1e-5);
+
+ if (cDim > 0)
+ kp.controlMatrix = Mat::eye(dDim, cDim, type) * (1e-3);
+}
+
+inline void initKalmanFilter(const cv::gapi::KalmanParams& kp, const bool control,
+ cv::KalmanFilter& ocvKalman)
+{
+ kp.state.copyTo(ocvKalman.statePost);
+ kp.errorCov.copyTo(ocvKalman.errorCovPost);
+
+ kp.transitionMatrix.copyTo(ocvKalman.transitionMatrix);
+ kp.measurementMatrix.copyTo(ocvKalman.measurementMatrix);
+ kp.measurementNoiseCov.copyTo(ocvKalman.measurementNoiseCov);
+ kp.processNoiseCov.copyTo(ocvKalman.processNoiseCov);
+
+ if (control)
+ kp.controlMatrix.copyTo(ocvKalman.controlMatrix);
+}
+
#else // !HAVE_OPENCV_VIDEO
inline cv::GComputation runOCVnGAPIBuildOptFlowPyramid(TestFunctional&,
testBackgroundSubtractorStreaming(gapiBackSub, pOCVBackSub, 1, 1, learningRate, testNumFrames);
}
-inline void initKalmanParams(cv::gapi::KalmanParams& kp, int type, int dDim, int mDim, int cDim)
-{
- kp.state = Mat::zeros(dDim, 1, type);
- cv::randu(kp.state, Scalar::all(0), Scalar::all(0.1));
- kp.errorCov = Mat::eye(dDim, dDim, type);
-
- kp.transitionMatrix = Mat::ones(dDim, dDim, type) * 2;
- kp.processNoiseCov = Mat::eye(dDim, dDim, type)*(1e-5);
- kp.measurementMatrix = Mat::eye(mDim, dDim, type) * 2;
- kp.measurementNoiseCov = Mat::eye(mDim, mDim, type)*(1e-5);
-
- if (cDim > 0)
- kp.controlMatrix = Mat::eye(dDim, cDim, type)* (1e-3);
-}
-
-inline void initKalmanFilter(const cv::gapi::KalmanParams& kp,
- cv::KalmanFilter& ocvKalman, bool control)
-{
- kp.state.copyTo(ocvKalman.statePost);
- kp.errorCov.copyTo(ocvKalman.errorCovPost);
-
- kp.transitionMatrix.copyTo(ocvKalman.transitionMatrix);
- kp.measurementMatrix.copyTo(ocvKalman.measurementMatrix);
- kp.measurementNoiseCov.copyTo(ocvKalman.measurementNoiseCov);
- kp.processNoiseCov.copyTo(ocvKalman.processNoiseCov);
-
- if (control)
- kp.controlMatrix.copyTo(ocvKalman.controlMatrix);
-}
-
TEST_P(KalmanFilterTest, AccuracyTest)
{
cv::gapi::KalmanParams kp;
- initKalmanParams(kp, type, dDim, mDim, cDim);
+ initKalmanParams(type, dDim, mDim, cDim, kp);
// OpenCV reference KalmanFilter initialization
cv::KalmanFilter ocvKalman(dDim, mDim, cDim, type);
- initKalmanFilter(kp, ocvKalman, true);
+ initKalmanFilter(kp, true, ocvKalman);
- //measurement vector
+ // measurement vector
cv::Mat measure_vec(mDim, 1, type);
- //control vector
+ // control vector
cv::Mat ctrl_vec = Mat::zeros(cDim > 0 ? cDim : 2, 1, type);
// G-API Kalman's output state
for (int i = 0; i < numIter; i++)
{
- haveMeasure = (rng(2u) == 1) ? true : false; // returns 0 or 1 - whether we have measurement at this iteration or not
+ haveMeasure = (rng(2u) == 1); // returns 0 or 1 - whether we have measurement at this iteration or not
if (haveMeasure)
cv::randu(measure_vec, Scalar::all(-1), Scalar::all(1));
// Comparison //////////////////////////////////////////////////////////////
{
- double diff = 0;
- vector<int> idx;
- EXPECT_TRUE(cmpEps(gapiKState, ocvKState, &diff, 1.0, &idx, false) >= 0);
+ EXPECT_TRUE(AbsExact().to_compare_f()(gapiKState, ocvKState));
}
}
TEST_P(KalmanFilterNoControlTest, AccuracyTest)
{
cv::gapi::KalmanParams kp;
- initKalmanParams(kp, type, dDim, mDim, 0);
+ initKalmanParams(type, dDim, mDim, 0, kp);
// OpenCV reference KalmanFilter initialization
cv::KalmanFilter ocvKalman(dDim, mDim, 0, type);
- initKalmanFilter(kp, ocvKalman, false);
+ initKalmanFilter(kp, false, ocvKalman);
- //measurement vector
+ // measurement vector
cv::Mat measure_vec(mDim, 1, type);
// G-API Kalman's output state
for (int i = 0; i < numIter; i++)
{
- haveMeasure = (rng(2u) == 1) ? true : false; // returns 0 or 1 - whether we have measurement at this iteration or not
+ haveMeasure = (rng(2u) == 1); // returns 0 or 1 - whether we have measurement at this iteration or not
if (haveMeasure)
cv::randu(measure_vec, Scalar::all(-1), Scalar::all(1));
// Comparison //////////////////////////////////////////////////////////////
{
- double diff = 0;
- vector<int> idx;
- EXPECT_TRUE(cmpEps(gapiKState, ocvKState, &diff, 1.0, &idx, false) >= 0);
+ EXPECT_TRUE(AbsExact().to_compare_f()(gapiKState, ocvKState));
}
}
{
// auxiliary variables
cv::Mat processNoise(2, 1, type);
- // For comparison
- double diff = 0;
- vector<int> idx;
- // Input mesurement
+ // Input measurement
cv::Mat measurement = Mat::zeros(1, 1, type);
// Angle and it's delta(phi, delta_phi)
cv::Mat state(2, 1, type);
// OCV Kalman initialization
cv::KalmanFilter KF(2, 1, 0);
- initKalmanFilter(kp, KF, false);
+ initKalmanFilter(kp, false, KF);
cv::randn(state, Scalar::all(0), Scalar::all(0.1));
haveMeasure = true;
ocvCorrState = KF.correct(measurement);
comp.apply(cv::gin(measurement, haveMeasure), cv::gout(gapiState));
- EXPECT_TRUE(cmpEps(gapiState, ocvCorrState, &diff, 1.0, &idx, false) >= 0);
+ EXPECT_TRUE(AbsExact().to_compare_f()(gapiState, ocvCorrState));
}
else
{
// Get GAPI Prediction
haveMeasure = false;
comp.apply(cv::gin(measurement, haveMeasure), cv::gout(gapiState));
- EXPECT_TRUE(cmpEps(gapiState, ocvPreState, &diff, 1.0, &idx, false) >= 0);
+ EXPECT_TRUE(AbsExact().to_compare_f()(gapiState, ocvPreState));
}
GAPI_DbgAssert(cv::norm(kp.processNoiseCov, KF.processNoiseCov, cv::NORM_INF) == 0);