|
a |
|
b/CrowdVoting/evaluation.py |
|
|
1 |
""" |
|
|
2 |
This is the code for analyzing detection results, calculating patient score. Generate .txt for all the bbox labels respectively and name them by patientID_frameId.txt |
|
|
3 |
Format: Ymin Xmin Ymax Xmax |
|
|
4 |
eg., 361.0 293.0 397.0 325.0 |
|
|
5 |
file name example: 48_12.txt |
|
|
6 |
|
|
|
7 |
@detect_res_file: the txt file contains the detection results. Format: jpg name,Ymin,Xmin,Ymax,Xmax,score |
|
|
8 |
jpg name format:patientId_frameId.jpg |
|
|
9 |
eg: 18_10.jpg,491.96744,113.14628,533.2568,153.23444,0.9348341,0.7855689961758875 |
|
|
10 |
@test_id: the tested patient or you wanna test all patients, input[] |
|
|
11 |
eg:[18,48,60] |
|
|
12 |
|
|
|
13 |
The output is written into eva_result.txt: format: patient id(missing if all patients are tested), patient score |
|
|
14 |
eg.18,1.0 |
|
|
15 |
""" |
|
|
16 |
|
|
|
17 |
import numpy as np |
|
|
18 |
|
|
|
19 |
detect_res_file = "crowd_vote_result.txt" |
|
|
20 |
patient_ids=[18] |
|
|
21 |
|
|
|
22 |
def main(detect_res_file, patient_ids): |
|
|
23 |
if len(patient_ids)==0: |
|
|
24 |
return(str(patient_score_eva(detect_res_file,-1))) |
|
|
25 |
else: |
|
|
26 |
score=list() |
|
|
27 |
for patient_id in patient_ids: |
|
|
28 |
cur_score = str(patient_score_eva(detect_res_file,patient_id)) |
|
|
29 |
score.append(str(patient_id)+","+cur_score) |
|
|
30 |
return score |
|
|
31 |
|
|
|
32 |
|
|
|
33 |
#this is the function for calculating iou |
|
|
34 |
def bbox_iou(a, b): |
|
|
35 |
epsilon = 1e-5 |
|
|
36 |
# COORDINATES OF THE INTERSECTION BOX |
|
|
37 |
y1 = max(a[0], b[0]) |
|
|
38 |
x1 = max(a[1], b[1]) |
|
|
39 |
y2 = min(a[2], b[2]) |
|
|
40 |
x2 = min(a[3], b[3]) |
|
|
41 |
|
|
|
42 |
# AREA OF OVERLAP - Area where the boxes intersect |
|
|
43 |
width = (x2 - x1) |
|
|
44 |
height = (y2 - y1) |
|
|
45 |
# handle case where there is NO overlap |
|
|
46 |
if (width < 0) or (height < 0): |
|
|
47 |
return 0.0 |
|
|
48 |
area_overlap = width * height |
|
|
49 |
|
|
|
50 |
# COMBINED AREA |
|
|
51 |
area_a = (a[2] - a[0]) * (a[3] - a[1]) |
|
|
52 |
area_b = (b[2] - b[0]) * (b[3] - b[1]) |
|
|
53 |
area_combined = area_a + area_b - area_overlap |
|
|
54 |
|
|
|
55 |
# RATIO OF AREA OF OVERLAP OVER COMBINED AREA |
|
|
56 |
iou = area_overlap / (area_combined+epsilon) |
|
|
57 |
return iou |
|
|
58 |
|
|
|
59 |
#this is the function for calculating patient score |
|
|
60 |
def patient_score_eva(file_name,patient_id): |
|
|
61 |
with open(file_name,'r') as f: |
|
|
62 |
lines = f.readlines() |
|
|
63 |
info=list() |
|
|
64 |
img_name=list() |
|
|
65 |
label_boxes = dict() |
|
|
66 |
for line in lines: |
|
|
67 |
cur_patient = int(line.split("_")[0]) |
|
|
68 |
if cur_patient==patient_id or patient_id==-1: |
|
|
69 |
sp=line.split("jpg") |
|
|
70 |
cur_img_name = sp[0] |
|
|
71 |
|
|
|
72 |
cur_frame = int(cur_img_name.split("_")[0].replace(".","")) |
|
|
73 |
cur_box_info = sp[1].split(",") |
|
|
74 |
|
|
|
75 |
#find the label for cur img |
|
|
76 |
if cur_img_name in label_boxes: |
|
|
77 |
label_box=label_boxes[cur_img_name] |
|
|
78 |
else: |
|
|
79 |
cur_img_label = cur_img_name.replace(".",".txt") |
|
|
80 |
label_box=[-1,-1,-1,-1] |
|
|
81 |
with open(cur_img_label) as f: |
|
|
82 |
cur_content = f.read().strip('\n') |
|
|
83 |
ls_label_box = cur_content.split(" ") |
|
|
84 |
for i in range(4): |
|
|
85 |
label_box[i]=float(ls_label_box[i]) |
|
|
86 |
label_boxes[cur_img_name]=label_box |
|
|
87 |
|
|
|
88 |
#read loc for cur img and calculate iou |
|
|
89 |
cur_box=[-1,-1,-1,-1] |
|
|
90 |
for i in range(4): |
|
|
91 |
cur_box[i]=float(cur_box_info[i+1]) |
|
|
92 |
cur_iou = bbox_iou(cur_box,label_box) |
|
|
93 |
#read score for cur img |
|
|
94 |
cur_score = float(cur_box_info[5].replace("\n","")) |
|
|
95 |
|
|
|
96 |
cur_info=[cur_patient,cur_frame,cur_iou,cur_score] |
|
|
97 |
info.append(cur_info) |
|
|
98 |
img_name.append(cur_img_name) |
|
|
99 |
|
|
|
100 |
m=np.array(info) |
|
|
101 |
select_res=list() |
|
|
102 |
|
|
|
103 |
#if one frame has several bounding boxes, then selecet the one with max score |
|
|
104 |
for cur_img_name in set(img_name): |
|
|
105 |
cur_patient = int(cur_img_name.split("_")[0]) |
|
|
106 |
cur_frame = int(cur_img_name.split("_")[0].replace(".","")) |
|
|
107 |
max_score=-1 |
|
|
108 |
select_img = -1 |
|
|
109 |
for i in range(len(m)): |
|
|
110 |
if m[i,0]==cur_patient and m[i,1]==cur_frame and m[i,3]>max_score: |
|
|
111 |
max_score=m[i,1] |
|
|
112 |
select_img=i |
|
|
113 |
select_res.append(m[select_img,]) |
|
|
114 |
|
|
|
115 |
#find the number of res with iou>0 |
|
|
116 |
r=np.array(select_res) |
|
|
117 |
count=0 |
|
|
118 |
for i in range(len(r)): |
|
|
119 |
if r[i,2]>0: |
|
|
120 |
count+=1 |
|
|
121 |
|
|
|
122 |
patient_score = count/len(r) |
|
|
123 |
return patient_score |
|
|
124 |
|
|
|
125 |
|
|
|
126 |
if __name__ == '__main__': |
|
|
127 |
eva_result=main(detect_res_file, patient_ids) |
|
|
128 |
with open('eva_result.txt', 'w') as f: |
|
|
129 |
for item in eva_result: |
|
|
130 |
f.write("%s" % item) |