Exemple #1
0
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))
Exemple #2
0
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()
Exemple #4
0
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)
Exemple #5
0
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
Exemple #6
0
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()
Exemple #8
0
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
    )
Exemple #9
0
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()
Exemple #10
0
    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
Exemple #11
0
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