Created
November 14, 2011 01:16
-
-
Save ashaegupta/1363015 to your computer and use it in GitHub Desktop.
unshredded Revised
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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