Closed FantasyJXF closed 4 years ago
Install the OpenCV with CUDA and use the following code to get optical flow
#include "opencv2/video/tracking.hpp" #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/core/cuda.hpp" #include "opencv2/cudaoptflow.hpp" #include "opencv2/cudaarithm.hpp" #include <stdio.h> #include <string> #include <iostream> using namespace std; using namespace cv; using namespace cv::cuda; static void convertFlowToImage(const Mat &flow_x, const Mat &flow_y, Mat &img_x, Mat &img_y, double lowerBound, double higherBound) { #define CAST(v, L, H) ((v) > (H) ? 255 : (v) < (L) ? 0 : cvRound(255*((v) - (L))/((H)-(L)))) for (int i = 0; i < flow_x.rows; ++i) { for (int j = 0; j < flow_y.cols; ++j) { float x = flow_x.at<float>(i,j); float y = flow_y.at<float>(i,j); img_x.at<uchar>(i,j) = CAST(x, lowerBound, higherBound); img_y.at<uchar>(i,j) = CAST(y, lowerBound, higherBound); } } #undef CAST } static void drawOptFlowMap(const Mat& flow, Mat& cflowmap, int step,double, const Scalar& color){ for(int y = 0; y < cflowmap.rows; y += step) for(int x = 0; x < cflowmap.cols; x += step) { const Point2f& fxy = flow.at<Point2f>(y, x); line(cflowmap, Point(x,y), Point(cvRound(x+fxy.x), cvRound(y+fxy.y)), color); circle(cflowmap, Point(x,y), 2, color, -1); } } int main(int argc, char** argv){ // IO operation //const char* keys = // { // "{ f | vidFile | ex2.avi | filename of video }" // "{ x | xFlowFile | flow_x | filename of flow x component }" // "{ y | yFlowFile | flow_y | filename of flow x component }" // "{ i | imgFile | flow_i | filename of flow image}" // "{ b | bound | 15 | specify the maximum of optical flow}" // "{ t | type | 0 | specify the optical flow algorithm }" // "{ d | device_id | 0 | set gpu id}" // "{ s | step | 1 | specify the step for frame sampling}" // }; const cv::String keys = "{@vidFile | | filename of video }" "{@xFlowFile | | filename of flow x component }" "{@yFlowFile | | filename of flow x component }" "{@imgFile | | filename of image component }" "{@bound | 15 | specify the maximum of optical flow}" "{@type | 0 | specify the optical flow algorithm }" "{@device_id | 0 | set gpu id }" "{@step | 1 | specify the step for frame sampling}" ; cv::CommandLineParser cmd(argc, argv, keys); std::string vidFile = cmd.get<string>("@vidFile"); std::string xFlowFile = cmd.get<string>("@xFlowFile"); std::string yFlowFile = cmd.get<string>("@yFlowFile"); std::string imgFile = cmd.get<string>("@imgFile"); int bound = cmd.get<int>("@bound"); int type = cmd.get<int>("@type"); int device_id = cmd.get<int>("@device_id"); int step = cmd.get<int>("@step"); cv::VideoCapture capture(vidFile); if(!capture.isOpened()) { printf("Could not initialize capturing..\n"); return -1; } int frame_num = 0; Mat image, prev_image, prev_grey, grey, frame, flow, flows[2]; GpuMat frame_0, frame_1, gflow; setDevice(device_id); cv::Ptr<cv::cuda::FarnebackOpticalFlow> alg_farn; cv::Ptr<cv::cuda::OpticalFlowDual_TVL1> alg_tvl1; cv::Ptr<cv::cuda::BroxOpticalFlow> alg_brox; while(true) { capture >> frame; if(frame.empty()) break; if(frame_num == 0) { image.create(frame.size(), CV_8UC3); grey.create(frame.size(), CV_8UC1); prev_image.create(frame.size(), CV_8UC3); prev_grey.create(frame.size(), CV_8UC1); frame.copyTo(prev_image); cvtColor(prev_image, prev_grey, CV_BGR2GRAY); frame_num++; int step_t = step; while (step_t > 1){ capture >> frame; step_t--; } continue; } frame.copyTo(image); cvtColor(image, grey, CV_BGR2GRAY); frame_0.upload(prev_grey); frame_1.upload(grey); // GPU optical flow switch(type){ case 0: alg_farn = cv::cuda::FarnebackOpticalFlow::create(); alg_farn->calc(frame_0,frame_1, gflow); break; case 1: alg_tvl1 = cv::cuda::OpticalFlowDual_TVL1::create(); alg_tvl1->calc(frame_0,frame_1, gflow); break; case 2: alg_brox = cv::cuda::BroxOpticalFlow::create(0.197f, 50.0f, 0.8f, 10, 77, 10); GpuMat d_frame0f, d_frame1f; frame_0.convertTo(d_frame0f, CV_32F, 1.0 / 255.0); frame_1.convertTo(d_frame1f, CV_32F, 1.0 / 255.0); alg_brox->calc(d_frame0f, d_frame1f, gflow); break; } gflow.download(flow); cv::split(flow, flows); // Output optical flow Mat imgX(flows[0].size(),CV_8UC1); Mat imgY(flows[1].size(),CV_8UC1); convertFlowToImage(flows[0],flows[1], imgX, imgY, -bound, bound); char tmp[20]; sprintf(tmp,"_%05d.jpg",int(frame_num)); // Mat imgX_, imgY_, image_; // resize(imgX,imgX_,cv::Size(340,256)); // resize(imgY,imgY_,cv::Size(340,256)); // resize(image,image_,cv::Size(340,256)); imwrite(xFlowFile + tmp,imgX); imwrite(yFlowFile + tmp,imgY); imwrite(imgFile + tmp, image); std::swap(prev_grey, grey); std::swap(prev_image, image); frame_num = frame_num + 1; int step_t = step; while (step_t > 1){ capture >> frame; step_t--; } } return 0; }
The command I use is :
./denseFlow_gpu --vidFile /home/Datasets/video/UCF-101/TaiChi/v_TaiChi_g25_c04.avi --xFlowFile tmp/flow_x --yFlowFile tmp/flow_x --imgFile tmp/image --bound 20 --type 1 --evice_id 0 --step 1
Here my question is about the command line --xFlowFile tmp/flow_x --yFlowFile tmp/flow_x, why the flow in x/y direction result in the same file?
--xFlowFile tmp/flow_x --yFlowFile tmp/flow_x
Obviously, --yFlowFile tmp/flow_y
--yFlowFile tmp/flow_y
Install the OpenCV with CUDA and use the following code to get optical flow
The command I use is :
Here my question is about the command line
--xFlowFile tmp/flow_x --yFlowFile tmp/flow_x
, why the flow in x/y direction result in the same file?