Intersection over Union是一种测量在特定数据集中检测相应物体准确度的一个标准。可以用在对于图像检测中输出一个预测范围的任务。如下图所示,检测的红框和真值绿框之间的相似性可以用IOU衡量,本质上是将目标检测与划分的准确度转换成检测结果和真值之间面积的比较。
两个检测区域重叠的部分/两个区域占据的部分 = 两个区域的重叠程度
I
O
U
=
A
∩
B
A
∪
B
=
A
∩
B
A
+
B
−
A
∩
B
IOU = \frac{A \cap B}{A \cup B}=\frac{A \cap B}{A + B - A\cap B}
IOU=A∪BA∩B=A+B−A∩BA∩B
从计算公式可以看出,IOU越大表示两个结果越相近,通常有一个阈值score来判断结果的好坏,IOU计算结果的例子如下:
从具体计算中即可看出,重叠区域矩形的顶点坐标是原始两个矩形顶点坐标的组合,观察不难发现其实就是四个横坐标x中中间的两个和四个纵坐标y中中间的两个,把两个原始矩形成为A和B,既有:
C
.
x
0
=
m
a
x
(
A
.
x
0
,
B
.
x
0
)
C
.
x
1
=
m
i
n
(
A
.
x
1
,
B
.
x
1
)
C
.
y
0
=
m
a
x
(
A
.
y
0
,
B
.
y
0
)
C
.
y
1
=
m
i
n
(
A
.
y
1
,
y
.
x
1
)
C.x_0 = max(A.x_0, B.x_0)\ \ \ \ C.x_1 = min(A.x_1, B.x_1) \\ C.y_0 = max(A.y_0, B.y_0)\ \ \ \ C.y_1 = min(A.y_1, y.x_1)
C.x0=max(A.x0,B.x0) C.x1=min(A.x1,B.x1)C.y0=max(A.y0,B.y0) C.y1=min(A.y1,y.x1)
我们很容易地得到了重叠处的坐标表示,就可以轻松计算处重叠除的面积了
注意:
A和B之间很可能没有重叠区域,也就是说我们还需要检查得到的矩形C坐标是否满足要求,即:
c
h
e
c
k
i
f
(
C
.
x
0
<
C
.
x
1
&
&
C
.
y
0
<
C
.
y
1
)
check\ if(C.x_0
将矩形区域用一个struct表示,将计算IOU和矩形面积的方法封装在struct里,具体内容如下:
#include
using namespace std;
struct Box{
int x0, y0; // 左上角
int x1, y1; // 右下角
Box():x0(0), y0(0), x1(0), y1(0){}
Box(int x0_, int y0_, int x1_, int y1_)
:x0(x0_), y0(y0_), x1(x1_), y1(y1_){}
float CalculateIOU(const Box &b){
Box result(max(x0, b.x0), max(y0, b.y0), min(x1, b.x1), min(y1, b.y1));
int A_area = CalculateArea();
int B_area = b.CalculateArea();
int inter_area = result.CalculateArea();
if(A_area!=0 && B_area!=0) return float(result.CalculateArea())/(float(A_area)+float(B_area) - inter_area);
else return 0;
}
int CalculateArea()const {
return (x0<x1 && y0<y1)? (x1-x0)*(y1-y0): 0;
}
};
int main(){
Box b1 = Box(0, 0 , 10, 10);
Box b2 = Box(2, 2, 12, 12);
Box b3 = Box(3, 5, 15, 8);
cout << b1.CalculateIOU(b2) << endl;
cout << b1.CalculateIOU(b3) << endl;
}
结果如下:
文章给出了IOU的意义+原理+具体实现,相关代码在github仓库中的Vison中
参考文献:
【深度学习】目标检测中 IOU 的概念及计算
深度学习中IU、IoU(Intersection over Union)的概念理解以及python程序实现