金字塔LK算法针对较大的运动图像序列。如果用一个大的窗口来捕获大的运动,往往会违背运动连贯的假设。也就是,这个大窗口内的子图像和原先的子图像发生了较大的变化。图像金子塔可以解决这个问题,最初在较大的空间尺度上进行跟踪,在通过对图像金字塔向下直到图像像素的处理来修正初始运动速度(位移)的假设。通俗的将,就是通过下采样是的大窗口变为小窗口,以此来满足运动连贯的假设。
偏导方法求解位移:
cvCalcOpticalFlowPyrLK中把特征点的速度和方向等价位特征的位移及其方向。
E为误差大小,wx,wy为x方向和y方向的窗口大小,I(x,y)为前一帧图像,J(x,y)为当前帧图像。一般的,假设如果是刚性运动,只要用以合理的搜索路径找位移d使得E最小,是块匹配的一种方法。
在金字塔LK算法,对E(d)求d的偏导,使得偏导数为0,从而求得相应的d。
It=I(x,y)-J(x,y),J(x+dx,y+dy)在d=0出泰勒张开,则13式可以化为
dopt 是d的最优解,上式即为Lucas-Kandade 的光流方程,在实际求解过程中需要进行迭代求解。
效果如图:
3 基于形态学的人体判定
3.1 关键节点分类
本算法把人体关键节点分为13个,然后依据无遮挡人体外形粗略分为U型点和N型点:
U型点有5个:分别为头顶、左右手腕、左右手肘
N型点有3个:即手臂与身体两个,裆部一个
剩余的点可以根据关键点之间的父子依存关系判定,例如脖子节点与头部节点相连于身体一侧。
3.2 节点判定
U型点和N型点的判定都是在产生轮廓记录拐点的基础上进行的,其分别方法在于点间角度的内外旋区分:
Vector3f vt1 = Vector3f (pt2.x-pt1.x,pt2.y-pt1.y,0);
Vector3f vt2=Vector3f t1.x-pt.x,pt1.y-pt.y,0);
arc12 = AngleBetweenVectors(vt1,vt2);
rarc12 = 180*arc12/pi;
Vector3f vtnor=Cross(vt1,vt2); if(vtnor.z <0) total_arc -= rarc12;
else total_arc += rarc12;
if (abs(total_arc+180)<StandArc)
{ //绘出U形的位置
//draw_2Points(pt,pre_pt,pt1,pt2,CV_RGB(255,255,250));
save_Points(pt,pre_pt,pt1,pt2,U_TYPE);
HasFoundedJoint = true ;
}
if (abs(total_arc-180)<nStandArc)
{ //记录n形点的位置 OpenGL人体运动识别及模型模拟+文献综述(4):http://www.751com.cn/tongxin/lunwen_6467.html