def crop_whole_alphabet(dir="Data/Alphabet/"): """ Crop image of every letter """ for ascii in range(26): ascii += ASCII_A image = image_utils.load_letter_as_image(ascii, dir) image = image_utils.crop_image(image) image_utils.save_letter_as_image(dir, image, chr(ascii))
def OCR(path): """ Read and return the most preferable letter from image """ image = image_utils.load_file(path) image = image_utils.crop_image(image) test_data = image_utils.analyze_image(image) alphabet_data = alphabet_generator.load_reference_proportions() difference = [{'letter': '', 'diff': 0} for letter in range(26)] for reference_letter in alphabet_data: index_letter = ord(reference_letter['letter']) - alphabet_generator.ASCII_A temp_diff = 0 for x in range(image_utils.SPLIT_NUMBER): for y in range(image_utils.SPLIT_NUMBER): # The compare function temp_diff += pow((test_data['subproportions'][x][y] * reference_letter['proportion'] - reference_letter['subproportions'][x][y] * test_data['proportion']), 2) difference[index_letter]['letter'] = reference_letter['letter'] difference[index_letter]['diff'] = temp_diff return sorted(difference, key=lambda letter: letter['diff'])[0]['letter']
def rgb2depth_stream(model, method='cv2', mirror=True, width=640, height=192, gamma=1, crop_mode='middle'): '''Runs depth estimation on live webcam video stream. Adjust brightness (gamma) for viewing purposes only. Anything other than gamma=1 is distorting the numerical depth prediction.''' cam = cv2.VideoCapture(0) while True: start = time.time() ret_val, img = cam.read() if mirror: img = cv2.flip(img, 1) #If img doesn't match output height & width if (img.shape[0] != height) or (img.shape[1] != width): #Crop image img = image_utils.crop_image(img, width, height, mode=crop_mode) img = img.reshape(1, height, width, 3) img = np.divide(img, 255).astype(np.float16) #Predict depth y_est = model.predict(img) y_est = y_est.reshape((height, width)) #Show depth prediction results if method == 'cv2': #Map 2D grayscale to RGB equivalent vis = cv2.cvtColor((y_est * 255 * (1 / gamma)).astype(np.uint8), cv2.COLOR_GRAY2BGR) vis = cv2.cvtColor(vis, cv2.COLOR_BGR2GRAY) #Map BGR to Rainbow vis = cv2.applyColorMap(vis, cv2.COLORMAP_RAINBOW) cv2.imshow('Depth Estimate', vis) elif method == 'heatmap': image_utils.heatmap(y_est, cmap='plasma') else: print('Unknown display method.') #Estimate instantaneous frames per second end = time.time() fps = round(1 / (end - start), 2) print(f'FPS: {fps}') if cv2.waitKey(1) == 27: break # esc to quit cv2.destroyAllWindows()
def tile_old(tile_filename: str, output_filename: str, output_width: int, output_height: int, choice: int = 0, crop: bool = True): """ Deprecated. It will populate the tiles but you have to specify the same choice number for every tile and it doesn't have any smarts about consecutive duplicates or multithreading. :param tile_filename: :param output_filename: :param output_width: :param output_height: :param choice: :param crop: :return: """ df = pd.read_csv(tile_filename) df = df[df['choice'] == choice] column_count = df['col'].max() row_count = df['row'].max() tile_width = int(output_width / column_count) tile_height = int(output_height / row_count) result = Image.new('RGB', (column_count * tile_width, row_count * tile_height)) pbar = tqdm.tqdm(total=row_count * column_count) for r in range(row_count): for c in range(column_count): choice_row = df[(df['row'] == r) & (df['col'] == c)] filename = choice_row['filename'].iloc[0] if crop: resized_child = crop_image(resize_image(Image.open(filename), width=tile_width), width=tile_width, height=tile_height) else: resized_child = resize_image(Image.open(filename), width=tile_width, height=tile_height) result.paste(im=resized_child, box=(c * tile_width, r * tile_height)) pbar.update(1) result.save(output_filename)
def preprocess(l): filename, postfix, output_filename, crop_blank_default_size, pad_size, buckets, downsample_ratio = l postfix_length = len(postfix) try: im1 = image_utils.crop_image(filename, output_filename, crop_blank_default_size) im2 = image_utils.pad_image(im1, output_filename, pad_size, buckets) status = image_utils.downsample_image(im2, output_filename, downsample_ratio) #im1.close() #im2.close() return True except IOError: app.logger.info("IOError in preprocesing") return False
def preprocess(l): filename, postfix, output_filename, crop_blank_default_size, pad_size, buckets, downsample_ratio = l postfix_length = len(postfix) status = image_utils.crop_image(filename, output_filename, crop_blank_default_size) if not status: print('%s is blank, crop a white image of default size!' % filename) status = image_utils.pad_image(output_filename, output_filename, pad_size, buckets) if not status: print( '%s (after cropping and padding) is larger than the largest provided bucket size, left unchanged!' % filename) os.remove(output_filename) return status = image_utils.downsample_image(output_filename, output_filename, downsample_ratio)
def rgb2depth_video(filename, model, out_FPS=10, width=640, height=192, output_filename=r'depth_output.avi', gamma=1, mirror=False, crop_mode='middle'): '''Create depth prediction video from input RGB video. Adjust brightness (gamma) for viewing purposes only. Anything other than gamma=1 is distorting the numerical depth prediction.''' cam = cv2.VideoCapture(filename) # Define the codec and create VideoWriter object. out = cv2.VideoWriter(output_filename,cv2.VideoWriter_fourcc('M','J','P','G'), out_FPS, (int(width),int(height))) while(cam.isOpened()): ret_val, img = cam.read() try: if mirror: img = cv2.flip(img, 1) #If img doesn't match output height & width if (img.shape[0] != height) or (img.shape[1] != width): #Crop image img=image_utils.crop_image(img,width,height,mode=crop_mode) #Predict depth img=img.reshape(1,height,width,3) img=np.divide(img,255).astype(np.float16) #Normalize input y_est=model.predict(img) y_est=y_est.reshape((height,width)) #Map 2D grayscale to RGB equivalent vis = cv2.cvtColor((y_est*255*(1/gamma)).astype(np.uint8),cv2.COLOR_GRAY2BGR) vis = cv2.cvtColor(vis,cv2.COLOR_BGR2GRAY) #Map BGR to Rainbow vis=cv2.applyColorMap(vis,cv2.COLORMAP_RAINBOW) #Write prediction to video out.write(vis) except: break cam.release() cv2.destroyAllWindows()
def pred(dataURL): """ Render prediction result. """ # decode base64 '._-' -> '+/=' dataURL = dataURL.replace('.', '+') dataURL = dataURL.replace('_', '/') dataURL = dataURL.replace('-', '=') # get the base64 string image_b64_str = dataURL # convert string to bytes byte_data = base64.b64decode(image_b64_str) image_data = BytesIO(byte_data) # open Image with PIL img = Image.open(image_data) # save original image as png (for debugging) ts = time.time() #img.save('image' + str(ts) + '.png', 'PNG') # convert image to RGBA img = img.convert("RGBA") # preprocess the image for the model image_cropped = crop_image(img) # crop the image and resize to 28x28 image_normalized = normalize_image(image_cropped) # normalize color after crop # convert image from RGBA to RGB img_rgb = convert_to_rgb(image_normalized) # convert image to numpy image_np = convert_to_np(img_rgb) # apply model and print prediction label, label_num, preds = get_prediction(model, image_np) print("This is a {}".format(label_num)) # save classification results as a diagram view_classify(image_np, preds) # create plotly visualization graphs = [ #plot with probabilities for each class of images { 'data': [ go.Bar( x = preds.ravel().tolist(), y = list(label_dict.values()), orientation = 'h') ], 'layout': { 'title': 'Class Probabilities', 'yaxis': { 'title': "Classes" }, 'xaxis': { 'title': "Probability", } } }] # encode plotly graphs in JSON ids = ["graph-{}".format(i) for i, _ in enumerate(graphs)] graphJSON = json.dumps(graphs, cls=plotly.utils.PlotlyJSONEncoder) # render the hook.html passing prediction resuls return render_template( 'hook.html', result = label_num, # predicted class label ids=ids, # plotly graph ids graphJSON=graphJSON, # json plotly graphs dataURL = dataURL # image to display with result )
im = im.rotate(base_rotation, expand=True) # Resize the image (useful for testing, keep at 1 for final images) im = util.resize_image(im, resize_factor) original_size = im.size im = im.rotate(image_rotation, expand=True) a = np.asarray(im) # get intervals intervals = (interval.threshold_interval(a, np.shape(a), 0.7, 0.91, width=width, func=util.lightness, inverted=True)) intervals = interval.randomly_filter_interval(intervals, 0) ac = a.copy() # Sort the pixels new = sort.sort_pixels(ac, intervals, width=width, sorting_func=util.lightness, reverse=False) im2 = Image.fromarray(new) # Unrotate the image im2 = im2.rotate(-image_rotation, expand=True) # uncrop added blackspace from the initial rotation im2 = util.crop_image(im2, (original_size[1], original_size[0])) im2.show() print('save image? (Y/N)') response = input() if response=='y' or response=='Y': print('name the file (with extension)') response = input() im2.save(response) im2.close()
def __getitem__(self, index): image_name = self.data['image_filenames'][index] label_name = self.data['label_filenames'][index] phase_number = self.data['phase_numbers'][index] has_label = (self.data['label_filenames'][index] is not '') info = {} info['Name'] = image_name info['PhaseNumber'] = phase_number nib_image = nib.load(os.path.join(self.data_root_dir, image_name)) info['PixelResolution'] = nib_image.header['pixdim'][1:4] info['ImageSize'] = nib_image.header['dim'][1:4] info['AffineTransform'] = nib_image.header.get_best_affine() info['Header'] = nib_image.header.copy() whole_image = nib_image.get_data() if has_label: whole_label = nib.load(os.path.join(self.data_root_dir, label_name)).get_data() if np.ndim(whole_image) == 4: whole_image = whole_image[:, :, :, phase_number] if has_label: whole_label = whole_label[:, :, :, phase_number] # # For ACDC # whole_label = 4 - whole_label # whole_label[whole_label == 4] = 0 whole_image_orig = np.copy(whole_image) clip_min = np.percentile(whole_image, 1) clip_max = np.percentile(whole_image, 99) whole_image = np.clip(whole_image, clip_min, clip_max) whole_image = (whole_image - whole_image.min() ) / float(whole_image.max() - whole_image.min()) whole_image = whole_image * 2 - 1 # Make image within -1 and 1 # whole_image = (whole_image - np.mean(whole_image, dtype=np.float32)) / np.std(whole_image, dtype=np.float32) # Pad image into square and resize here # whole_image = image_utils.zero_pad(whole_image) # whole_label = image_utils.zero_pad(whole_label) # # whole_image = image_utils.resize_image(whole_image, [image_size, image_size], interpolation_order=1) # whole_label = image_utils.resize_image(whole_label, [image_size, image_size], interpolation_order=0) * 255 x, y, z = whole_image.shape x_centre, y_centre = int(x / 2), int(y / 2) cropped_image, _, _ = image_utils.crop_image( whole_image, x_centre, y_centre, [self.image_size, self.image_size]) if has_label: cropped_label, _, _ = image_utils.crop_image( whole_label, x_centre, y_centre, [self.image_size, self.image_size]) else: cropped_label = None # Perform data augmentation if self.augment: cropped_image, cropped_label = image_utils.augment_data_2d( cropped_image, cropped_label, preserve_across_slices=False, max_shift=self.shift, max_rotate=self.rotate, max_scale=self.scale, max_intensity=self.intensity) cropped_image = (cropped_image - self.mean) / self.std # !! Put into NCHW format batch_images = np.expand_dims(np.transpose(cropped_image, axes=(2, 0, 1)), axis=1) if has_label: batch_labels = np.expand_dims(np.transpose(cropped_label, axes=(2, 0, 1)), axis=1) if batch_images.shape[0] > self.num_images_limit: slices = sorted( list(np.random.permutation( batch_images.shape[0]))[:self.num_images_limit]) batch_images = batch_images[slices, :, :, :] if has_label: batch_labels = batch_labels[slices, :, :, :] # print("Warning: Number of slices limited to {} to fit GPU".format(num_images_limit)) if has_label: return batch_images, batch_labels, info, whole_image_orig, whole_label else: return batch_images, None, info, whole_image_orig, None
def tile(tile_filename: str, output_filename: str, output_width: int, output_height: int, aspect_ratio: float, processes: int, crop: bool = True): """ Do the tiling. This leverages multiprocessing for loading the tiles from disk, but keep in mind that as of now, all of these resized candidate images are going to sit in memory and then be pasted into the final result image. This is fine for every use case I've run, but you could see why it might blow up in memory if you were trying to do this for a billboard-size image. Consider refactoring this when we start working on billboards. :param tile_filename: :param output_filename: :param output_width: :param output_height: :param aspect_ratio: :param choice: :param crop: :return: """ df = pd.read_csv(tile_filename) column_count = df['col'].max() + 1 row_count = df['row'].max() + 1 tile_width = math.ceil(float(output_width) / column_count) tile_height = math.ceil(float(output_height) / row_count) result = Image.new('RGB', (column_count * tile_width, row_count * tile_height)) tuples = [] selected_filenames = [] for r in range(row_count): row_filenames = [] for c in range(column_count): # Find neighbors neighbors = [] if r > 0: if c > 0: neighbors.append(selected_filenames[r - 1][c - 1]) neighbors.append(selected_filenames[r - 1][c]) if c < column_count - 1: neighbors.append(selected_filenames[r - 1][c + 1]) if c > 0: neighbors.append(row_filenames[c - 1]) choice_rows = df[(df['row'] == r) & (df['col'] == c) & ( ~df['filename'].isin(neighbors))].sort_values('choice') filename = choice_rows['filename'].iloc[0] tuples.append({'filename': filename, 'c': c, 'r': r}) row_filenames.append(filename) selected_filenames.append(row_filenames) with multiprocessing.Pool(processes=processes) as pool: result_tuple_list = list( tqdm.tqdm(pool.imap( partial(load_tile, crop=crop, aspect_ratio=aspect_ratio, tile_width=tile_width, tile_height=tile_height), tuples), total=len(tuples), desc='Loading tiles into memory.')) # input_tile_path, ext = os.path.splitext(tile_filename) # save_final_choices(selected_filenames, f'{input_tile_path}_final{ext}') for result_tuple in tqdm.tqdm(result_tuple_list, desc='Creating actual collage image'): result.paste(im=result_tuple[0], box=result_tuple[1]) # If the image wasn't perfectly divisible by the tile dimensions, we'll spill over outside our desired final image dimensions. Save a copy of the uncropped then crop it and save a final version too. prefix, ext = os.path.splitext(output_filename) result.save(f'{prefix}_uncropped{ext}') crop_image(result, output_width, output_height, center=False).save(output_filename)
def get_random_batch(filename_list, batch_size, image_size=192, data_augmentation=False, shift=0.0, rotate=0.0, scale=0.0, intensity=0.0, flip=False): # Randomly select batch_size images from filename_list n_file = len(filename_list) n_selected = 0 images = [] labels = [] while n_selected < batch_size: rand_index = random.randrange(n_file) image_name, label_name = filename_list[rand_index] if os.path.exists(image_name) and os.path.exists(label_name): print(' Select {0} {1}'.format(image_name, label_name)) # Read image and label image = nib.load(image_name).get_data() label = nib.load(label_name).get_data() # Handle exceptions if image.shape != label.shape: print('Error: mismatched size, image.shape = {0}, ' 'label.shape = {1}'.format(image.shape, label.shape)) print('Skip {0}, {1}'.format(image_name, label_name)) continue if image.max() < 1e-6: print('Error: blank image, image.max = {0}'.format(image.max())) print('Skip {0} {1}'.format(image_name, label_name)) continue # Normalise the image size X, Y, Z = image.shape cx, cy = int(X / 2), int(Y / 2) image = crop_image(image, cx, cy, image_size) label = crop_image(label, cx, cy, image_size) # Intensity rescaling image = rescale_intensity(image, (1.0, 99.0)) # Append the image slices to the batch # Use list for appending, which is much faster than numpy array for z in range(Z): images += [image[:, :, z]] labels += [label[:, :, z]] # Increase the counter n_selected += 1 # Convert to a numpy array images = np.array(images, dtype=np.float32) labels = np.array(labels, dtype=np.int32) # Add the channel dimension # tensorflow by default assumes NHWC format images = np.expand_dims(images, axis=3) # Perform data augmentation if data_augmentation: images, labels = data_augmenter(images, labels, shift=shift, rotate=rotate, scale=scale, intensity=intensity, flip=flip) return images, labels