mirror of
https://github.com/opencv/opencv_contrib.git
synced 2025-10-19 11:21:39 +08:00
Merge pull request #1940 from tsenst:add_robust_optical_flow_implementation
Add robust local optical flow (RLOF) implementations (#1940) * Add robust local optical flow (RLOF) implementations which is an improved pyramidal iterative Lucas-Kanade approach. This implementations contains interfaces for sparse optical flow for feature tracking and dense optical flow based on sparse-to-dense interpolation schemes. Add performance and accuracy tests have been implementation as well as documentation with the related publications * - exchange tabs with spaces - fix optflow.bib indentation - remove optflow_o.hpp - change RLOFOpticalFlowParameter interfaces to Ptr<RLOFOpticalFlowParameter> to remove error on building. Fix warnings * introducing precompiler flag RLOD_SSE * remove header that could not be found * remove whitespaces fix perf and accuracy tests * remove x86intrin.h header * fix ios and arm by removing last sse commands * fix warnings for windows compilation * fix documentation RLOFOpticalFlowParameter * integrate cast to remove last warnings * * add create method and function inferfaces to RLOFOpticalFlowParamter to enable python wrapper interfaces * white space fixes / coding style * fix perf test * other changes: precomp.hpp / static * use Matx44f and Vec4f instead of Mat * normSigmas into constants * replace ceil() calls * maximum level is set to 5 so that it is similar value used in the papers * implement paralellized horizontal cross segmentation as used in Geistert2016 * drop dead code * Avoid using "data" and "step" calculations. Use .ptr<mat_type>(row, col) instead. * Avoid using "data" and "step" calculations. Use .ptr<mat_type>(row, col) instead. * bugfix on BEPLK with ica and adapt the accuracy tests * more 'static' functions * bugfix after changing ptr + step to .ptr(y,x) calls by adjusting ROI of prevImage, currImage and derivI as well as changing the offset of the points in the invoker classes. * add some static_cast to avoid warning * remove 50 grid size sample from perf test. This grid size is to sparse for the epic interpolation * remove notSameColor function since it is not used anymore
This commit is contained in:

committed by
Alexander Alekhin

parent
b1e9dd5454
commit
1c9e23745c
@@ -83,7 +83,20 @@ static float calcRMSE(Mat flow1, Mat flow2)
|
||||
}
|
||||
return (float)sqrt(sum / (1e-9 + counter));
|
||||
}
|
||||
|
||||
static float calcRMSE(vector<Point2f> prevPts, vector<Point2f> currPts, Mat flow)
|
||||
{
|
||||
vector<float> ee;
|
||||
for (unsigned int n = 0; n < prevPts.size(); n++)
|
||||
{
|
||||
Point2f gtFlow = flow.at<Point2f>(prevPts[n]);
|
||||
if (isFlowCorrect(gtFlow.x) && isFlowCorrect(gtFlow.y))
|
||||
{
|
||||
Point2f diffFlow = (currPts[n] - prevPts[n]) - gtFlow;
|
||||
ee.push_back(sqrt(diffFlow.x * diffFlow.x + diffFlow.y * diffFlow.y));
|
||||
}
|
||||
}
|
||||
return static_cast<float>(mean(ee).val[0]);
|
||||
}
|
||||
static float calcAvgEPE(vector< pair<Point2i, Point2i> > corr, Mat flow)
|
||||
{
|
||||
double sum = 0;
|
||||
@@ -111,9 +124,13 @@ static float calcAvgEPE(vector< pair<Point2i, Point2i> > corr, Mat flow)
|
||||
|
||||
bool readRubberWhale(Mat &dst_frame_1, Mat &dst_frame_2, Mat &dst_GT)
|
||||
{
|
||||
const string frame1_path = getRubberWhaleFrame1();
|
||||
const string frame2_path = getRubberWhaleFrame2();
|
||||
const string gt_flow_path = getRubberWhaleGroundTruth();
|
||||
string frame1_path = getRubberWhaleFrame1();
|
||||
string frame2_path = getRubberWhaleFrame2();
|
||||
string gt_flow_path = getRubberWhaleGroundTruth();
|
||||
// removing space may be an issue on windows machines
|
||||
frame1_path.erase(std::remove_if(frame1_path.begin(), frame1_path.end(), isspace), frame1_path.end());
|
||||
frame2_path.erase(std::remove_if(frame2_path.begin(), frame2_path.end(), isspace), frame2_path.end());
|
||||
gt_flow_path.erase(std::remove_if(gt_flow_path.begin(), gt_flow_path.end(), isspace), gt_flow_path.end());
|
||||
|
||||
dst_frame_1 = imread(frame1_path);
|
||||
dst_frame_2 = imread(frame2_path);
|
||||
@@ -125,6 +142,7 @@ bool readRubberWhale(Mat &dst_frame_1, Mat &dst_frame_2, Mat &dst_GT)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
TEST(DenseOpticalFlow_SimpleFlow, ReferenceAccuracy)
|
||||
{
|
||||
Mat frame1, frame2, GT;
|
||||
@@ -157,6 +175,102 @@ TEST(DenseOpticalFlow_DeepFlow, ReferenceAccuracy)
|
||||
EXPECT_LE(calcRMSE(GT, flow), target_RMSE);
|
||||
}
|
||||
|
||||
TEST(SparseOpticalFlow, ReferenceAccuracy)
|
||||
{
|
||||
// with the following test each invoker class should be tested once
|
||||
Mat frame1, frame2, GT;
|
||||
ASSERT_TRUE(readRubberWhale(frame1, frame2, GT));
|
||||
vector<Point2f> prevPts, currPts;
|
||||
for (int r = 0; r < frame1.rows; r+=10)
|
||||
{
|
||||
for (int c = 0; c < frame1.cols; c+=10)
|
||||
{
|
||||
prevPts.push_back(Point2f(static_cast<float>(c), static_cast<float>(r)));
|
||||
}
|
||||
}
|
||||
vector<uchar> status(prevPts.size());
|
||||
vector<float> err(prevPts.size());
|
||||
Ptr<SparseRLOFOpticalFlow> algo = SparseRLOFOpticalFlow::create();
|
||||
algo->setForwardBackward(0.0f);
|
||||
Ptr<RLOFOpticalFlowParameter> param = Ptr<RLOFOpticalFlowParameter>(new RLOFOpticalFlowParameter);
|
||||
param->supportRegionType = SR_CROSS;
|
||||
param->useIlluminationModel = true;
|
||||
param->solverType = ST_BILINEAR;
|
||||
algo->setRLOFOpticalFlowParameter(param);
|
||||
algo->calc(frame1, frame2, prevPts, currPts, status, err);
|
||||
EXPECT_LE(calcRMSE(prevPts, currPts, GT), 0.3f);
|
||||
|
||||
param->solverType = ST_STANDART;
|
||||
algo->setRLOFOpticalFlowParameter(param);
|
||||
algo->calc(frame1, frame2, prevPts, currPts, status, err);
|
||||
EXPECT_LE(calcRMSE(prevPts, currPts, GT), 0.34f);
|
||||
|
||||
param->useIlluminationModel = false;
|
||||
param->solverType = ST_BILINEAR;
|
||||
algo->setRLOFOpticalFlowParameter(param);
|
||||
algo->calc(frame1, frame2, prevPts, currPts, status, err);
|
||||
EXPECT_LE(calcRMSE(prevPts, currPts, GT), 0.27f);
|
||||
|
||||
param->solverType = ST_STANDART;
|
||||
algo->setRLOFOpticalFlowParameter(param);
|
||||
algo->calc(frame1, frame2, prevPts, currPts, status, err);
|
||||
EXPECT_LE(calcRMSE(prevPts, currPts, GT), 0.27f);
|
||||
|
||||
param->normSigma0 = numeric_limits<float>::max();
|
||||
param->normSigma1 = numeric_limits<float>::max();
|
||||
param->useIlluminationModel = true;
|
||||
|
||||
param->solverType = ST_BILINEAR;
|
||||
algo->setRLOFOpticalFlowParameter(param);
|
||||
algo->calc(frame1, frame2, prevPts, currPts, status, err);
|
||||
EXPECT_LE(calcRMSE(prevPts, currPts, GT), 0.28f);
|
||||
|
||||
param->solverType = ST_STANDART;
|
||||
algo->setRLOFOpticalFlowParameter(param);
|
||||
algo->calc(frame1, frame2, prevPts, currPts, status, err);
|
||||
EXPECT_LE(calcRMSE(prevPts, currPts, GT), 0.28f);
|
||||
|
||||
param->useIlluminationModel = false;
|
||||
|
||||
param->solverType = ST_BILINEAR;
|
||||
algo->setRLOFOpticalFlowParameter(param);
|
||||
algo->calc(frame1, frame2, prevPts, currPts, status, err);
|
||||
EXPECT_LE(calcRMSE(prevPts, currPts, GT), 0.80f);
|
||||
|
||||
param->solverType = ST_STANDART;
|
||||
algo->setRLOFOpticalFlowParameter(param);
|
||||
algo->calc(frame1, frame2, prevPts, currPts, status, err);
|
||||
EXPECT_LE(calcRMSE(prevPts, currPts, GT), 0.28f);
|
||||
}
|
||||
|
||||
TEST(DenseOpticalFlow_RLOF, ReferenceAccuracy)
|
||||
{
|
||||
Mat frame1, frame2, GT;
|
||||
ASSERT_TRUE(readRubberWhale(frame1, frame2, GT));
|
||||
Mat flow;
|
||||
Ptr<DenseRLOFOpticalFlow> algo = DenseRLOFOpticalFlow::create();
|
||||
Ptr<RLOFOpticalFlowParameter> param = Ptr<RLOFOpticalFlowParameter>(new RLOFOpticalFlowParameter);
|
||||
param->supportRegionType = SR_CROSS;
|
||||
param->solverType = ST_BILINEAR;
|
||||
algo->setRLOFOpticalFlowParameter(param);
|
||||
algo->setForwardBackward(1.0f);
|
||||
algo->setGridStep(cv::Size(4, 4));
|
||||
algo->setInterpolation(INTERP_EPIC);
|
||||
algo->calc(frame1, frame2, flow);
|
||||
|
||||
ASSERT_EQ(GT.rows, flow.rows);
|
||||
ASSERT_EQ(GT.cols, flow.cols);
|
||||
EXPECT_LE(calcRMSE(GT, flow), 0.44f);
|
||||
|
||||
algo->setInterpolation(INTERP_GEO);
|
||||
algo->calc(frame1, frame2, flow);
|
||||
|
||||
ASSERT_EQ(GT.rows, flow.rows);
|
||||
ASSERT_EQ(GT.cols, flow.cols);
|
||||
EXPECT_LE(calcRMSE(GT, flow), 0.55f);
|
||||
|
||||
}
|
||||
|
||||
TEST(DenseOpticalFlow_SparseToDenseFlow, ReferenceAccuracy)
|
||||
{
|
||||
Mat frame1, frame2, GT;
|
||||
|
Reference in New Issue
Block a user