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)