一、iou的简介及原理解析
iou 的全称为交并比(intersection over union),通过这个名称我们大概可以猜到 iou 的计算方法。iou 计算的是 “预测的边框” 和 “真实的边框” 的交集和并集的比值。
开始计算之前,我们首先进行分析下交集和并集到底应该怎么计算:我们首先需要计算交集,然后并集通过两个边框的面积的和减去交集部分即为并集,因此 iou 的计算的难点在于交集的计算。
为了计算交集,你脑子里首先想到的方法应该是:考虑两个边框的相对位置,然后按照相对位置(左上,左下,右上,右下,包含,互不相交)分情况讨论,来计算交集。
上图就是你的直觉,这样想没有错。但计算一个交集,就要分多种情况讨论,要是程序真的按照这逻辑编写就太搞笑了。因此对这个问题进行进一步地研究显得十分有必要。
让我们重新思考一下两个框交集的计算。两个框交集的计算的实质是两个集合交集的计算,因此我们可以将两个框的交集的计算简化为:
通过简化,我们可以清晰地看到,交集计算的关键是交集上下界点(图中蓝点)的计算。
我们假设集合 a 为 [x1,x2],集合 b 为 [y1,y2]。然后我们来求ab交集的上下界限。
交集计算的逻辑
- 交集下界z1:max(x1,y1)
- 交集上界z2:min(x2,y2)
- 如果z2-z1小于0,则说明集合 a 和集合 b 没有交集。
下面使用python来实现两个一维集合的 iou 的计算:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
def iou(set_a, set_b): ''' 一维 iou 的计算 ''' x1, x2 = set_a # (left, right) y1, y2 = set_b # (left, right) low = max (x1, y1) high = min (x2, y2) # intersection if high - low< 0 : inter = 0 else : inter = high - low # union union = (x2 - x1) + (y2 - y1) - inter # iou iou = inter / union return iou |
上面,我们计算了两个一维集合的 iou,将上面的程序进行扩展,即可得到两个框 iou 计算的程序。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
def iou(box1, box2): ''' 两个框(二维)的 iou 计算 注意:边框以左上为原点 box:[top, left, bottom, right] ''' in_h = min (box1[ 2 ], box2[ 2 ]) - max (box1[ 0 ], box2[ 0 ]) in_w = min (box1[ 3 ], box2[ 3 ]) - max (box1[ 1 ], box2[ 1 ]) inter = 0 if in_h< 0 or in_w< 0 else in_h * in_w union = (box1[ 2 ] - box1[ 0 ]) * (box1[ 3 ] - box1[ 1 ]) + \ (box2[ 2 ] - box2[ 0 ]) * (box2[ 3 ] - box2[ 1 ]) - inter iou = inter / union return iou |
二、基于tensorflow的iou实现
上节介绍了iou,及其的计算,下面我们给出其在 tensorflow 上的实现:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
import tensorflow as tf def iou_calculator(x, y, w, h, l_x, l_y, l_w, l_h): """calaulate iou args: x: net predicted x y: net predicted y w: net predicted width h: net predicted height l_x: label x l_y: label y l_w: label width l_h: label height returns: iou """ # convert to coner x_max = x + w / 2 y_max = y + h / 2 x_min = x - w / 2 y_min = y - h / 2 l_x_max = l_x + l_w / 2 l_y_max = l_y + l_h / 2 l_x_min = l_x - l_w / 2 l_y_min = l_y - l_h / 2 # calculate the inter inter_x_max = tf.minimum(x_max, l_x_max) inter_x_min = tf.maximum(x_min, l_x_min) inter_y_max = tf.minimum(y_max, l_y_max) inter_y_min = tf.maximum(y_min, l_y_min) inter_w = inter_x_max - inter_x_min inter_h = inter_y_max - inter_y_min inter = tf.cond(tf.logical_or(tf.less_equal(inter_w, 0 ), tf.less_equal(inter_h, 0 )), lambda :tf.cast( 0 ,tf.float32), lambda :tf.multiply(inter_w,inter_h)) # calculate the union union = w * h + l_w * l_h - inter iou = inter / union return iou |
以上就是解析目标检测之iou的详细内容,更多关于目标检测iou的资料请关注服务器之家其它相关文章!
原文链接:https://blog.csdn.net/u014061630/article/details/82818112