IOU(Intersect over Union)
IoU는 아래의 그림[1] 같이 구해진다. 예측된 바운더리 박스와 사용자가 설정한 바운더리 박스 간 중첩되는 부분의 면적을 측정해서 중첩된 면적을 합집합의 면적으로 나눠준다.
IoU의 계산 결과 값이 0.5 이상이면 제대로 검출(TP)되었다고 판단한다. 만약 0.5 미만이면 잘못 검출(FP)되었다고 판단한다. (이 값은 임의의 값으로 설정할 수 있다.)
중첩 영역 계산
중첩 영역 계산은 박스 A, 박스 B의 왼쪽 상단, 오른쪽 하단의 좌표 값을 이용하여 중첩 부분의 왼쪽 상단, 오른쪽 하단의 값을 구한다. 그리고 width, height 값을 이용하여 Overlapping region 값을 구한다.
결합 영역 계산
중첩 영역 계산을 이용하여 구한 Overlapping region과 박스 A, 박스 B 값을 이용하여 결합 영역을 계산한다.
IOU 점수 해석
Python 코드
def get_iou(a, b, epsilon=1e-5):
# COORDINATES OF THE INTERSECTION BOX
x1 = max(a[0], b[0])
y1 = max(a[1], b[1])
x2 = min(a[2], b[2])
y2 = min(a[3], b[3])
# AREA OF OVERLAP - Area where the boxes intersect
width = (x2 - x1)
height = (y2 - y1)
# handle case where there is NO overlap
if (width<0) or (height <0):
return 0.0
area_overlap = width * height
# COMBINED AREA
area_a = (a[2] - a[0]) * (a[3] - a[1])
area_b = (b[2] - b[0]) * (b[3] - b[1])
area_combined = area_a + area_b - area_overlap
# RATIO OF AREA OF OVERLAP OVER COMBINED AREA
iou = area_overlap / (area_combined+epsilon)
return iou
C++ 코드
std::vector<float> ofApp::IouValue(std::vector<ofVec4f> Input, std::vector<ofVec4f> Human) {
vector<float> iou;
ofVec2f tmpinput_leftup;
ofVec2f tmpinput_rightdown;
ofVec2f tmphuman_leftup;
ofVec2f tmphuman_rightdown;
int x1, y1, x2, y2;
int tmpwidth;
int tmpheight;
float area_overlap;
float area_a;
float area_b;
float area_combined;
float epsilon;
int maxsize = max(Input.size(), (Human.size()));
iou.resize(maxsize);
for (int k = 0; k < maxsize; k++) {
tmpinput_leftup.x = Input[k].x;
tmpinput_leftup.y = Input[k].y;
tmpinput_rightdown.x = Input[k].x + Input[k].z;
tmpinput_rightdown.y = Input[k].y + Input[k].w;
tmphuman_leftup.x = Human[k].x;
tmphuman_leftup.y = Human[k].y;
tmphuman_rightdown.x = Human[k].x + Human[k].z;
tmphuman_rightdown.y = Human[k].y + Human[k].w;
x1 = max(tmpinput_leftup.x, tmphuman_leftup.x);
y1 = max(tmpinput_leftup.y, tmphuman_leftup.y);
x2 = min(tmpinput_rightdown.x, tmphuman_rightdown.x);
y2 = min(tmpinput_rightdown.y, tmphuman_rightdown.y);
tmpwidth = (x2 - x1);
tmpheight = (y2 - y1);
if (tmpwidth < 0 || tmpheight < 0) {
iou[k] = 0.0f;
continue;
}
area_overlap = tmpwidth * tmpheight;
area_a = (tmpinput_rightdown.x - tmpinput_leftup.x) * (tmpinput_rightdown.y - tmpinput_leftup.y);
area_b = (tmphuman_rightdown.x - tmphuman_leftup.x) * (tmphuman_rightdown.y - tmphuman_leftup.y);
area_combined = area_a + area_b - area_overlap;
epsilon = 1e-5;
iou[k] = area_overlap / (area_combined + epsilon);
}
return iou;
}
참고문헌