opencv Farneback光流法

来源:互联网 发布:手机淘宝有秒杀专区吗 编辑:程序博客网 时间:2024/06/11 14:47
#include <iostream> #include "opencv2/opencv.hpp" using namespace cv;  using namespace std;#define UNKNOWN_FLOW_THRESH 1e9  static void makecolorwheel(vector<Scalar> &colorwheel)  {  int RY = 15;  int YG = 6;  int GC = 4;  int CB = 11;  int BM = 13;  int MR = 6;  int i;  for (i = 0; i < RY; i++) colorwheel.push_back(Scalar(255,       255*i/RY,     0));  for (i = 0; i < YG; i++) colorwheel.push_back(Scalar(255-255*i/YG, 255,       0));  for (i = 0; i < GC; i++) colorwheel.push_back(Scalar(0,         255,      255*i/GC));  for (i = 0; i < CB; i++) colorwheel.push_back(Scalar(0,         255-255*i/CB, 255));  for (i = 0; i < BM; i++) colorwheel.push_back(Scalar(255*i/BM,      0,        255));  for (i = 0; i < MR; i++) colorwheel.push_back(Scalar(255,       0,        255-255*i/MR));  }  static void motionToColor(Mat flow, Mat &color)  {  static vector<Scalar> colorwheel; //Scalar r,g,b  if (colorwheel.empty())  makecolorwheel(colorwheel);  // determine motion range:  float maxrad = -1;  // Find max flow to normalize fx and fy  for (int i= 0; i < flow.rows; ++i)   {  for (int j = 0; j < flow.cols; ++j)   {  Vec2f flow_at_point = flow.at<Vec2f>(i, j);  //flow:x,yfloat fx = flow_at_point[0];  float fy = flow_at_point[1];  if ((fabs(fx) >  UNKNOWN_FLOW_THRESH) || (fabs(fy) >  UNKNOWN_FLOW_THRESH))  continue;  float rad = sqrt(fx * fx + fy * fy);  maxrad = maxrad > rad ? maxrad : rad;  }  }  for (int i= 0; i < flow.rows; ++i)   {  for (int j = 0; j < flow.cols; ++j)   {  uchar *data = color.data + color.step[0] * i + color.step[1] * j;  Vec2f flow_at_point = flow.at<Vec2f>(i, j);  float fx = flow_at_point[0] / maxrad;  float fy = flow_at_point[1] / maxrad;//归一化if ((fabs(fx) >  UNKNOWN_FLOW_THRESH) || (fabs(fy) >  UNKNOWN_FLOW_THRESH))  {  data[0] = data[1] = data[2] = 0;//BGRcontinue;  }  float rad = sqrt(fx * fx + fy * fy);//速率float angle = atan2(-fy, -fx) / CV_PI;//夹角 float fk = (angle + 1.0) / 2.0 * (colorwheel.size()-1);  int k0 = (int)fk;  int k1 = (k0 + 1) % colorwheel.size();  float f = fk - k0;  //f = 0; // uncomment to see original color wheel  for (int b = 0; b < 3; b++)   {  float col0 = colorwheel[k0][b] / 255.0;  float col1 = colorwheel[k1][b] / 255.0;  float col = (1 - f) * col0 + f * col1;  if (rad <= 1)  col = 1 - rad * (1 - col); // increase saturation with radius  else  col *= .75; // out of range  data[2 - b] = (int)(255.0 * col);  }  }  }  }  int main(){const char* videoFileName = "D:/FarnebackInGPU/myProject/myProject/dataset/MAH00054.MP4";//const char* videoFileName = "optical_flow_input.avi";VideoCapture cap;//string strFileName(videoFileName);//cap.open(0);  cap.open(videoFileName);  if( !cap.isOpened() )  return 1;  Mat prevgray, gray, flow, cflow, frame;  namedWindow("flow", 1); bool isFirstFrame = true;Mat motion2color; while (true){double t = (double)cvGetTickCount();  cap >> frame;  if (!frame.data) break;while (frame.cols > 800){resize(frame, frame, Size(frame.cols / 2, frame.rows / 2));}cvtColor(frame, gray, CV_BGR2GRAY); imshow(videoFileName, frame);//显示当前帧if (isFirstFrame){motion2color.create(gray.rows, gray.cols, CV_8UC3);  //BGRisFirstFrame = false;}else{calcOpticalFlowFarneback(prevgray, gray, flow, 0.5, 3, 15, 3, 5, 1.2, 0);  motionToColor(flow, motion2color); imshow("flow", motion2color); t = (double)cvGetTickCount() - t;  cout << "cost time: " << t / ((double)cvGetTickFrequency() * 1000 * 1000)<<"s." << endl; }std::swap(prevgray, gray);char ch = waitKey(1);if(ch == 27) return 1;else if(ch > -1) waitKey(0);}return 0;}
                                             
0 0