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