def align_rotations(images): """Align the rotations of a set of images by trying rotations up to 10 degrees clockwise and counterclockwise.""" # Rotate the images to be all aligned. # We take the first image as the base, and then search in the -10 to +10 degrees for the rotation # # We take the rotation angle for which the inner square of the images is best aligned image_shape = images[0].size aligned_images = [] aligned_images.append(images[0]) rotation_base_img = images[0] rotation_crop_x1 = int(image_shape[0] * (3/8.0)) rotation_crop_x2 = image_shape[0] - rotation_crop_x1 rotation_crop_y1 = 0 # image_shape[1] / (3/8.0) rotation_crop_y2 = image_shape[1] - rotation_crop_y1 rotation_crop_box = (rotation_crop_x1, rotation_crop_y1, rotation_crop_x2, rotation_crop_y2) rotation_test_angles = np.hstack([np.arange(0,3,0.25), np.arange(3.5,5,0.5),np.arange(5,10,1)]) rotation_test_angles = np.hstack([0 - rotation_test_angles, rotation_test_angles]) rotation_base = as_ary(rotation_base_img.crop(rotation_crop_box)) for i, img in enumerate(images[1:]): min_diff = np.Inf min_diff_angle = np.nan best_rotated_image = None # find the angle a for which the difference between the original and the rotated image is minimized for a in rotation_test_angles: rotated_img = img.rotate(a, expand=0) # expand=0 to keep the size the same rotated_img_ary = as_ary(rotated_img.crop(rotation_crop_box)) # only compare cropped versions of the images. Restricting to a vertical bar diff = np.square(rotation_base - rotated_img_ary) summed_diff = np.mean(diff) # print "Trying angle %f with diff %f" % (a, summed_diff) if summed_diff < min_diff: min_diff = summed_diff min_diff_angle = a best_rotated_image = rotated_img if best_rotated_image != None: # should always hold aligned_images.append(best_rotated_image) return aligned_images
# pixels = np.arange(image_ary.shape[0] * image_ary.shape[1]) * 3 # image = image_ary.flatten() # img = np.amax(np.vstack([image[pixels], image[pixels + 1], image[pixels + 2]]),0) # img = to_img(img, image_ary.shape[0:2]) images.append(img) image_names.append(filename) print "Aligning rotations" aligned_images = align_rotations(images) print "Cropping" cropped_images = [crop_to_wafer(img) for img in aligned_images] # Convert it all to one large array: image_arr = np.vstack([as_ary(img).flatten() for img in cropped_images]) image_shape = as_ary(cropped_images[0]).shape print "Computing mean and variance" # Compute mean and variance of the batch mean = np.mean(image_arr, axis=0) std = np.std(image_arr,axis=0) threshold = 2 # rescale to [0.0, 255] def rescale(dat): mn = np.amin(dat) mx = np.amax(dat) return ((dat - mn) / (mx - mn)) * 512