从轮廓中取得四肢与头部的算法

从轮廓中取得四肢与头部的算法

实现了取得四肢与头部的算法,即取得五个U形的端点.

从轮廓中取得四肢与头部的算法_第1张图片
算法如下:


int SegmentBody(CvSeq* contour)
{
float StandBodyLength = 10.0;
float StandArc = 40;
float lk,l1,l2=0;
CvPoint pt1,pt2,pt0;
double total_arc = 0; //内旋角度
double rarc12= 0;
double arc12= 0;

bool Haslkvec = false; //是否存在先前记录的矢量

CvSeqReader reader;
CvSeqReader subReader;
int N = contour->total;
int i;
CvPoint pt;
CvPoint pre_pt;
CvPoint pre_pre_pt;

//CvFont font;
//cvInitFont( &font, CV_FONT_HERSHEY_SIMPLEX, 0.3, 0.3, 0.0, 1, CV_AA );


cvStartReadSeq(contour, &reader);

for (i= 0; i < N; i++)
{
   CV_READ_SEQ_ELEM(pt, reader);
   //printf("%d,%d \n",pt.x,pt.y);
   pre_pt = pre_pre_pt = pt;
  
  
   //draw_cross( pt, CV_RGB(255,255,255), 3 );

   if(i==9)
    draw_cross( pt, CV_RGB(240,222,240), 3 );
     
   //cvLine( dst, pt,pre_pt,CV_RGB(0,255,0),2,CV_AA, 0 );
   //计算两点之间的距离
   subReader = reader ;

   Haslkvec = false;
   total_arc =0;

   //printf("------------------ \n");
   //printf("%d,%d \n",pt.x,pt.y);
   for(int j=0;j<5;j++)
   {  
    //printf("in sub %d,%d \n",pt.x,pt.y);
    l1=calc_2Point_Magnitude(pt,pre_pt);
    if (l1>StandBodyLength)
    {
     //是否存在先前记录的点,如果有,检查角度范围
     if(Haslkvec)
     {
     
      Vector3f vt1 = Vector3f (pre_pre_pt.x-pre_pt.x,pre_pre_pt.y-pre_pt.y,0);
      Vector3f vt2 = Vector3f (pre_pt.x-pt.x,pre_pt.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;


     
      //检查角度范围合理 -200 -160
      if (abs(total_arc+180)<StandArc)
      {
      
       //检查平行线之间构成四边形是否在同一轴线上,相似度判断
       if(Is_Closed_Vectors(pt,pre_pt,pt1,pt2))
       {
        //匹配成功,完成一个搜索    
        //记录两个矢量,清空标记    
        Haslkvec = false;
        total_arc = 0;
        //绘出位置
        draw_2Points(pt,pre_pt,pt1,pt2);


        //跳过已经成形的点,好处是减少计算,二是避免歧异点
        for(int k=0;k<j;k++)
        {
         CV_READ_SEQ_ELEM(pt, reader);
         pre_pt = pre_pre_pt = pt;
        }

       }
       //cvShowImage( "Components", dst );
       //cvWaitKey(0);

       break;
      }

     }
     else
     {
      //记录两个点
      pt1=pt;
      pt2=pre_pt;
      Haslkvec = true;
     }
    
    }
    //对于短线段忽略,并且跳过其检测点,将加快检测速度。
    else
    {
     pt = pre_pt;
     pre_pt = pre_pre_pt;        
    }

    pre_pre_pt = pre_pt;
    pre_pt= pt;
    CV_READ_SEQ_ELEM(pt, subReader);
   

   }

}


return 0;
}


你可能感兴趣的:(算法,vector,float,DST,Components)