Skip to content

Commit 1580a86

Browse files
committed
refactor: improve code readability by passing closure variables as parameters
1 parent 12a54f9 commit 1580a86

1 file changed

Lines changed: 21 additions & 15 deletions

File tree

jigsaw_puzzle_solver/solver/assembler.py

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -117,64 +117,70 @@ def assemble(self):
117117
None
118118
"""
119119

120-
def _best_fit_piece_at(y, x):
120+
def _best_fit_piece_at(y, x, unused_ids, blueprint):
121121
"""
122122
Find the puzzle piece that can be most naturally stitched at the given position.
123123
124124
Args:
125125
y: int, the row position.
126126
x: int, the column position.
127+
unused_ids: list of int, remaining puzzle piece IDs to consider.
128+
blueprint: PuzzleBlock object, current state of assembled pieces.
127129
128130
Returns:
129131
The PuzzlePiece object that is the best fit.
130132
"""
131-
nonlocal unused_ids
132133
best_candidate = PuzzlePiece()
133134
for img_id in unused_ids: # for all remaining images
134-
for adj in self.blueprint.get_active_neighbors(y, x): # for all adjacent images
135+
for adj in blueprint.get_active_neighbors(y, x): # for all adjacent images
135136
for k in range(self.orientation_cnt * adj.dir, # for all transformations
136137
self.orientation_cnt * adj.dir + self.orientation_cnt):
137138
score = self.sim_matrix[adj.img_id][img_id][self.idx_map(adj.orientation, k)]
138139
if best_candidate.score < score or not best_candidate.is_valid():
139140
best_candidate.set(img_id, k % self.orientation_cnt, score, y, x, adj.dir)
140141
return best_candidate
141142

142-
def _dequeue_and_merge():
143+
def _dequeue_and_merge(p_queue, unused_ids, blueprint):
143144
"""
144145
Dequeue the puzzle piece with the highest score from the priority queue
145146
and merge it into the ConstructionBlueprint object.
146147
Then remove all duplicate puzzle pieces from the priority queue.
147148
149+
Args:
150+
p_queue: LinkedHashmapPriorityQueue object, queue of pieces to be merged.
151+
unused_ids: list of int, remaining puzzle piece IDs (will be modified).
152+
blueprint: PuzzleBlock object, current state of assembled pieces.
153+
148154
Returns:
149155
The PuzzlePiece object that was dequeued and merged.
150156
"""
151-
nonlocal p_queue, unused_ids
152157
piece, duplicates = p_queue.dequeue_and_remove_duplicate_ids()
153-
self.blueprint.activate_position(piece)
158+
blueprint.activate_position(piece)
154159
unused_ids.remove(piece.img_id)
155160
print("image merged: ", piece.tostring(), "\t",
156161
len(self.raw_imgs) - len(unused_ids), "/", len(self.raw_imgs), flush=True)
157162
self.merge_history.append(piece)
158163
# print("current-blueprint:\n", blueprint.data)
159164
return piece, duplicates
160165

161-
def _enqueue_all_frontiers(frontier_pieces_list):
166+
def _enqueue_all_frontiers(frontier_pieces_list, p_queue, unused_ids, blueprint):
162167
"""
163168
For all next possible puzzle piece placement positions,
164169
find the best fit piece at each position and append them puzzle pieces to the priority queue.
165170
166171
Args:
167-
frontier_pieces_list:
168-
List of PuzzlePiece objects representing the positions of the puzzle pieces on the
172+
frontier_pieces_list: List of PuzzlePiece objects representing the positions of the puzzle pieces on the
169173
frontier of the ConstructionBlueprint.
174+
p_queue: LinkedHashmapPriorityQueue object, queue of pieces to be merged.
175+
unused_ids: list of int, remaining puzzle piece IDs to consider.
176+
blueprint: PuzzleBlock object, current state of assembled pieces.
170177
171178
Returns:
172179
None
173180
"""
174-
nonlocal p_queue
175181
for frontier in frontier_pieces_list:
176-
if self.blueprint.validate_position(*frontier.pos()):
177-
pc = _best_fit_piece_at(*frontier.pos())
182+
if blueprint.validate_position(*frontier.pos()):
183+
pc = _best_fit_piece_at(*frontier.pos(), unused_ids, blueprint)
178184
if pc.is_valid():
179185
p_queue.enqueue(pc.img_id, pc)
180186

@@ -197,9 +203,10 @@ def _enqueue_all_frontiers(frontier_pieces_list):
197203
p_queue.dequeue()
198204
continue
199205
# dequeue puzzle piece from the priority queue, and merge it towards the final image form.
200-
piece, duplicates = _dequeue_and_merge()
206+
piece, duplicates = _dequeue_and_merge(p_queue, unused_ids, self.blueprint)
201207
# add the best fit puzzle pieces at all frontier positions to the priority queue
202-
_enqueue_all_frontiers(self.blueprint.get_inactive_neighbors(*piece.pos()) + duplicates)
208+
_enqueue_all_frontiers(self.blueprint.get_inactive_neighbors(*piece.pos()) + duplicates,
209+
p_queue, unused_ids, self.blueprint)
203210
print("MST assembly algorithm:", time.time() - s_time, "seconds")
204211

205212
def save_assembled_image(self, filepath):
@@ -318,7 +325,6 @@ def _compute_elementwise_similarity(x):
318325
"""
319326
Compute similarity between two images for a specific combination of orientations and stitching directions.
320327
"""
321-
global RAW_IMGS_NORM, ORIENTATION_CNT
322328
i, j, k = x[0][0], x[0][1], x[0][2]
323329
# only compute for the upper triangular region.
324330
if i > j:

0 commit comments

Comments
 (0)