//draw_2Points(pt,pre_pt,pt1,pt2,CV_RGB(230,255,0));
save_Points(pt,pre_pt,pt1,pt2,N_TYPE);
HasFoundedJoint = true ;
}
检查角度范围 U型点 -200至-160
N型点 150至 210
3.3 无用干扰点的筛除
由于本算法是先提取运动人体外部轮廓,然后分辨关键节点,如果轮廓提取时产生不符合人体形态的点,将会对后续操作产生判定干扰,所以需要对轮廓点进行筛选,简化无信息含量的细节,同时去除干扰点。
在本算法中,关键在于记录U型点和N型点,也就是对四肢的关键节点提取,所以我们在得到的人体轮廓上不希望出现难以识别的正方形(事实上只有躯体部分是类正方形),于是需要将这种错误产生的正方形的干扰节点筛除,以防产生误判。这里用到了两种判定方法:
① 取两个矢量中心点连线,取连线与较大矢量的夹角,如果夹角在90度偏差20度内认为是正方形。
HumanMotion::Is_Closed_Vectors(CvPoint pt1,CvPoint pt2,CvPoint pt3,CvPoint pt4)
{
CvPoint pt5,pt6;
const float StandSqArc = 40;
pt5.x= (pt1.x + pt2.x ) /2;
pt5.y= (pt1.y + pt2.y ) /2;
pt6.x= (pt3.x + pt4.x ) /2;
pt6.y= (pt3.y + pt4.y ) /2;
Vector3f vt1 = Vector3f (pt1.x-pt2.x,pt1.y-pt2.y,0);
Vector3f vt2 = Vector3f (pt3.x-pt4.x,pt3.y-pt4.y,0);
Vector3f vtc = Vector3f (pt6.x-pt5.x,pt6.y-pt5.y,0);
Vector3f vtmax;
if(Magnitude(vt1) > Magnitude(vt2))
vtmax= vt1;
else
vtmax= vt2;
double arc12 = AngleBetweenVectors(vtc,vtmax);
double rarc12 = 180*arc12/pi;
if (abs(abs(rarc12)-90)<StandSqArc)
return true;
else
return false;
}
② 两矢量长度不等,差距相差4倍时,认为无效;或者两矢量错位,不协调,即对角线长度大于两矢量长度的两倍。
HumanMotion::Is_Apar_Vectors(CvPoint pt1,CvPoint pt2,CvPoint pt3,CvPoint pt4)
{
bool result = false;
const float StandLenRatio = 4.0;
const float StandCrossLenRatio = 2.0;
Vector3f vt1 = Vector3f (pt1.x-pt2.x,pt1.y-pt2.y,0);
Vector3f vt2 = Vector3f (pt3.x-pt4.x,pt3.y-pt4.y,0);
//1.两矢量长度不等,差距相差4倍时,认为无效
double lenvct1,lenvct2,raido12;
lenvct1 = Magnitude(vt1);
lenvct2 = Magnitude(vt2);
raido12 = lenvct1/lenvct2;
if( raido12<StandLenRatio && raido12 > 1/StandLenRatio )
result = true ;
//2.两矢量错位,不协调,即对角线长度大于两矢量长度的两倍。
if(result)
{
Vector3f vtc1 = Vector3f (pt1.x-pt3.x,pt1.y-pt3.y,0); //对角线1 OpenGL人体运动识别及模型模拟+文献综述(5):http://www.youerw.com/tongxin/lunwen_6467.html