光流Optical Flow介绍与OpenC…
来源:互联网 发布:数据库设计与关系理论 编辑:程序博客网 时间:2024/06/05 18:41
光流(opticflow)是什么呢?名字很专业,感觉很陌生,但本质上,我们是最熟悉不过的了。因为这种视觉现象我们每天都在经历。从本质上说,光流就是你在这个运动着的世界里感觉到的明显的视觉运动(呵呵,相对论,没有绝对的静止,也没有绝对的运动)。例如,当你坐在火车上,然后往窗外看。你可以看到树、地面、建筑等等,他们都在往后退。这个运动就是光流。而且,我们都会发现,他们的运动速度居然不一样?这就给我们提供了一个挺有意思的信息:通过不同目标的运动速度判断它们与我们的距离。一些比较远的目标,例如云、山,它们移动很慢,感觉就像静止一样。但一些离得比较近的物体,例如建筑和树,就比较快的往后退,然后离我们的距离越近,它们往后退的速度越快。一些非常近的物体,例如路面的标记啊,草地啊等等,快到好像在我们耳旁发出嗖嗖的声音。
1)calcOpticalFlowPyrLK
通过金字塔Lucas-Kanade光流方法计算某些点集的光流(稀疏光流)。理解的话,可以参考这篇论文:”Pyramidal Implementation of theLucas Kanade Feature TrackerDescription of thealgorithm”
2)calcOpticalFlowFarneback
用Gunnar Farneback的算法计算稠密光流(即图像上所有像素点的光流都计算出来)。它的相关论文是:"Two-Frame Motion EstimationBased on PolynomialExpansion"
3)CalcOpticalFlowBM
通过块匹配的方法来计算光流。
4)CalcOpticalFlowHS
用Horn-Schunck的算法计算稠密光流。相关论文好像是这篇:”Determining Optical Flow”
5)calcOpticalFlowSF
这一个是2012年欧洲视觉会议的一篇文章的实现:"SimpleFlow: A Non-iterative,Sublinear Optical FlowAlgorithm",工程网站是:http://graphics.berkeley.edu/papers/Tao-SAN-2012-05/
http://www.opencv.org.cn/opencvdoc/2.3.2/html/modules/video/doc/motion_analysis_and_object_tracking.html#calcopticalflowfarneback
http://vision.middlebury.edu/flow/
孟塞尔颜色系统的空间大致成一个圆柱形:
南北轴=明度(value),从全黑(1)到全白(10)。
经度=色相(hue)。把一周均分成五种主色调和五种中间色:红(R)、红黄(YR)、黄(Y)、黄绿(GY)、绿(G)、绿蓝(BG)、蓝(B)、蓝紫(PB)、紫(P)、紫红(RP)。相邻的两个位置之间再均分10份,共100份。
距轴的距离=色度(chroma),表示色调的纯度。其数值从中间(0)向外随着色调的纯度增加,没有理论上的上限(普通的颜色实际上限为10左右,反光、荧光等材料可高达30)。由于人眼对各种颜色的的敏感度不同,色度不一定与每个色调和明度组合相匹配。
具体颜色的标识形式为:色相+明度+色度。
voidcalcOpticalFlowFarneback
大部分参数在论文中都有一套比较好的值的,直接采用他们的就好了。
- //
Farneback dense optical flow calculate and show in Munsell system of colors - //
Author : Zouxy - //
Date : 2013-3-15 - //
HomePage : http://blog.csdn.net/zouxy09 - //
Email : zouxy09@qq.com -
- //
API calcOpticalFlowFarneback () comes from OpenCV, and this - //
2D dense optical flow algorithm from the following paper: - //
Gunnar Farneback. "Two-Frame Motion Estimation Based on Polynomial Expansion". - //
And the OpenCV source code locate in ..\opencv2.4.3\modules\video\src\optflowgf.cpp -
- #include
- #include
"opencv2/opencv.hpp" -
- using
namespace cv; - using
namespace std; -
- #define
UNKNOWN_FLOW_THRESH 1e9 -
- //
Color encoding of flow vectors from: - //
http://members.shaw.ca/quadibloc/other/colint.htm - //
This code is modified from: - //
http://vision.middlebury.edu/flow/data/ - void
makecolorwheel(vector &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 //Scalarcolorwheel; r,g,b -
if (colorwheel.empty()) -
makecolorwheel(colorwheel); -
-
// determine motion range: -
float maxrad = -1; -
-
// Find max flow to normalize fx and fy -
for ( inti= 0; i < flow.rows; ++i) -
{ -
for ( intj = 0; j < flow.cols; ++j) -
{ -
Vec2f flow_at_point = flow.at(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 ( inti= 0; i < flow.rows; ++i) -
{ -
for ( intj = 0; j < flow.cols; ++j) -
{ -
uchar *data = color.data + color.step[0] * i + color.step[1] * j; -
Vec2f flow_at_point = flow.at(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 ( intb = 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("test_02.wmv"); -
-
if( !cap.isOpened() ) -
return -1; -
-
Mat prevgray, gray, flow, cflow, frame; -
namedWindow("flow", 1); -
-
Mat motion2color; -
-
for(;;) -
{ -
double t double)cvGetTickCount();= ( -
-
cap >> frame; -
cvtColor(frame, gray, CV_BGR2GRAY); -
imshow("original", frame); -
-
if( prevgray.data ) -
{ -
calcOpticalFlowFarneback (prevgray, gray, flow, 0.5, 3, 15, 3, 5, 1.2, 0); -
motionToColor(flow, motion2color); -
imshow("flow", motion2color); -
} -
if(waitKey(10)>=0) -
break; -
std::swap(prevgray, gray); -
-
t = (double)cvGetTickCount() - t; -
cout << "cost time: " << double)cvGetTickFrequency()*1000.)t / (( << endl; -
} -
return 0; - }
这个是效果:
一个挥动的手:
- 光流Optical Flow介绍与OpenC…
- 光流 optical flow介绍
- 光流Optical Flow介绍与OpenCV实现
- 光流Optical Flow介绍与OpenCV实现
- 光流Optical Flow介绍与OpenCV实现
- 光流Optical Flow介绍与OpenCV实现
- 【转】光流Optical Flow介绍与OpenCV实现
- 光流Optical Flow介绍与OpenCV实现
- 光流Optical Flow介绍与OpenCV实现
- 光流Optical Flow介绍与OpenCV实现
- 光流Optical Flow介绍与OpenCV实现
- 光流Optical Flow介绍与OpenCV实现
- 光流Optical Flow介绍与OpenCV实现
- 光流Optical Flow介绍与OpenCV实现
- 光流Optical Flow介绍与OpenCV实现 .
- 光流Optical Flow介绍与OpenCV实现
- 光流Optical Flow介绍与OpenCV实现
- 光流Optical Flow介绍与OpenCV实现
- OpenCV打开摄像头 保存视频…
- 谈谈ConcurrentHashMap1.7和1.8的不同实现
- OpenCV_复制一个或多个ROI图像区域
- iOS如何使用TestFlight进行App Beta版测试
- CvMat、Mat、IplImage之间的转换详…
- 光流Optical Flow介绍与OpenC…
- QTSingleApplication的用法
- 关于精确度-保留小数点后几位小数
- css3选择器
- VS2010中“转到定义”提示“未能找到…
- 高通bootloader 介绍
- VS调试技巧 (转载)
- 将string转换成char* (转)
- STL之一string