@@ -89,9 +89,17 @@ def generateunaries(img):
89
89
np .save ("unary" , unaries )
90
90
91
91
92
+ class Node :
93
+ def __init__ (self , nodeid , y , x ):
94
+ self .nodeid = nodeid
95
+ self .y = y
96
+ self .x = x
97
+
98
+
92
99
class Nodegrid :
93
100
def __init__ (self , ysize , xsize ):
94
101
self .g = maxflow .GraphFloat ()
102
+
95
103
self .nodeids = self .g .add_grid_nodes ((ysize , xsize ))
96
104
97
105
self .ysize = ysize
@@ -101,55 +109,63 @@ def loop(self, edgecallback, nodecallback):
101
109
"""
102
110
Loops over the grid of nodes. Two callback functions are required:
103
111
104
- :param edgecallback: Called for every edge with node id (i, j)
105
- as parameter.
106
- :param nodecallback: called for every node with node id as parameter.
112
+ :param edgecallback: Called for every edge.
113
+ :param nodecallback: Called for every node.
107
114
"""
108
115
logging .info ("Iterate through graph." )
109
116
110
117
for y in range (self .ysize - 1 ):
111
118
for x in range (self .xsize - 1 ):
119
+ node_i = self .getNode (y , x )
120
+
121
+ # Node
122
+ nodecallback (node_i , self .g )
123
+
112
124
# Right edge
113
- edgecallback ( self .nodeids [ y , x ],
114
- self . nodeids [ y , x + 1 ] , self .g )
125
+ node_j = self .getNode ( y , x + 1 )
126
+ edgecallback ( node_i , node_j , self .g )
115
127
116
128
# Down edge
117
- edgecallback (self .nodeids [y , x ],
118
- self .nodeids [y + 1 , x ], self .g )
119
-
120
- # Node
121
- nodecallback (self .nodeids [y , x ], y , x , self .g )
129
+ node_j = self .getNode (y + 1 , x )
130
+ edgecallback (node_i , node_j , self .g )
122
131
123
132
# Last column
124
133
for y in range (self .ysize - 1 ):
125
- # Down edge
126
- edgecallback (self .nodeids [y , self .xsize - 1 ],
127
- self .nodeids [y + 1 , self .xsize - 1 ], self .g )
134
+ node_i = self .getNode (y , self .xsize - 1 )
128
135
129
136
# Node
130
- nodecallback (self .nodeids [y , self .xsize - 1 ], y , x , self .g )
137
+ nodecallback (node_i , self .g )
138
+
139
+ # Down edge
140
+ node_j = self .getNode (y + 1 , self .xsize - 1 )
141
+ edgecallback (node_i , node_j , self .g )
131
142
132
143
# Last row
133
144
for x in range (self .xsize - 1 ):
134
- # Right edge
135
- edgecallback (self .nodeids [self .ysize - 1 , x ],
136
- self .nodeids [self .ysize - 1 , x + 1 ], self .g )
145
+ node_i = self .getNode (self .ysize - 1 , x )
137
146
138
147
# Node
139
- nodecallback (self .nodeids [self .ysize - 1 , x ], y , x , self .g )
148
+ nodecallback (node_i , self .g )
149
+
150
+ # Right edge
151
+ node_j = self .getNode (self .ysize - 1 , x + 1 )
152
+ edgecallback (node_i , node_j , self .g )
140
153
141
154
# Last node
142
- nodecallback (self .nodeids [ self .ysize - 1 , self .xsize - 1 ], y , x , self .g )
155
+ nodecallback (self .getNode ( self .ysize - 1 , self .xsize - 1 ) , self .g )
143
156
144
157
def loopnodes (self , callback ):
145
158
for y in range (self .ysize ):
146
159
for x in range (self .xsize ):
147
- callback (self .nodeids [ y , x ], y , x , self .g )
160
+ callback (self .getNode ( y , x ) , self .g )
148
161
149
162
def maxflow (self ):
150
163
logging .info ("Calculate max flow." )
151
164
self .g .maxflow ()
152
165
166
+ def getNode (self , y , x ):
167
+ return Node (self .nodeids [y , x ], y , x )
168
+
153
169
154
170
class Binseg :
155
171
def __init__ (self , img , unaries ):
@@ -158,41 +174,70 @@ def __init__(self, img, unaries):
158
174
159
175
self .nodegrid = Nodegrid (img .shape [0 ], img .shape [1 ])
160
176
161
- self .l = 0.005
162
- self .w = 100
177
+ self .l = 0.0005
178
+ self .w = 10
163
179
164
- def edge (self , nodeid_i , nodeid_j , graph ):
180
+ def edge (self , node_i , node_j , graph ):
165
181
"""
166
182
Callback for pairwise energy.
167
183
"""
168
- pass
184
+ i = [node_i .y , node_i .x ]
185
+ j = [node_j .y , node_j .x ]
186
+
187
+ # Pixel values
188
+ xi = self .img [i [0 ], i [1 ]]
189
+ xj = self .img [j [0 ], j [1 ]]
190
+
191
+ A = self .pairwiseenergy (0 , 0 , xi , xj )
192
+ B = self .pairwiseenergy (0 , 1 , xi , xj )
193
+ C = self .pairwiseenergy (1 , 0 , xi , xj )
194
+ D = self .pairwiseenergy (1 , 1 , xi , xj )
195
+
196
+ #energy = self.pairwiseenergy(self.unaries[i[0], i[1], 2],
197
+ # self.unaries[j[0], j[1], 2],
198
+ # xi, xj)
199
+
200
+ # print(A, B, C, D)
201
+
202
+ graph .add_edge (node_i .nodeid , node_j .nodeid , B + C - A - D , 0.0 )
169
203
170
- def node_assign (self , nodeid_i , y , x , graph ):
204
+ graph .add_tedge (node_i .nodeid , C , A )
205
+ graph .add_tedge (node_j .nodeid , D , C )
206
+
207
+ def node_assign (self , node_i , graph ):
171
208
"""
172
209
Callback for assigning unary energy.
173
210
"""
174
- graph .add_tedge (nodeid_i , self .unaries [y , x , 1 ], self .unaries [y , x , 0 ])
211
+ graph .add_tedge (node_i .nodeid ,
212
+ self .unaries [node_i .y , node_i .x , 1 ],
213
+ self .unaries [node_i .y , node_i .x , 0 ])
175
214
176
- def node_segment (self , nodeid_i , y , x , graph ):
215
+ def node_segment (self , node_i , graph ):
177
216
"""
178
217
Callback for segmentation.
179
218
"""
180
- if graph .get_segment (nodeid_i ) == 0 :
181
- self .img [y , x ] = np .array ([0 , 0 , 0 ])
219
+ if graph .get_segment (node_i . nodeid ) == 0 :
220
+ self .img [node_i . y , node_i . x ] = np .array ([0 , 0 , 0 ])
182
221
else :
183
- self .img [y , x ] = np .array ([255 , 255 , 0 ])
184
-
185
- def pairwiseenergy (y1 , x1 , y2 , x2 ):
186
- pass
187
- # if unaries[y1, x1, 2] != unaries[y2, x2, 2]:
188
- # delta = 1
189
- # else:
190
- # delta = 0
191
- #
192
- # # Not same label
193
- # energy = w * np.exp(-l * np.power(np.linalg.norm(img[y1, x1] - img[y2, x2], ord=2), 2)) * delta
194
- # # a = (np.linalg.norm(img[y1, x1] - img[y2, x2], ord=2))
195
- # return energy
222
+ self .img [node_i .y , node_i .x ] = np .array ([255 , 255 , 0 ])
223
+
224
+ def pairwiseenergy (self , y1 , y2 , x1 , x2 ):
225
+ """
226
+ Returns pairwise energy between node i and node j using the Potts model.
227
+
228
+ :param y1: Label of i node.
229
+ :param y2: Label of j node.
230
+ :param x1: Pixel value at node i.
231
+ :param x2: Pixel value at node j.
232
+ :return: Pairwise energy.
233
+ """
234
+ if y1 == y2 :
235
+ return 0.0
236
+
237
+ # Not same label
238
+ # np.sum(np.power(x1 - x2, 2), 0)
239
+ energy = self .w * np .exp (- self .l * np .power (np .linalg .norm (x1 - x2 , 2 ), 2 ))
240
+ return energy
196
241
197
242
def segment (self ):
198
243
self .nodegrid .loop (self .edge , self .node_assign )
0 commit comments