def test_build_graph(self): test_patches = get_test_patches() show_image(assemble_patches(test_patches, 2)) matrix = build_graph(test_patches) self.assertTupleEqual(matrix.shape, (4, 4, 16), "matrix wrong shape") # show_image(combine_patches(test_patches[0], test_patches[1], 0)) self.assertGreater( matrix[0, 1, 0], matrix[0, 1, 2], "black with rotated red should score better than black with just red" ) self.assertGreater( matrix[0, 1, 2], matrix[0, 1, 10], "rotated black with rotated red should score better than just black with rotated red" ) self.assertEqual( matrix[0, 1, 2], matrix[1, 0, 2], "black with red should get the same score regardless of which is listed first" ) self.assertLess( matrix[2, 3, 7], matrix[1, 3, 11], "similar shades should have a better score then blatantly different colors" ) # self.assertLess(matrix[2, 3, 13], matrix[3, 2, 0], "identical interesting edges should give a lower score than identical boring edges") self.assertEqual( np.amin(matrix), matrix[2, 3, 13], "identical and interesting edges should give the lowest score")
def compare_images(image1: np.ndarray, image2: np.ndarray): """ takes two rgb images and displays a red/green image of where the two input images have the same pixel values; green pixels mean identical, red pixels mean they differ :param image1: the first image for comparison as a numpy array of shape (m, n, 3) :param image2: the second image for comparison as a numpy array of shape (r, c, 3) :return: None """ red_pixel = np.array([205, 0, 0]) green_pixel = np.array([0, 205, 40]) full_height = max(image1.shape[0], image2.shape[0]) inner_height = min(image1.shape[0], image2.shape[0]) full_width = max(image1.shape[1], image2.shape[1]) inner_width = min(image1.shape[1], image2.shape[1]) to_show = np.empty((full_height, full_width, 3), dtype=int) for i in range(to_show.shape[0]): for j in range(to_show.shape[1]): if i >= inner_height or j >= inner_width: to_show[i, j, :] = red_pixel continue identical = True for c in range(3): if image1[i, j, c] != image2[i, j, c]: identical = False break if identical: to_show[i, j, :] = green_pixel else: to_show[i, j, :] = red_pixel show_image(to_show)
def test_assemble_image(self): original = load_image_from_disk("TestImages/TestPatches.png") test_patches = get_test_patches() # cycle black, red, and dark blue clockwise # rotate black by 180, rotate red by 90 test_patches_shuffled = [ test_patches[2], np.rot90(test_patches[0], 2), np.rot90(test_patches[1], 1), test_patches[3] ] # make the reconstruction matrix reconstruction = np.array([[[1, 2], [2, 3]], [[0, 0], [3, 0]]]) actual = assemble_image(test_patches_shuffled, reconstruction) show_image(original) show_image(assemble_patches(test_patches_shuffled, 2)) show_image(actual) self.assertTrue(np.array_equal(original, actual), "reconstructed image is not the same as the original")
continue identical = True for c in range(3): if image1[i, j, c] != image2[i, j, c]: identical = False break if identical: to_show[i, j, :] = green_pixel else: to_show[i, j, :] = red_pixel show_image(to_show) if __name__ == "__main__": original_image = load_image_from_disk("TestImages/Giraffe.jpg ") show_image(original_image, "original") # ps = original_image.shape[1] // 2 ps = 28 original_patched, dimensions = patch_image(original_image, ps) patch_list, shuffle_dictionary = scramble_image(original_patched, 4) show_image(assemble_patches(patch_list, original_image.shape[1] // ps), "scrambled") # hypothetical_min = 85 + (15.038 * math.log(ps)) # hypothetical_max = 255 - (14.235 * math.log(ps)) print(f"algorithm start time: {datetime.datetime.now()}") reconstruction_matrix = jigsaw_kruskals(patch_list) reconstructed_image = assemble_image_kruskal(patch_list, reconstruction_matrix) # reconstructed_image = jigsaw_kruskals(patch_list) # reconstructed_image = jigsaw_prims(patch_list) print(f"algorithm end time: {datetime.datetime.now()}") if reconstructed_image is not None: show_image(reconstructed_image, "final answer")
#true_classes_names = (pd.DataFrame({"CategoryId": true_classes}) # .merge(categories, on="CategoryId")["CategoryName"].tolist()) true_classes_names = [] for i in true_classes: true_classes_names.append(categories['CategoryName'][i - 1]) #target_classes_names = (pd.DataFrame({"CategoryId": target_classes}) # .merge(categories, on="CategoryId")["CategoryName"].tolist()) target_classes_names = [] for i in target_classes: target_classes_names.append(categories['CategoryName'][i - 1]) print("Here's an example of one of the images in the development set") show_image(images[0]) print(true_classes_names[0].split(',')[0].replace(' ', '_')) #print(categories['CategoryName'][0]) # Saves the image in order for analysis and spit out their correct category for i in range(len(images)): save_image( images[i], i, 'C:/Users/Bowen/Desktop/Project/image-perturbation-defense/NIPS/test/') correct_label = true_classes_names[i].split(',')[0].replace( ' ', '_') # Convert ['giant panda, panda etc....'] to 'giant_panda' with open('true_classes.csv', 'a', newline='') as csvfile: spamwriter = csv.writer(csvfile) spamwriter.writerow([correct_label])
def jigsaw_prims(patches: list) -> np.ndarray: """ takes a list of square patches and uses prim's algorithm to assemble the patches :param patches: a list of numpy arrays representing the scrambled patches of the original image :return: the re-assembled image as a numpy array of shape (x, y, 3) """ n = len(patches) patches_available = list(range(n)) # figure out the patch size patch_size = patches[0].shape[0] # a matrix to store scores already calculated scores_matrix = np.empty((3, 3, n, 4), dtype=float) scores_matrix[:, :, :, :] = INFINITY # a matrix to store which slots have pieces construction_matrix = np.array( [[NO_PIECE, EXPANSION_SPACE, NO_PIECE], [EXPANSION_SPACE, YES_PIECE, EXPANSION_SPACE], [NO_PIECE, EXPANSION_SPACE, NO_PIECE]]) # an array holding the actual pixel values (starts at all black) assembled_image = np.zeros((patch_size * 3, patch_size * 3, 3), dtype=int) # pull the start patch out and place it in the assembled image assembled_image[patch_size:(2 * patch_size), patch_size:(2 * patch_size), :] = patches[0] show_image(assembled_image) patches_available.remove(0) # while the list of remaining patches isn't empty, pull out the next best option and place it while len(patches_available) > 0: # to place the next best option: # for each empty spot adjacent to a placed patch, try putting each unused patch in each possible orientation # for each of those options, give it a score accounting for all of its neighbors # whichever of all the options has the best score is the one that gets placed # ----- # find places where we could put a patch expansion_spaces = find_expansion_spaces(construction_matrix) if len(expansion_spaces) == 0: raise RuntimeError( f"jigsaw_prims could not find any expansion spaces, but there are more patches to place" ) # make sure they all have scores for row, col in expansion_spaces: for patch_index in patches_available: for r in range(4): if scores_matrix[row, col, patch_index, r] == INFINITY: patch_to_place = np.rot90(patches[patch_index], r) # if row == 0 and col == 1 and patch_index == 3 and r == 3: # show_image(patch_to_place) # show_image(assembled_image) # print(construction_matrix) score = prims_placement_score(construction_matrix, assembled_image, patch_to_place, row, col) scores_matrix[row, col, patch_index, r] = score # find the placement of the best score min_scores = np.where(scores_matrix == np.amin(scores_matrix)) min_scores = list( zip(min_scores[0], min_scores[1], min_scores[2], min_scores[3])) # place the best patch for row, col, patch_index, r in min_scores: # make sure we picked a piece that hasn't been used yet if patch_index not in patches_available: continue # shouldn't need this, but just in case patches_available.remove(patch_index) # mark the space as taken; update its neighbors as available for placement construction_matrix[row, col] = YES_PIECE # actually place the patch rotated_patch = np.rot90(patches[patch_index], r) assembled_image[(row * patch_size):((row + 1) * patch_size), (col * patch_size):((col + 1) * patch_size), :] = rotated_patch show_image(assembled_image, str(scores_matrix[row, col, patch_index, r])) # set the place's scores and the patch's scores to infinity to mark them as taken/used scores_matrix[row, col, :, :] = INFINITY scores_matrix[:, :, patch_index, :] = INFINITY # check if we've placed a piece at the edge of the available canvas; expand if we did if row == 0 or row == construction_matrix.shape[0] - 1: new_scores_row = np.empty( (1, scores_matrix.shape[1], scores_matrix.shape[2], scores_matrix.shape[3]), dtype=float) new_scores_row[:, :, :, :] = INFINITY new_construction_row = np.empty( (1, construction_matrix.shape[1]), dtype=int) new_construction_row[:, :] = NO_PIECE new_image_row = np.zeros((patch_size, assembled_image.shape[1], assembled_image.shape[2]), dtype=int) if row == 0: # we placed one on the top row scores_matrix = np.concatenate( (new_scores_row, scores_matrix), axis=0) construction_matrix = np.concatenate( (new_construction_row, construction_matrix), axis=0) assembled_image = np.concatenate( (new_image_row, assembled_image), axis=0) row += 1 else: # we placed one on the bottom row scores_matrix = np.concatenate( (scores_matrix, new_scores_row), axis=0) construction_matrix = np.concatenate( (construction_matrix, new_construction_row), axis=0) assembled_image = np.concatenate( (assembled_image, new_image_row), axis=0) if col == 0 or col == construction_matrix.shape[1] - 1: new_scores_col = np.empty( (scores_matrix.shape[0], 1, scores_matrix.shape[2], scores_matrix.shape[3]), dtype=float) new_scores_col[:, :, :, :] = INFINITY new_construction_col = np.empty( (construction_matrix.shape[0], 1), dtype=int) new_construction_col[:, :] = NO_PIECE new_image_col = np.zeros((assembled_image.shape[0], patch_size, assembled_image.shape[2]), dtype=int) if col == 0: # we placed one on the left column scores_matrix = np.concatenate( (new_scores_col, scores_matrix), axis=1) construction_matrix = np.concatenate( (new_construction_col, construction_matrix), axis=1) assembled_image = np.concatenate( (new_image_col, assembled_image), axis=1) col += 1 else: # we placed one on the bottom row scores_matrix = np.concatenate( (scores_matrix, new_scores_col), axis=1) construction_matrix = np.concatenate( (construction_matrix, new_construction_col), axis=1) assembled_image = np.concatenate( (assembled_image, new_image_col), axis=1) # check and update the neighbors of the newly placed patch # also reset the adjacent places' scores to infinity so they'll be recalculated accounting for the new piece for row_shift in [-1, 1]: if construction_matrix[row + row_shift, col] == NO_PIECE: construction_matrix[row + row_shift, col] = EXPANSION_SPACE if construction_matrix[row + row_shift, col] == EXPANSION_SPACE: scores_matrix[row + row_shift, col, :, :] = INFINITY for col_shift in [-1, 1]: if construction_matrix[row, col + col_shift] == NO_PIECE: construction_matrix[row, col + col_shift] = EXPANSION_SPACE if construction_matrix[row, col + col_shift] == EXPANSION_SPACE: scores_matrix[row, col + col_shift, :, :] = INFINITY break # trim edges h, w, _ = assembled_image.shape assembled_image = assembled_image[patch_size:(h - patch_size), patch_size:(w - patch_size), :] return assembled_image