| | import matplotlib.cm |
| | import numpy as np |
| | import skimage.feature |
| | import skimage.filters |
| | import skimage.io |
| |
|
| |
|
| | def vec2im(V, shape=()): |
| | """ |
| | Transform an array V into a specified shape - or if no shape is given assume a square output format. |
| | |
| | Parameters |
| | ---------- |
| | |
| | V : numpy.ndarray |
| | an array either representing a matrix or vector to be reshaped into an two-dimensional image |
| | |
| | shape : tuple or list |
| | optional. containing the shape information for the output array if not given, the output is assumed to be square |
| | |
| | Returns |
| | ------- |
| | |
| | W : numpy.ndarray |
| | with W.shape = shape or W.shape = [np.sqrt(V.size)]*2 |
| | |
| | """ |
| |
|
| | if len(shape) < 2: |
| | shape = [np.sqrt(V.size)] * 2 |
| | shape = map(int, shape) |
| | return np.reshape(V, shape) |
| |
|
| |
|
| | def enlarge_image(img, scaling=3): |
| | """ |
| | Enlarges a given input matrix by replicating each pixel value scaling times in horizontal and vertical direction. |
| | |
| | Parameters |
| | ---------- |
| | |
| | img : numpy.ndarray |
| | array of shape [H x W] OR [H x W x D] |
| | |
| | scaling : int |
| | positive integer value > 0 |
| | |
| | Returns |
| | ------- |
| | |
| | out : numpy.ndarray |
| | two-dimensional array of shape [scaling*H x scaling*W] |
| | OR |
| | three-dimensional array of shape [scaling*H x scaling*W x D] |
| | depending on the dimensionality of the input |
| | """ |
| |
|
| | if scaling < 1 or not isinstance(scaling, int): |
| | print("scaling factor needs to be an int >= 1") |
| |
|
| | if len(img.shape) == 2: |
| | H, W = img.shape |
| |
|
| | out = np.zeros((scaling * H, scaling * W)) |
| | for h in range(H): |
| | fh = scaling * h |
| | for w in range(W): |
| | fw = scaling * w |
| | out[fh : fh + scaling, fw : fw + scaling] = img[h, w] |
| |
|
| | elif len(img.shape) == 3: |
| | H, W, D = img.shape |
| |
|
| | out = np.zeros((scaling * H, scaling * W, D)) |
| | for h in range(H): |
| | fh = scaling * h |
| | for w in range(W): |
| | fw = scaling * w |
| | out[fh : fh + scaling, fw : fw + scaling, :] = img[h, w, :] |
| |
|
| | return out |
| |
|
| |
|
| | def repaint_corner_pixels(rgbimg, scaling=3): |
| | """ |
| | DEPRECATED/OBSOLETE. |
| | |
| | Recolors the top left and bottom right pixel (groups) with the average rgb value of its three neighboring pixel (groups). |
| | The recoloring visually masks the opposing pixel values which are a product of stabilizing the scaling. |
| | Assumes those image ares will pretty much never show evidence. |
| | |
| | Parameters |
| | ---------- |
| | |
| | rgbimg : numpy.ndarray |
| | array of shape [H x W x 3] |
| | |
| | scaling : int |
| | positive integer value > 0 |
| | |
| | Returns |
| | ------- |
| | |
| | rgbimg : numpy.ndarray |
| | three-dimensional array of shape [scaling*H x scaling*W x 3] |
| | """ |
| |
|
| | |
| | rgbimg[0:scaling, 0:scaling, :] = ( |
| | rgbimg[0, scaling, :] + rgbimg[scaling, 0, :] + rgbimg[scaling, scaling, :] |
| | ) / 3.0 |
| | |
| | rgbimg[-scaling:, -scaling:, :] = ( |
| | rgbimg[-1, -1 - scaling, :] |
| | + rgbimg[-1 - scaling, -1, :] |
| | + rgbimg[-1 - scaling, -1 - scaling, :] |
| | ) / 3.0 |
| | return rgbimg |
| |
|
| |
|
| | def digit_to_rgb(X, scaling=3, shape=(), cmap="binary"): |
| | """ |
| | Takes as input an intensity array and produces a rgb image due to some color map |
| | |
| | Parameters |
| | ---------- |
| | |
| | X : numpy.ndarray |
| | intensity matrix as array of shape [M x N] |
| | |
| | scaling : int |
| | optional. positive integer value > 0 |
| | |
| | shape: tuple or list of its , length = 2 |
| | optional. if not given, X is reshaped to be square. |
| | |
| | cmap : str |
| | name of color map of choice. default is 'binary' |
| | |
| | Returns |
| | ------- |
| | |
| | image : numpy.ndarray |
| | three-dimensional array of shape [scaling*H x scaling*W x 3] , where H*W == M*N |
| | """ |
| |
|
| | |
| | cmap = eval("matplotlib.cm.{}".format(cmap)) |
| |
|
| | image = enlarge_image(vec2im(X, shape), scaling) |
| | image = cmap(image.flatten())[..., 0:3].reshape( |
| | [image.shape[0], image.shape[1], 3] |
| | ) |
| |
|
| | return image |
| |
|
| |
|
| | def hm_to_rgb(R, X=None, scaling=3, shape=(), sigma=2, cmap="bwr", normalize=True): |
| | """ |
| | Takes as input an intensity array and produces a rgb image for the represented heatmap. |
| | optionally draws the outline of another input on top of it. |
| | |
| | Parameters |
| | ---------- |
| | |
| | R : numpy.ndarray |
| | the heatmap to be visualized, shaped [M x N] |
| | |
| | X : numpy.ndarray |
| | optional. some input, usually the data point for which the heatmap R is for, which shall serve |
| | as a template for a black outline to be drawn on top of the image |
| | shaped [M x N] |
| | |
| | scaling: int |
| | factor, on how to enlarge the heatmap (to control resolution and as a inverse way to control outline thickness) |
| | after reshaping it using shape. |
| | |
| | shape: tuple or list, length = 2 |
| | optional. if not given, X is reshaped to be square. |
| | |
| | sigma : double |
| | optional. sigma-parameter for the canny algorithm used for edge detection. the found edges are drawn as outlines. |
| | |
| | cmap : str |
| | optional. color map of choice |
| | |
| | normalize : bool |
| | optional. whether to normalize the heatmap to [-1 1] prior to colorization or not. |
| | |
| | Returns |
| | ------- |
| | |
| | rgbimg : numpy.ndarray |
| | three-dimensional array of shape [scaling*H x scaling*W x 3] , where H*W == M*N |
| | """ |
| |
|
| | |
| | cmap = eval("matplotlib.cm.{}".format(cmap)) |
| |
|
| | if normalize: |
| | R = R / np.max(np.abs(R)) |
| | R = (R + 1.0) / 2.0 |
| |
|
| | R = enlarge_image(R, scaling) |
| | rgb = cmap(R.flatten())[..., 0:3].reshape([R.shape[0], R.shape[1], 3]) |
| | |
| |
|
| | if not X is None: |
| | |
| | xdims = X.shape |
| | Rdims = R.shape |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | return rgb |
| |
|
| |
|
| | def save_image(rgb_images, path, gap=2): |
| | """ |
| | Takes as input a list of rgb images, places them next to each other with a gap and writes out the result. |
| | |
| | Parameters |
| | ---------- |
| | |
| | rgb_images : list , tuple, collection. such stuff |
| | each item in the collection is expected to be an rgb image of dimensions [H x _ x 3] |
| | where the width is variable |
| | |
| | path : str |
| | the output path of the assembled image |
| | |
| | gap : int |
| | optional. sets the width of a black area of pixels realized as an image shaped [H x gap x 3] in between the input images |
| | |
| | Returns |
| | ------- |
| | |
| | image : numpy.ndarray |
| | the assembled image as written out to path |
| | """ |
| |
|
| | sz = [] |
| | image = [] |
| | for i in range(len(rgb_images)): |
| | if not sz: |
| | sz = rgb_images[i].shape |
| | image = rgb_images[i] |
| | gap = np.zeros((sz[0], gap, sz[2])) |
| | continue |
| | if not sz[0] == rgb_images[i].shape[0] and sz[1] == rgb_images[i].shape[2]: |
| | print("image", i, "differs in size. unable to perform horizontal alignment") |
| | print("expected: Hx_xD = {0}x_x{1}".format(sz[0], sz[1])) |
| | print( |
| | "got : Hx_xD = {0}x_x{1}".format( |
| | rgb_images[i].shape[0], rgb_images[i].shape[1] |
| | ) |
| | ) |
| | print("skipping image\n") |
| | else: |
| | image = np.hstack((image, gap, rgb_images[i])) |
| |
|
| | image *= 255 |
| | image = image.astype(np.uint8) |
| |
|
| | print("saving image to ", path) |
| | skimage.io.imsave(path, image) |
| | return image |
| |
|