OpenVc判断矩形是否相交算法

来源:互联网 发布:推荐手机支架 知乎 编辑:程序博客网 时间:2024/06/03 17:45

在opencv中,对于跟踪的目标,通常用矩形进行圈定,但是Opencv的cvFindContours却不会那么精确,通常会将一个目标分成若干个相邻或相交或包含关系的矩形,此时需要判断这些矩的关系,以便进行融合,矩形之间的关系通常又很复杂,通常会有如下关系




在网上还确实不好找,有的是基于两条线是否相交,然后进行两两相交16次判断,但很多算法有bug,最典型是两条X一样的直线不相交会判断成相交,另外呢,由于矩形是平的或是垂直的,没必要复杂的数学运算。

做了两个函数,一个是判断线相交,一个是判断矩形相交,代码不用细看,直接用就行了

1、直线是否相交

BOOL IsLineSegmentCross(POINT pt1, POINT pt2, POINT pt3, POINT pt4,int iLinesRelation)
{
 int iL1,iL2,iL3,iL4,iMax;
 if(iLinesRelation==0)  //平行关系
 {
  if(pt1.y==pt2.y)//横线
  {
   if(pt1.y!=pt3.y)
    return FALSE;
   else    //两条线Y值相同
   {
    iL1=abs(pt1.x-pt2.x);
    iL2=abs(pt3.x-pt4.x);
    iL3=abs(pt3.x-pt2.x);
    iL4=abs(pt4.x-pt1.x);
    if(iL3>iL4)
     iMax=iL3;
    else
     iMax=iL4;
    if(iL1+iL2
     return FALSE;
    else
     return TRUE;
   }
  }
  else     //坚线
  {
   if(pt1.x!=pt3.x)
    return FALSE;
   else
   {
    iL1=abs(pt1.y-pt2.y);
    iL2=abs(pt3.y-pt4.y);
    iL3=abs(pt2.y-pt3.y);
    iL4=abs(pt1.y-pt4.y);
    if(iL3>iL4)
     iMax=iL3;
    else
     iMax=iL4;
    if(iL1+iL2
     return FALSE;
    else
     return TRUE;
   }
  }
 }
 else      //垂直关系
 {
  if(pt1.y==pt2.y)//横线
  {
   if(pt3.xpt2.x)
    return FALSE;
   else
   {
    if(pt1.y>=pt3.y&&pt1.y<=pt4.y)
     return TRUE;
    else
     return FALSE;
   }
  }
  else     //坚线
  {
   if(pt1.xpt4.x)
    return FALSE;
   else
   {
    if(pt3.y>=pt1.y&&pt3.y<=pt2.y)
     return TRUE;
    else
     return FALSE;
   }
  }
 }
    return TRUE; 
}
2、矩形是否相交

BOOL CNetXPlayerDlg::RectIsCross(RECT _Rect1,RECT _Rect2)
{
 POINT pt1,pt2,pt3,pt4;
//
 pt1.x=_Rect1.left;
 pt1.y=_Rect1.top;
 pt2.x=_Rect1.right;
 pt2.y=_Rect1.top;

 pt3.x=_Rect2.left;
 pt3.y=_Rect2.top;
 pt4.x=_Rect2.right;
 pt4.y=_Rect2.top;
 if(IsLineSegmentCross(pt1,pt2,pt3,pt4,0))
  return TRUE;
 pt3.x=_Rect2.right;
 pt3.y=_Rect2.top;
 pt4.x=_Rect2.right;
 pt4.y=_Rect2.bottom;
 if(IsLineSegmentCross(pt1,pt2,pt3,pt4,1))
  return TRUE;
 pt3.x=_Rect2.left;
 pt3.y=_Rect2.bottom;
 pt4.x=_Rect2.right;
 pt4.y=_Rect2.bottom;
 if(IsLineSegmentCross(pt1,pt2,pt3,pt4,0))
  return TRUE;
 pt3.x=_Rect2.left;
 pt3.y=_Rect2.top;
 pt4.x=_Rect2.left;
 pt4.y=_Rect2.bottom;
 if(IsLineSegmentCross(pt1,pt2,pt3,pt4,1))
  return TRUE;
//
 pt1.x=_Rect1.right;
 pt1.y=_Rect1.top;
 pt2.x=_Rect1.right;
 pt2.y=_Rect1.bottom;

 pt3.x=_Rect2.left;
 pt3.y=_Rect2.top;
 pt4.x=_Rect2.right;
 pt4.y=_Rect2.top;
 if(IsLineSegmentCross(pt1,pt2,pt3,pt4,1))
  return TRUE;
 pt3.x=_Rect2.right;
 pt3.y=_Rect2.top;
 pt4.x=_Rect2.right;
 pt4.y=_Rect2.bottom;
 if(IsLineSegmentCross(pt1,pt2,pt3,pt4,0))
  return TRUE;
 pt3.x=_Rect2.left;
 pt3.y=_Rect2.bottom;
 pt4.x=_Rect2.right;
 pt4.y=_Rect2.bottom;
 if(IsLineSegmentCross(pt1,pt2,pt3,pt4,1))
  return TRUE;
 pt3.x=_Rect2.left;
 pt3.y=_Rect2.top;
 pt4.x=_Rect2.left;
 pt4.y=_Rect2.bottom;
 if(IsLineSegmentCross(pt1,pt2,pt3,pt4,0))
  return TRUE;
//
 pt1.x=_Rect1.left;
 pt1.y=_Rect1.bottom;
 pt2.x=_Rect1.right;
 pt2.y=_Rect1.bottom;

 pt3.x=_Rect2.left;
 pt3.y=_Rect2.top;
 pt4.x=_Rect2.right;
 pt4.y=_Rect2.top;
 if(IsLineSegmentCross(pt1,pt2,pt3,pt4,0))
  return TRUE;
 pt3.x=_Rect2.right;
 pt3.y=_Rect2.top;
 pt4.x=_Rect2.right;
 pt4.y=_Rect2.bottom;
 if(IsLineSegmentCross(pt1,pt2,pt3,pt4,1))
  return TRUE;
 pt3.x=_Rect2.left;
 pt3.y=_Rect2.bottom;
 pt4.x=_Rect2.right;
 pt4.y=_Rect2.bottom;
 if(IsLineSegmentCross(pt1,pt2,pt3,pt4,0))
  return TRUE;
 pt3.x=_Rect2.left;
 pt3.y=_Rect2.top;
 pt4.x=_Rect2.left;
 pt4.y=_Rect2.bottom;
 if(IsLineSegmentCross(pt1,pt2,pt3,pt4,1))
  return TRUE;
//
 pt1.x=_Rect1.left;
 pt1.y=_Rect1.top;
 pt2.x=_Rect1.left;
 pt2.y=_Rect1.bottom;

 pt3.x=_Rect2.left;
 pt3.y=_Rect2.top;
 pt4.x=_Rect2.right;
 pt4.y=_Rect2.top;
 if(IsLineSegmentCross(pt1,pt2,pt3,pt4,1))
  return TRUE;
 pt3.x=_Rect2.right;
 pt3.y=_Rect2.top;
 pt4.x=_Rect2.right;
 pt4.y=_Rect2.bottom;
 if(IsLineSegmentCross(pt1,pt2,pt3,pt4,0))
  return TRUE;
 pt3.x=_Rect2.left;
 pt3.y=_Rect2.bottom;
 pt4.x=_Rect2.right;
 pt4.y=_Rect2.bottom;
 if(IsLineSegmentCross(pt1,pt2,pt3,pt4,1))
  return TRUE;
 pt3.x=_Rect2.left;
 pt3.y=_Rect2.top;
 pt4.x=_Rect2.left;
 pt4.y=_Rect2.bottom;
 if(IsLineSegmentCross(pt1,pt2,pt3,pt4,0))
  return TRUE;
 return FALSE;
}

直接使用第二个函数就行了,代码略有点....,但绝对没有BUG,性能肯定是最棒的


原文地址:http://blog.sina.com.cn/s/blog_5375c7f90102vjes.html

0 0