Intersect over Union[IoU] C++ / Python 코드

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;

}

 

 


참고문헌

 

Ronny Restrepo

Intersect over Union (IoU) Intersect over Union (IoU) is a metric that allows us to evaluate how similar our predicted bounding box is to the ground truth bounding box. The idea is that we want to compare the ratio of the area where the two boxes overlap t

ronny.rest