Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code review! #1

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
Open
42 changes: 21 additions & 21 deletions ResizeDemo.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,42 +18,42 @@
sc = SeamCarverLib.SeamCarver(pic)

print "print vertical seam 1"
print sc.width(), sc.height()
print sc._width, sc._height
#SeamCarverUtilities.printVerticalSeamEnergy(sc)
SeamCarverUtilities.printVerticalSeam(sc)
SeamCarverUtilities.printSeam(sc, direction="vertical")
#SeamCarverUtilities.distToArray(sc)

print "remove vertical seam"
s = sc.findVerticalSeam()
s = sc.findSeam(direction="vertical")
sc.removeVerticalSeam(s)
print sc.width(), sc.height()
print sc._width, sc._height
print "find vertical seam"
SeamCarverUtilities.printVerticalSeam(sc)
SeamCarverUtilities.printSeam(sc, direction="vertical")

print "print horizontal seam"
SeamCarverUtilities.printHorizontalSeam(sc)
SeamCarverUtilities.printSeam(sc, direction="horizontal")
#SeamCarverUtilities.distToArray(sc)
#SeamCarverUtilities.printHorizontalSeamEnergy(sc)

print "remove horizontal seam"
s = sc.findHorizontalSeam()
s = sc.findSeam(direction="horizontal")
sc.removeHorizontalSeam(s)
print sc.width(), sc.height()
print sc._width, sc._height
#SeamCarverUtilities.printHorizontalSeamEnergy(sc)
print "find horizontal seam"
SeamCarverUtilities.printHorizontalSeam(sc)
SeamCarverUtilities.printSeam(sc, direction="horizontal")
#SeamCarverUtilities.distToArray(sc)


# s = sc.findVerticalSeam()
# sc.removeVerticalSeam(s)

# # print "print vertical seam 2"
# print sc.width(), sc.height()
# print sc._width, sc._height
# SeamCarverUtilities.printVerticalSeam(sc)
# #SeamCarverUtilities.printVerticalSeamEnergy(sc)
# # s = sc.findVerticalSeam()
# # for i in range(sc.height()):
# # for i in range(sc._height):
# # print s[i]
# # # print sc._edgeTo
# # # print sc._distTo
Expand All @@ -62,42 +62,42 @@

# s = sc.findVerticalSeam()
# sc.removeVerticalSeam(s)
# print sc.width(), sc.height()
# print sc._width, sc._height

# # print "print vertical seam 3"
# # print sc.width(), sc.height()
# # print sc._width, sc._height
# SeamCarverUtilities.printVerticalSeam(sc)
# SeamCarverUtilities.distToArray(sc)
# #SeamCarverUtilities.printVerticalSeamEnergy(sc)
# # s = sc.findVerticalSeam()
# # for i in range(sc.height()):
# # for i in range(sc._height):
# # print s[i]

# s = sc.findVerticalSeam()
# sc.removeVerticalSeam(s)
# print sc.width(), sc.height()
# print sc._width, sc._height

# # print "print vertical seam 4"
# # print sc.width(), sc.height()
# # print sc._width, sc._height
# SeamCarverUtilities.printVerticalSeam(sc)
#SeamCarverUtilities.printVerticalSeamEnergy(sc)
# s = sc.findVerticalSeam()
# for i in range(sc.height()):
# for i in range(sc._height):
# print s[i]

# print "print vertical seam 2"
# # print sc._edgeTo
# # print sc._distTo
# s = sc.findVerticalSeam()
# sc.removeVerticalSeam(s)
# print sc.height(), sc.width()
# print sc._height, sc._width
#SeamCarverUtilities.printVerticalSeam(sc)
# print

# print "print vertical seam 3"
# s = sc.findVerticalSeam()
# sc.removeVerticalSeam(s)
# print sc.height(), sc.width()
# print sc._height, sc._width
# # print sc._edgeTo
# # print sc._distTo
# #pdb.set_trace()
Expand All @@ -107,15 +107,15 @@
# print "remove vertical seam 4"
# s = sc.findVerticalSeam()
# sc.removeVerticalSeam(s)
# print sc.height(), sc.width()
# print sc._height, sc._width
# # print sc._edgeTo
# # print sc._distTo
# SeamCarverUtilities.printVerticalSeam(sc)

# print "remove vertical seam 5"
# s = sc.findVerticalSeam()
# sc.removeVerticalSeam(s)
# print sc.height(), sc.width()
# print sc._height, sc._width
# SeamCarverUtilities.printVerticalSeam(sc)


Expand Down
159 changes: 69 additions & 90 deletions SeamCarverLib.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import pdb

class SeamCarver(object):
"removes seams from an image"
"""removes seams from an image"""
def __init__(self, picture):
self._img = picture.imageArray
self._height = picture.num_rows
Expand All @@ -25,24 +25,21 @@ def __init__(self, picture):
self._edgeTo = []
self._distTo = []


def width(self):
return self._width

def height(self):
return self._height

def energy(self, col, row):
"return energy of pixel in (col, row)"
"""return energy of pixel in (col, row)"""
if self._isValid(col, row):
return self._energy[self._toLinear(col, row)]
else:
print "invalid coordinates to energy: %s %s" % (col, row)

def findVerticalSeam(self, transposed=False):
"return vertical seam in image"
def findSeam(self, direction):
"""return vertical seam in image"""
# vertical seam = sequence of cols; seam[0] is col of row 0
# row-indexed seam
seam = [-1 for _ in range(self._height)]
self._buildGraph(transposed)
# - row-indexed seam
# horizontal seam = sequence of rows; seam[0] is row of col 0
# - col-indexed seam
seam = [-1] * self._height
self._buildGraph(direction)
row = self._height - 1
v = self._edgeTo[self._sink]
while (v != self._source):
Expand All @@ -53,21 +50,8 @@ def findVerticalSeam(self, transposed=False):
#self._distTo = []
return seam

def findHorizontalSeam(self, transposed=True):
"return horizontal seam in image"
# tranpose dimensions
self._exchDims()

# horizontal seam = sequence of rows; seam[0] is row of col 0
# col-indexed seam
seam = self.findVerticalSeam(transposed)
self._exchDims()
#self._edgeTo = []
#self._distTo = []
return seam

def _shiftImgUp(self, (col, row)):
"remove horizontal seam in img and energy array by shifting up each col"
"""remove horizontal seam in img and energy array by shifting up each col"""
for r in range(row, self._height - 1):
i = self._width * r + col
rchan_index = i*3
Expand All @@ -77,7 +61,7 @@ def _shiftImgUp(self, (col, row)):
self._energy[i] = self._energy[i + self._width]

def _removeSeam(self, seam):
"remove seam of pixels from image"
"""remove seam of pixels from image"""
# remove horizontal seam
if(len(seam)) != self._width or self._width < 2:
raise ValueError
Expand All @@ -91,7 +75,7 @@ def _removeSeam(self, seam):


def removeVerticalSeam(self, seam):
"remove vertical seam of pixels from image"
"""remove vertical seam of pixels from image"""
if (len(seam) != self._height or self._height == 0 or self._width == 2):
raise ValueError
indexes_to_remove = map(lambda (r, col): self._width * r + col, enumerate(seam))
Expand Down Expand Up @@ -128,7 +112,7 @@ def removeVerticalSeam(self, seam):
self._sink = self._source + 1

def removeHorizontalSeam(self, seam):
"remove horizontal seam of pixels"
"""remove horizontal seam of pixels"""
self._removeSeam(seam)

# update energy
Expand All @@ -147,13 +131,13 @@ def removeHorizontalSeam(self, seam):


def _onEdge(self, col, row):
"True if pixel is on left, top, or right edge"
"""True if pixel is on left, top, or right edge"""
return col == 0 or col == self._width - 1 or row == 0

def _updateEnergy(self, R_chan, resized_width):
'''re-calculate energy values for pixels on either side of seam
"""re-calculate energy values for pixels on either side of seam

R_chan is a list of R channels'''
R_chan is a list of R channels"""
for R in R_chan:
# index = index of seam pixel wrt original image
index = R / self._num_channels
Expand Down Expand Up @@ -199,9 +183,9 @@ def _updateEnergy(self, R_chan, resized_width):
self._energyGrad(resized_index - 1, resized_width)

def _energyGrad(self, index, width):
'''Calculate energy of pixel in resized image. Update self._energy
"""Calculate energy of pixel in resized image. Update self._energy

uses resized_index and resized_width'''
uses resized_index and resized_width"""

left = (index - 1) * self._num_channels
right = (index + 1) * self._num_channels
Expand Down Expand Up @@ -230,19 +214,13 @@ def _energyGrad(self, index, width):
def _diff_squared(self, x, y):
return (x - y)**2

def _exchDims(self):
"exchange self._width and self._height"
swap = self._width
self._width = self._height
self._height = swap

def _toLinear(self, col, row):
"converts pixel from (col, row) to single index"
"""converts pixel from (col, row) to single index"""
if self._isValid(col, row):
return row * self._width + col

def _toGrid(self, num):
"converts pixel from single index to (col, row)"
"""converts pixel from single index to (col, row)"""
if self._isValid(num):
row = num / self._width
col = num % self._width
Expand All @@ -260,8 +238,8 @@ def _isValid(self, col, row=None):
else:
return True

def _buildGraph(self, transposed):
"pixels are nodes; edges define precedence constraints in a seam"
def _buildGraph(self, direction):
"""pixels are nodes; edges define precedence constraints in a seam"""
# graph data structures
self._edgeTo = [_SENTINEL for _ in range(self._num_pixels + 2)] # add 2 for source, sink pixels
self._distTo = [_INF for _ in range(self._num_pixels + 2)]
Expand All @@ -276,59 +254,60 @@ def _buildGraph(self, transposed):
# for each vertex (pixel), calculate edgeTo[], distTo[]
# start at row 1
for v in range(self._width, self._num_pixels):
if (v % self._width == 0):
# pixel is on left edge
self._edgeTodistTo(v, transposed, edgeL=True)
elif (v % self._width == self._width - 1):
# pixel is on right edge
self._edgeTodistTo(v, transposed, edgeR=True)
else:
self._edgeTodistTo(v, transposed)
edges = []
if v % self._width == 0:
edges.append('left')
if v % self._width == self._width - 1:
edges.append("right")
if v / self._width == 0:
edges.append("top")
if v / self._width == self._height - 1:
edges.append("bottom")

if direction == "vertical" and "top" in edges:
continue
if direction == "horizontal" and "left" in edges:
continue

self._edgeTodistTo(v, direction, edges)

# edgeTo[sink] is vertex in last row with min energy
index, min_energy = min(enumerate(self._distTo[self._num_pixels - self._width:self._num_pixels]), key=lambda (x, y): y)
self._distTo[self._sink] = min_energy
self._edgeTo[self._sink] = (self._height - 1) * self._width + index



def _edgeTodistTo(self, v, transposed, edgeL=False, edgeR=False):
def _edgeTodistTo(self, pixel, direction, edges):
# returns pixel connected to v with min energy
if edgeL:
# left edge
vC = v - self._width
vRD = v - self._width + 1
vLU = vC
elif edgeR:
# right edge
vLU = v - self._width - 1
vC = v - self._width
vRD = vC
else:
# pixels connect to v
vLU = v - self._width - 1
vC = v - self._width
vRD = v - self._width + 1

# energy of pixels connected to v
if transposed:
(colU, rowU) = self._toGrid(vLU)
(colC, rowC) = self._toGrid(vC)
(colD, rowD) = self._toGrid(vRD)
# read energy
eLU = self._energy[self._height * colU + rowU]
eC = self._energy[self._height * colC + rowC]
eRD = self._energy[self._height * colD + rowD]
else:
# read energy directly from energy array
eLU = self._energy[vLU]
eC = self._energy[vC]
eRD = self._energy[vRD]
#print (eLU, vLU), (eC, vC), (eRD, vRD)

if direction == "vertical":
ancestor_one = pixel - self._width - 1
ancestor_two = pixel - self._width
ancestor_three = pixel - self._width + 1
if 'left' in edges:
ancestor_one = ancestor_two
elif 'right' in edges:
ancestor_three = ancestor_two

else: #horizontal
ancestor_one = pixel + self._width - 1
ancestor_two = pixel - 1
ancestor_three = pixel - self._width - 1
if 'top' in edges:
ancestor_three = ancestor_two
elif 'bottom' in edges:
ancestor_one = ancestor_two

eLU = self._energy[ancestor_one]
eC = self._energy[ancestor_two]
eRD = self._energy[ancestor_three]
#print (eLU, ancestor_one), (eC, ancestor_two), (eRD, ancestor_three)
# find min distance and its associated vertex
dist, from_vertex = min((self._distTo[vLU] + eLU, vLU), (self._distTo[vC] + eC, vC), (self._distTo[vRD] + eRD, vRD))
#e, vertex = min([(eC, vC), (eLU, vLU), (eRD, vRD)])
self._edgeTo[v] = from_vertex
self._distTo[v] = dist
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))
#e, vertex = min([(eC, ancestor_two), (eLU, ancestor_one), (eRD, ancestor_three)])
self._edgeTo[pixel] = from_vertex
self._distTo[pixel] = dist



Expand Down
Loading