Skip to content

Commit 4df7f95

Browse files
committed
Don't transpose
Refactors edge and distance calculation to avoid confusing (to me) transposition. This commit isn't quite complete/working, but it gives an idea of the direction I'd suggest going. By the way, it's possible to swap two variables in python in one line: b, a = a, b
1 parent 98419d1 commit 4df7f95

File tree

1 file changed

+45
-49
lines changed

1 file changed

+45
-49
lines changed

SeamCarverLib.py

Lines changed: 45 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,8 @@ def findSeam(self, direction):
3636
# - row-indexed seam
3737
# horizontal seam = sequence of rows; seam[0] is row of col 0
3838
# - col-indexed seam
39-
if direction == "horizontal":
40-
self._exchDims()
4139
seam = [-1] * self._height
42-
self._buildGraph(transposed)
40+
self._buildGraph(direction)
4341
row = self._height - 1
4442
v = self._edgeTo[self._sink]
4543
while (v != self._source):
@@ -48,8 +46,6 @@ def findSeam(self, direction):
4846
row -= 1
4947
#self._edgeTo = []
5048
#self._distTo = []
51-
if direction == "horizontal":
52-
self._exchDims()
5349
return seam
5450

5551
def _shiftImgUp(self, (col, row)):
@@ -216,12 +212,6 @@ def _energyGrad(self, index, width):
216212
def _diff_squared(self, x, y):
217213
return (x - y)**2
218214

219-
def _exchDims(self):
220-
"""exchange self._width and self._height"""
221-
swap = self._width
222-
self._width = self._height
223-
self._height = swap
224-
225215
def _toLinear(self, col, row):
226216
"""converts pixel from (col, row) to single index"""
227217
if self._isValid(col, row):
@@ -246,7 +236,7 @@ def _isValid(self, col, row=None):
246236
else:
247237
return True
248238

249-
def _buildGraph(self, transposed):
239+
def _buildGraph(self, direction):
250240
"""pixels are nodes; edges define precedence constraints in a seam"""
251241
# graph data structures
252242
self._edgeTo = [_SENTINEL for _ in range(self._num_pixels + 2)] # add 2 for source, sink pixels
@@ -262,52 +252,58 @@ def _buildGraph(self, transposed):
262252
# for each vertex (pixel), calculate edgeTo[], distTo[]
263253
# start at row 1
264254
for v in range(self._width, self._num_pixels):
265-
if (v % self._width == 0):
266-
# pixel is on left edge
267-
self._edgeTodistTo(v, transposed, edgeL=True)
268-
elif (v % self._width == self._width - 1):
269-
# pixel is on right edge
270-
self._edgeTodistTo(v, transposed, edgeR=True)
271-
else:
272-
self._edgeTodistTo(v, transposed)
255+
edges = []
256+
if v % self._width == 0:
257+
edges.append('left')
258+
if v % self._width == self._width - 1:
259+
edges.append("right")
260+
if v / self._width == 0:
261+
edges.append("top")
262+
if v / self._width == self._height - 1:
263+
edges.append("bottom")
264+
265+
if direction == "vertical" and "top" in edges:
266+
continue
267+
if direction == "horizontal" and "left" in edges:
268+
continue
269+
270+
self._edgeTodistTo(v, direction, edges)
271+
273272
# edgeTo[sink] is vertex in last row with min energy
274273
index, min_energy = min(enumerate(self._distTo[self._num_pixels - self._width:self._num_pixels]), key=lambda (x, y): y)
275274
self._distTo[self._sink] = min_energy
276275
self._edgeTo[self._sink] = (self._height - 1) * self._width + index
277276

278277

279278

280-
def _edgeTodistTo(self, pixel, transposed, edgeL=False, edgeR=False):
279+
def _edgeTodistTo(self, pixel, direction, edges):
281280
# returns pixel connected to v with min energy
282-
up_pixel = pixel - self._width
283-
right_up_diagonal_pixel = pixel - self._width + 1
284-
left_up_diagonal_pixel = pixel - self._width - 1
285-
286-
if edgeL:
287-
# left edge
288-
left_up_diagonal_pixel = up_pixel
289-
elif edgeR:
290-
# right edge
291-
right_up_diagonal_pixel = up_pixel
292-
293-
# energy of pixels connected to pixel
294-
if transposed:
295-
(colU, rowU) = self._toGrid(left_up_diagonal_pixel)
296-
(colC, rowC) = self._toGrid(up_pixel)
297-
(colD, rowD) = self._toGrid(right_up_diagonal_pixel)
298-
# read energy
299-
eLU = self._energy[self._height * colU + rowU]
300-
eC = self._energy[self._height * colC + rowC]
301-
eRD = self._energy[self._height * colD + rowD]
302-
else:
303-
# read energy directly from energy array
304-
eLU = self._energy[left_up_diagonal_pixel]
305-
eC = self._energy[up_pixel]
306-
eRD = self._energy[right_up_diagonal_pixel]
307-
#print (eLU, left_up_diagonal_pixel), (eC, up_pixel), (eRD, right_up_diagonal_pixel)
281+
282+
if direction == "vertical":
283+
ancestor_one = pixel - self._width - 1
284+
ancestor_two = pixel - self._width
285+
ancestor_three = pixel - self._width + 1
286+
if 'left' in edges:
287+
ancestor_one = ancestor_two
288+
elif 'right' in edges:
289+
ancestor_three = ancestor_two
290+
291+
else: #horizontal
292+
ancestor_one = pixel + self._width - 1
293+
ancestor_two = pixel - 1
294+
ancestor_three = pixel - self._width - 1
295+
if 'top' in edges:
296+
ancestor_three = ancestor_two
297+
elif 'bottom' in edges:
298+
ancestor_one = ancestor_two
299+
300+
eLU = self._energy[ancestor_one]
301+
eC = self._energy[ancestor_two]
302+
eRD = self._energy[ancestor_three]
303+
#print (eLU, ancestor_one), (eC, ancestor_two), (eRD, ancestor_three)
308304
# find min distance and its associated vertex
309-
dist, from_vertex = min((self._distTo[left_up_diagonal_pixel] + eLU, left_up_diagonal_pixel), (self._distTo[up_pixel] + eC, up_pixel), (self._distTo[right_up_diagonal_pixel] + eRD, right_up_diagonal_pixel))
310-
#e, vertex = min([(eC, up_pixel), (eLU, left_up_diagonal_pixel), (eRD, right_up_diagonal_pixel)])
305+
dist, from_vertex = min((self._distTo[ancestor_one] + eLU, ancestor_one), (self._distTo[ancestor_two] + eC, ancestor_two), (self._distTo[ancestor_three] + eRD, ancestor_three))
306+
#e, vertex = min([(eC, ancestor_two), (eLU, ancestor_one), (eRD, ancestor_three)])
311307
self._edgeTo[pixel] = from_vertex
312308
self._distTo[pixel] = dist
313309

0 commit comments

Comments
 (0)