1 #include <caffe2/video/optical_flow.h> 5 void OpticalFlowExtractor(
6 const cv::Mat& prev_gray,
7 const cv::Mat& curr_gray,
8 const int flow_alg_type,
10 #if CV_MAJOR_VERSION >= 4 11 cv::Ptr<cv::DISOpticalFlow> tvl1 = cv::DISOpticalFlow::create();
13 cv::Ptr<cv::DualTVL1OpticalFlow> tvl1 = cv::DualTVL1OpticalFlow::create();
15 switch (flow_alg_type) {
16 case FLowAlgType::FarnebackOpticalFlow:
17 cv::calcOpticalFlowFarneback(
27 cv::OPTFLOW_FARNEBACK_GAUSSIAN);
29 case FLowAlgType::DensePyrLKOpticalFlow:
30 LOG(ERROR) <<
"DensePyrLKOpticalFlow only has sparse version on CPU";
32 case FLowAlgType::BroxOpticalFlow:
33 LOG(ERROR) <<
"BroxOpticalFlow on CPU is not available";
35 case FLowAlgType::OpticalFlowDual_TVL1:
36 tvl1->calc(prev_gray, curr_gray, flow);
39 LOG(ERROR) <<
"Unsupported optical flow type " << flow_alg_type;
44 void MergeOpticalFlow(cv::Mat& prev_flow,
const cv::Mat& curr_flow) {
45 const int rows = prev_flow.rows;
46 const int cols = prev_flow.cols;
49 for (
int y = 0; y < rows; y++) {
50 for (
int x = 0; x < cols; x++) {
51 cv::Point2f u = prev_flow.at<cv::Point2f>(y, x);
53 int x_new = std::min(cols - 1, std::max(0, cvRound(u.x + x)));
54 int y_new = std::min(rows - 1, std::max(0, cvRound(u.y + y)));
55 cv::Point2f u_new = curr_flow.at<cv::Point2f>(y_new, x_new);
58 prev_flow.at<cv::Point2f>(y, x) += u_new;
63 void MultiFrameOpticalFlowExtractor(
64 const std::vector<cv::Mat>& grays,
65 const int optical_flow_alg_type,
67 int num_frames = grays.size();
68 CAFFE_ENFORCE_GE(num_frames, 2,
"need at least 2 frames!");
71 std::vector<cv::Mat> flows;
72 for (
int i = 0; i < num_frames - 1; i++) {
74 OpticalFlowExtractor(grays[i], grays[i + 1], optical_flow_alg_type, tmp);
78 flows[0].copyTo(flow);
80 for (
int i = 1; i < num_frames - 1; i++) {
81 MergeOpticalFlow(flow, flows[i]);
A global dictionary that holds information about what Caffe2 modules have been loaded in the current ...