Skip to content

Instantly share code, notes, and snippets.

@ashaegupta
Created November 14, 2011 01:16
Show Gist options
  • Select an option

  • Save ashaegupta/1363015 to your computer and use it in GitHub Desktop.

Select an option

Save ashaegupta/1363015 to your computer and use it in GitHub Desktop.
unshredded Revised
from PIL import Image
PIXEL_DIFF_CONSTANT = 2
IMAGE_HEIGHT = 359
IMAGE_WIDTH = 640
SHRED_WIDTH = 32
PIXEL_IN_COL_TO_SAMPLE = [2,29,40,210,123,122,111,123,190,304] # Automate
NUMBER_OF_COLUMNS = IMAGE_WIDTH/SHRED_WIDTH
FILE = "TokyoPanoramaShredded.png"
# Unshred a shredded image
def unshred():
image = Image.open(FILE)
sections = sourceToSections(image)
ordered_shreds = getOrderedShreds(sections)
unshredded = orderedShredsToUnShredded(ordered_shreds, image)
unshredded.save('unshredded.png', 'PNG')
# Class to keep track of unshredded images, right_most_pix_col and left_most_pix_col
class Section(object):
def __init__(self):
ordered_shreds = []
right_most_pixel_col = []
left_most_pixel_col = []
# Creates a list of section objects from the source image
def sourceToSections(image):
sections = []
for i in range(0, NUMBER_OF_COLUMNS):
section = Section()
section.ordered_shreds = [i]
x = i*SHRED_WIDTH
shred = image.crop((x, 0, x+SHRED_WIDTH-1, IMAGE_HEIGHT))
section.right_most_pixel_col = getPixelCol(0, shred)
section.left_most_pixel_col = getPixelCol(SHRED_WIDTH-1, shred)
sections.append(section)
return sections
# Get a column of pixel
def getPixelCol(col, shred):
data = shred.getdata()
width,height = shred.size
pixel_col = []
for i in PIXEL_IN_COL_TO_SAMPLE:
pixel = data[col*width+i]
pixel_col.append(pixel)
return pixel_col
# Return an image from an ordered list
def orderedShredstoUnshredded(ordered_shreds, image):
unshredded = Image("RGBA", (IMAGE_WIDTH, IMAGE_HEIGHT))
curr_section = 0
for i in ordered_shreds:
x = i*SHRED_WIDTH
strip = image.crop((x, 0, x+SHRED_WIDTH-1, IMAGE_HEIGHT))
unshredded.paste(strip, (0,curr_section*SHRED_WIDTH))
curr_section += 1
return unshredded
# Returns a list of ordered image columns from a list of sections
def getOrderedShreds(sections):
while(len(sections)>1):
sections = mergeSections(sections)
ordered = sections.pop().ordered_shreds
return ordered
# Returns a list of sections that are merged as much as possible in one pass
def mergeSections(sections):
merged_list = sections.pop(0)
for section in sections:
merged_list = addSection(section, merged_list)
return merged_list
# Adds a section into the appropr iate part of a list or append to end if no match
# Note: could improve to deal with a simultaneous successful right and left match
# currently only handles one match for a given pass through the list
def addSection(section_to_add, merged_list):
has_match = False
new_merged_list = []
for section in merged_list:
match_type = isSectionMatch(section, section_to_add)
if(match_type and not has_match):
section = mergeSections(section, section_to_add, match_type)
has_match = True
new_merged_list.append(section)
if not (has_match):
new_merged_list.append(section_to_add)
return new_merged_list
# Merge an item on the left or right side of a section and return the adjusted section
def mergeSections(section, item, match_type):
if(match_type==1):
section.ordered_shreds = section.ordered_shreds + item.ordered_shreds
section.right_most_pixel_col = item.right_most_pixel_col
if(match_type==-1):
section.ordered_shreds = item.ordered_shreds + section.ordered_shreds
section.left_most_pixel_col = item.left_most_pixel_col
return section
# Determine if two sections match and return if right or left match
def isSectionMatch(section_1, section_2):
if isColumnMatch(section_1.right_most_pixel_col, section_2.left_most_pixel_col):
return 1
if isColumnMatch(section_1.left_most_pixel_col, section_2.right_most_pixel_col):
return -1
else:
return 0
# Determine if two columns match returns true iff all pixels meet match criteria
def isColumnMatch(col_1, col_2):
match = True
for i in PIXEL_IN_COL_TO_SAMPLE:
match = (isPixelMatch(col_1[i], col_2[i]) & match)
return match
# Determine if two pixels match
def isPixelMatch(pixel_1, pixel_2):
if ((abs(pixel_1[0] - pixel_2[0]) < PIXEL_DIFF_CONSTANT)
and (abs(pixel_1[1] - pixel_2[1]) < PIXEL_DIFF_CONSTANT)
and (abs(pixel_1[2] - pixel_2[2]) < PIXEL_DIFF_CONSTANT)
and (abs(pixel_1[3] - pixel_2[3]) < PIXEL_DIFF_CONSTANT)):
return true
else:
return false
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment