1
+ % A MATLAB Toolbox
2
+ %
3
+ % Compare two segmentation results using
4
+ % 1. Probabilistic Rand Index
5
+ % 2. Variation of Information
6
+ % 3. Global Consistency Error
7
+ %
8
+ % IMPORTANT: The two input images must have the same size!
9
+ %
10
+ % Authors: John Wright, and Allen Y. Yang
11
+ % Contact: Allen Y. Yang <[email protected] >
12
+ %
13
+ % (c) Copyright. University of California, Berkeley. 2007.
14
+ %
15
+ % Notice: The packages should NOT be used for any commercial purposes
16
+ % without direct consent of their author(s). The authors are not responsible
17
+ % for any potential property loss or damage caused directly or indirectly by the usage of the software.
18
+
19
+ function [ri ,gce ,vi ]=compare_segmentations(sampleLabels1 ,sampleLabels2 )
20
+
21
+ % compare_segmentations
22
+ %
23
+ % Computes several simple segmentation benchmarks. Written for use with
24
+ % images, but works for generic segmentation as well (i.e. if the
25
+ % sampleLabels inputs are just lists of labels, rather than rectangular
26
+ % arrays).
27
+ %
28
+ % The measures:
29
+ % Rand Index
30
+ % Global Consistency Error
31
+ % Variation of Information
32
+ %
33
+ % The Rand Index can be easily extended to the Probabilistic Rand Index
34
+ % by averaging the result across all human segmentations of a given
35
+ % image:
36
+ % PRI = 1/K sum_1^K RI( seg, humanSeg_K ).
37
+ % With a little more work, this can also be extended to the Normalized
38
+ % PRI.
39
+ %
40
+ % Inputs:
41
+ % sampleLabels1 - n x m array whose entries are integers between 1
42
+ % and K1
43
+ % sampleLabels2 - n x m (sample size as sampleLabels1) array whose
44
+ % entries are integers between 1 and K2 (not
45
+ % necessarily the same as K1).
46
+ % Outputs:
47
+ % ri - Rand Index
48
+ % gce - Global Consistency Error
49
+ % vi - Variation of Information
50
+ %
51
+ % NOTE:
52
+ % There are a few formulas here that look less-straightforward (e.g.
53
+ % the log2_quotient function). These exist to handle corner cases
54
+ % where some of the groups are empty, and quantities like 0 *
55
+ % log(0/0) arise...
56
+ %
57
+ % Oct. 2006
58
+ % Questions? John Wright - [email protected]
59
+
60
+ [imWidth ,imHeight ]=size(sampleLabels1 );
61
+ [imWidth2 ,imHeight2 ]=size(sampleLabels2 );
62
+ N= imWidth * imHeight ;
63
+ if (imWidth ~= imWidth2 )||(imHeight ~= imHeight2 )
64
+ disp( ' Input sizes: ' );
65
+ disp( size(sampleLabels1 ) );
66
+ disp( size(sampleLabels2 ) );
67
+ error(' Input sizes do not match in compare_segmentations.m' );
68
+ end ;
69
+
70
+ % make the group indices start at 1
71
+ if min(min(sampleLabels1 )) < 1
72
+ sampleLabels1 = sampleLabels1 - min(min(sampleLabels1 )) + 1 ;
73
+ end
74
+ if min(min(sampleLabels2 )) < 1
75
+ sampleLabels2 = sampleLabels2 - min(min(sampleLabels2 )) + 1 ;
76
+ end
77
+
78
+ segmentcount1= max(max(sampleLabels1 ));
79
+ segmentcount2= max(max(sampleLabels2 ));
80
+
81
+ % compute the count matrix
82
+ % from this we can quickly compute rand index, GCE, VOI, ect...
83
+ n= zeros(segmentcount1 ,segmentcount2 );
84
+
85
+ for i= 1 : imWidth
86
+ for j= 1 : imHeight
87
+ u= sampleLabels1(i ,j );
88
+ v= sampleLabels2(i ,j );
89
+ n(u ,v )=n(u ,v )+1 ;
90
+ end ;
91
+ end ;
92
+
93
+ ri = rand_index(n );
94
+ gce = global_consistancy_error(n );
95
+ vi = variation_of_information(n );
96
+
97
+ return ;
98
+
99
+
100
+ % the performance measures
101
+
102
+ % the rand index, in [0,1] ... higher => better
103
+ % fast computation is based on equation (2.2) of Rand's paper.
104
+ function ri = rand_index(n )
105
+ N = sum(sum(n ));
106
+ n_u= sum(n ,2 );
107
+ n_v= sum(n ,1 );
108
+ N_choose_2= N *(N - 1 )/2 ;
109
+ ri = 1 - ( sum(n_u .* n_u )/2 + sum(n_v .* n_v )/2 - sum(sum(n .* n )) )/N_choose_2 ;
110
+
111
+ % global consistancy error (from BSDS ICCV 01 paper) ... lower => better
112
+ function gce = global_consistancy_error(n )
113
+ N = sum(sum(n ));
114
+ marginal_1 = sum(n ,2 );
115
+ marginal_2 = sum(n ,1 );
116
+ % the hackery is to protect against cases where some of the marginals are
117
+ % zero (should never happen, but seems to...)
118
+ E1 = 1 - sum( sum(n .* n ,2 ) ./ (marginal_1 + (marginal_1 == 0 )) ) / N ;
119
+ E2 = 1 - sum( sum(n .* n ,1 ) ./ (marginal_2 + (marginal_2 == 0 )) ) / N ;
120
+ gce = min( E1 , E2 ) ;
121
+
122
+
123
+ % variation of information a "distance", in (0,vi_max] ... lower => better
124
+ function vi = variation_of_information(n )
125
+ N = sum(sum(n ));
126
+ joint = n / N ; % the joint pmf of the two labels
127
+ marginal_2 = sum(joint ,1 ); % row vector
128
+ marginal_1 = sum(joint ,2 ); % column vector
129
+ H1 = - sum( marginal_1 .* log2(marginal_1 + (marginal_1 == 0 ) ) ); % entropy of the first label
130
+ H2 = - sum( marginal_2 .* log2(marginal_2 + (marginal_2 == 0 ) ) ); % entropy of the second label
131
+ MI = sum(sum( joint .* log2_quotient( joint , marginal_1 * marginal_2 ) )); % mutual information
132
+ vi = H1 + H2 - 2 * MI ;
133
+
134
+ % log2_quotient
135
+ % helper function for computing the mutual information
136
+ % returns a matrix whose ij entry is
137
+ % log2( a_ij / b_ij ) if a_ij, b_ij > 0
138
+ % 0 if a_ij is 0
139
+ % log2( a_ij + 1 ) if a_ij > 0 but b_ij = 0 (this behavior should
140
+ % not be encountered in practice!
141
+ function lq = log2_quotient( A , B )
142
+ lq = log2( (A + ((A == 0 ).*B ) + (B == 0 )) ./ (B + (B == 0 )) );
0 commit comments