zoukankan      html  css  js  c++  java
  • OpenCV 学习笔记(11)【OpenCV】光流场方法标出前景(运动)和背景(静止)

    用光流场方法,标出前景(运动)和背景(静止)。

    环境:VS2017 + OpenCV3.4.1

    光流场介绍可以参见英文版学习OpenCV3的第17章Tracking

    英文原版学习OpenCV3下载链接

    https://download.csdn.net/download/iefenghao/11194776

    视频测试

    步骤

    (1)打开视频

    (2)转为灰度图

    (3)光流检测,标出前景

    #include <iostream>
    #include "opencv2/opencv.hpp"
     
    using namespace cv;
    using namespace std;
     
    #define UNKNOWN_FLOW_THRESH 1e9
    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));
    }
     
    void motionToColor(Mat flow, Mat &color)
    {
    	if (color.empty())
    		color.create(flow.rows, flow.cols, CV_8UC3);
     
    	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);
    			float 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;
    				continue;
    			}
    			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(int, char**)
    {
    	VideoCapture cap;
    	//cap.open(0);
    	cap.open("srcVideo.mp4");
     
    	if (!cap.isOpened())
    		return -1;
     
    	Mat prevgray, gray, flow, cflow, frame;
     
    	Mat motion2color;
     
    	for (;;)
    	{
    		double t = (double)cvGetTickCount();
     
    		cap >> frame;
    		cvtColor(frame, gray, CV_BGR2GRAY);
    		imshow("src 1210", frame);
     
    		if (prevgray.data)
    		{
    			calcOpticalFlowFarneback(prevgray, gray, flow, 0.5, 3, 15, 3, 5, 1.2, 0);
    			motionToColor(flow, motion2color);
    			imshow("dst 1210", motion2color);
    		}
    		if (waitKey(10) >= 0)
    			break;
    		std::swap(prevgray, gray);
     
    		t = (double)cvGetTickCount() - t;
    		cout << "cost time: " << t / ((double)cvGetTickFrequency()*1000.) << endl;
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    关于动画的各种实现方法【转】
    关于弹出框的理念【转】
    jquery点击目标DIV以外关闭效果
    唯美诗句
    mouseover和this的巧用
    基于html5 canvas 的强大图表插件【Chart.js】
    关于百度地图API (持续跟新)
    JS的异步回调函数
    MMU内存管理单元(看书笔记)
    系统移植详细步骤
  • 原文地址:https://www.cnblogs.com/kekeoutlook/p/11306276.html
Copyright © 2011-2022 走看看