Merge pull request #18869 from anna-khakimova:ak/kalman
* GAPI: Kalman filter stateful kernel * Applied comments * Applied comments. Second iteration * Add overload without control vector * Remove structure constructor and dimension fields. * Add sample as test * Remove visualization from test-sample + correct doxygen comments * Applied comments.
This commit is contained in:
@@ -57,5 +57,63 @@ GMat BackgroundSubtractor(const GMat& src, const BackgroundSubtractorParams& bsp
|
||||
return GBackgroundSubtractor::on(src, bsp);
|
||||
}
|
||||
|
||||
GMat KalmanFilter(const GMat& m, const cv::GOpaque<bool>& have_m, const GMat& c, const KalmanParams& kp)
|
||||
{
|
||||
return GKalmanFilter::on(m, have_m, c, kp);
|
||||
}
|
||||
|
||||
GMat KalmanFilter(const GMat& m, const cv::GOpaque<bool>& have_m, const KalmanParams& kp)
|
||||
{
|
||||
return GKalmanFilterNoControl::on(m, have_m, kp);
|
||||
}
|
||||
|
||||
namespace video {
|
||||
void checkParams(const cv::gapi::KalmanParams& kfParams,
|
||||
const cv::GMatDesc& measurement, const cv::GMatDesc& control)
|
||||
{
|
||||
int type = kfParams.transitionMatrix.type();
|
||||
GAPI_Assert(type == CV_32FC1 || type == CV_64FC1);
|
||||
int depth = CV_MAT_DEPTH(type);
|
||||
|
||||
bool controlCapable = !(control == GMatDesc{});
|
||||
|
||||
if (controlCapable)
|
||||
{
|
||||
GAPI_Assert(!kfParams.controlMatrix.empty());
|
||||
GAPI_Assert(control.depth == depth && control.chan == 1 &&
|
||||
control.size.height == kfParams.controlMatrix.cols &&
|
||||
control.size.width == 1);
|
||||
}
|
||||
else
|
||||
GAPI_Assert(kfParams.controlMatrix.empty());
|
||||
|
||||
GAPI_Assert(!kfParams.state.empty() && kfParams.state.type() == type);
|
||||
GAPI_Assert(!kfParams.errorCov.empty() && kfParams.errorCov.type() == type);
|
||||
GAPI_Assert(!kfParams.transitionMatrix.empty() && kfParams.transitionMatrix.type() == type);
|
||||
GAPI_Assert(!kfParams.processNoiseCov.empty() && kfParams.processNoiseCov.type() == type);
|
||||
GAPI_Assert(!kfParams.measurementNoiseCov.empty() && kfParams.measurementNoiseCov.type() == type);
|
||||
GAPI_Assert(!kfParams.measurementMatrix.empty() && kfParams.measurementMatrix.type() == type);
|
||||
GAPI_Assert(measurement.depth == depth && measurement.chan == 1);
|
||||
|
||||
int dDim = kfParams.transitionMatrix.cols;
|
||||
GAPI_Assert(kfParams.transitionMatrix.rows == dDim);
|
||||
|
||||
GAPI_Assert(kfParams.processNoiseCov.cols == dDim &&
|
||||
kfParams.processNoiseCov.rows == dDim);
|
||||
GAPI_Assert(kfParams.errorCov.cols == dDim && kfParams.errorCov.rows == dDim);
|
||||
GAPI_Assert(kfParams.state.rows == dDim && kfParams.state.cols == 1);
|
||||
GAPI_Assert(kfParams.measurementMatrix.cols == dDim);
|
||||
|
||||
int mDim = kfParams.measurementMatrix.rows;
|
||||
GAPI_Assert(kfParams.measurementNoiseCov.cols == mDim &&
|
||||
kfParams.measurementNoiseCov.rows == mDim);
|
||||
|
||||
if (controlCapable)
|
||||
GAPI_Assert(kfParams.controlMatrix.rows == dDim);
|
||||
|
||||
GAPI_Assert(measurement.size.height == mDim &&
|
||||
measurement.size.width == 1);
|
||||
}
|
||||
} // namespace video
|
||||
} //namespace gapi
|
||||
} //namespace cv
|
||||
|
||||
@@ -107,6 +107,73 @@ GAPI_OCV_KERNEL_ST(GCPUBackgroundSubtractor,
|
||||
}
|
||||
};
|
||||
|
||||
GAPI_OCV_KERNEL_ST(GCPUKalmanFilter, cv::gapi::video::GKalmanFilter, cv::KalmanFilter)
|
||||
{
|
||||
static void setup(const cv::GMatDesc&, const cv::GOpaqueDesc&,
|
||||
const cv::GMatDesc&, const cv::gapi::KalmanParams& kfParams,
|
||||
std::shared_ptr<cv::KalmanFilter> &state, const cv::GCompileArgs&)
|
||||
{
|
||||
state = std::make_shared<cv::KalmanFilter>(kfParams.transitionMatrix.rows, kfParams.measurementMatrix.rows,
|
||||
kfParams.controlMatrix.cols, kfParams.transitionMatrix.type());
|
||||
|
||||
// initial state
|
||||
state->statePost = kfParams.state;
|
||||
state->errorCovPost = kfParams.errorCov;
|
||||
|
||||
// dynamic system initialization
|
||||
state->controlMatrix = kfParams.controlMatrix;
|
||||
state->measurementMatrix = kfParams.measurementMatrix;
|
||||
state->transitionMatrix = kfParams.transitionMatrix;
|
||||
state->processNoiseCov = kfParams.processNoiseCov;
|
||||
state->measurementNoiseCov = kfParams.measurementNoiseCov;
|
||||
}
|
||||
|
||||
static void run(const cv::Mat& measurements, bool haveMeasurement,
|
||||
const cv::Mat& control, const cv::gapi::KalmanParams&,
|
||||
cv::Mat &out, cv::KalmanFilter& state)
|
||||
{
|
||||
cv::Mat pre = state.predict(control);
|
||||
|
||||
if (haveMeasurement)
|
||||
state.correct(measurements).copyTo(out);
|
||||
else
|
||||
pre.copyTo(out);
|
||||
}
|
||||
};
|
||||
|
||||
GAPI_OCV_KERNEL_ST(GCPUKalmanFilterNoControl, cv::gapi::video::GKalmanFilterNoControl, cv::KalmanFilter)
|
||||
{
|
||||
static void setup(const cv::GMatDesc&, const cv::GOpaqueDesc&,
|
||||
const cv::gapi::KalmanParams& kfParams,
|
||||
std::shared_ptr<cv::KalmanFilter> &state,
|
||||
const cv::GCompileArgs&)
|
||||
{
|
||||
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;
|
||||
|
||||
// dynamic system initialization
|
||||
state->measurementMatrix = kfParams.measurementMatrix;
|
||||
state->transitionMatrix = kfParams.transitionMatrix;
|
||||
state->processNoiseCov = kfParams.processNoiseCov;
|
||||
state->measurementNoiseCov = kfParams.measurementNoiseCov;
|
||||
}
|
||||
|
||||
static void run(const cv::Mat& measurements, bool haveMeasurement,
|
||||
const cv::gapi::KalmanParams&, cv::Mat &out,
|
||||
cv::KalmanFilter& state)
|
||||
{
|
||||
cv::Mat pre = state.predict();
|
||||
|
||||
if (haveMeasurement)
|
||||
state.correct(measurements).copyTo(out);
|
||||
else
|
||||
pre.copyTo(out);
|
||||
}
|
||||
};
|
||||
|
||||
cv::gapi::GKernelPackage cv::gapi::video::cpu::kernels()
|
||||
{
|
||||
static auto pkg = cv::gapi::kernels
|
||||
@@ -114,6 +181,8 @@ cv::gapi::GKernelPackage cv::gapi::video::cpu::kernels()
|
||||
, GCPUCalcOptFlowLK
|
||||
, GCPUCalcOptFlowLKForPyr
|
||||
, GCPUBackgroundSubtractor
|
||||
, GCPUKalmanFilter
|
||||
, GCPUKalmanFilterNoControl
|
||||
>();
|
||||
return pkg;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user