判断两个矩形是否相交(C++)

最近在研究opencv识别红绿灯的任务,用的是机器学习+图像处理的方法,但有个麻烦的问题就是误识别率很高,为了把这些误识别出的物体给过滤点,我想到了通过颜色占比的方法来过滤,结果是可以过滤点一部分,但不能完全过滤。没办法,接下来有打算用红绿灯框匹配灯的办法来过滤,这就涉及到框矩形和灯矩形的匹配问题,又延伸到了平面坐标系下两个矩形的交叉问题,想了想,总结算法如下。


#include <stdio.h>
 
int
between( double  d1,  double  d2,  double  d3)
{
     if  (d1 < d2) {
         return  (d1 <= d3 && d3 <= d2);
     else  {
         return  (d2 <= d3 && d3 <= d1);
     }
 
     return  0;
}
 
 
/*
  * 几种重叠的情况
  *
  * 1. B 至少有一个顶点在 A 的内部
  *     -----------------
  *     |A              |
  *     |               |
  *     |           ------------
  *     |           |   |      |
  *     |           |   |      |
  *     ------------|----      |
  *                 |         B|
  *                 ------------
  *
  * 2. 如果 B 的顶点都在 A 的外部
  *    重叠的条件是 A 的对角顶点至少有一个在 B 的内部
  * 2.1
  * ----------------------------
  * |                          |
  * |   -----------------      |
  * |   |A              |      |
  * |   |               |     B|
  * ----------------------------
  *     |               |       
  *     |               |       
  *     -----------------       
  *
  * 2.2
  * ----------------------------
  * |                          |
  * |   -----------------      |
  * |   |A              |      |
  * |   |               |      |
  * |   |               |      |
  * |   |               |      |
  * |   -----------------     B|
  * ----------------------------
  *
  *  3. 十字交叉情况1
  *       ----------
  *       |A       |
  *       |        |
  * ----------------------------
  * |     |        |           |
  * |     |        |          B|
  * ----------------------------
  *       |        |
  *       |        |
  *       ----------
  *
  *  4. 十字交叉情况2
  *       ----------
  *       |        |
  *       |        |
  * ----------------------------
  * |A    |        |           |
  * |     |        |           |
  * ----------------------------
  *       |        |
  *       |       B|
  *       ----------
  */
int
overlap(
         double  xa1,  double  ya1,  double  xa2,  double  ya2,
         double  xb1,  double  yb1,  double  xb2,  double  yb2)
{
     /* 1 */
     if  (between(xa1, xa2, xb1) && between(ya1, ya2, yb1))
         return  1;
     if  (between(xa1, xa2, xb2) && between(ya1, ya2, yb2))
         return  1;
     if  (between(xa1, xa2, xb1) && between(ya1, ya2, yb2))
         return  1;
     if  (between(xa1, xa2, xb2) && between(ya1, ya2, yb1))
         return  1;
 
 
     /* 2 */
     if  (between(xb1, xb2, xa1) && between(yb1, yb2, ya1))
         return  1;
     if  (between(xb1, xb2, xa2) && between(yb1, yb2, ya2))
         return  1;
 
     /* 3 */
     if  ( (between(ya1, ya2, yb1) && between(ya1, ya2, yb2))
       && (between(xb1, xb2, xa1) && between(xb1, xb2, xa2)) )
         return  1;
 
     /* 4 */
     if  ( (between(xa1, xa2, xb1) && between(xa1, xa2, xb2))
       && (between(yb1, yb2, ya1) && between(yb1, yb2, ya2)) )
         return  1;
 
     return  0;
}
 
int
main( int  argc,  char  *argv[])
{
     int  ret;
     double  xa1, ya1, xa2, ya2;
     double  xb1, yb1, xb2, yb2;
 
     xa1 = 0.0; ya1 = 0.0;
     xa2 = 9.0; ya2 = 9.0;
 
     xb1 = 10.0; yb1 = 10.0;
     xb2 = 19.0; yb2 = 19.0;
     ret = overlap(xa1, ya1, xa2, ya2, xb1, yb1, xb2, yb2);
     printf ( "(%f,%f),(%f,%f): %d\n" , xb1, yb1, xb2, yb2, ret);
 
     xb1 = 10.0; yb1 = 10.0;
     xb2 = 19.0; yb2 = 19.0;
     ret = overlap(xa1, ya1, xa2, ya2, xb1, yb1, xb2, yb2);
     printf ( "(%f,%f),(%f,%f): %d\n" , xb1, yb1, xb2, yb2, ret);
 
     xb1 =  8.0; yb1 =  8.0;
     xb2 = 19.0; yb2 = 19.0;
     ret = overlap(xa1, ya1, xa2, ya2, xb1, yb1, xb2, yb2);
     printf ( "(%f,%f),(%f,%f): %d\n" , xb1, yb1, xb2, yb2, ret);
 
     xb1 =  9.0; yb1 =  9.0;
     xb2 = 19.0; yb2 = 19.0;
     ret = overlap(xa1, ya1, xa2, ya2, xb1, yb1, xb2, yb2);
     printf ( "(%f,%f),(%f,%f): %d\n" , xb1, yb1, xb2, yb2, ret);
 
     xb1 = -1.0; yb1 =  5.0;
     xb2 = 10.0; yb2 = 10.0;
     ret = overlap(xa1, ya1, xa2, ya2, xb1, yb1, xb2, yb2);
     printf ( "(%f,%f),(%f,%f): %d\n" , xb1, yb1, xb2, yb2, ret);
 
     xb1 = -1.0; yb1 = -1.0;
     xb2 = 10.0; yb2 = 10.0;
     ret = overlap(xa1, ya1, xa2, ya2, xb1, yb1, xb2, yb2);
     printf ( "(%f,%f),(%f,%f): %d\n" , xb1, yb1, xb2, yb2, ret);
 
     /* 3 */
     xb1 =  2.0; yb1 = -2.0;
     xb2 =  5.0; yb2 = 12.0;
     ret = overlap(xa1, ya1, xa2, ya2, xb1, yb1, xb2, yb2);
     printf ( "(%f,%f),(%f,%f): %d\n" , xb1, yb1, xb2, yb2, ret);
 
     /* 4 */
     xb1 = -2.0; yb1 =  2.0;
     xb2 = 15.0; yb2 =  3.0;
     ret = overlap(xa1, ya1, xa2, ya2, xb1, yb1, xb2, yb2);
     printf ( "(%f,%f),(%f,%f): %d\n" , xb1, yb1, xb2, yb2, ret);
 
 
 
     return  0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值