Ejemplo n.º 1
0
def overlap(topics,
            emotions,
            icons,
            colors,
            size,
            background=(255, 255, 255),
            icon_ratio=0.1,
            size_flux=0.25,
            rand_alpha=True,
            passes=10,
            mask_all=True,
            border_shape=False,
            border_color=None,
            inc_floor=.5,
            inc_ceiling=.75,
            text=True,
            **kwargs):
    """
    Overlap visualization.

    :param topics: Topics to use (list).
    :param emotions: Emotions to use (list).
    :param icons: Shape icons (dict).
    :param colors: Emotion colors (dict).
    :param background: Background color in RGB (tuple).
    :param border_shape: Whether to apply icon shape as border (bool).
    :param border_color: Border color in RGB (tuple).
    :param text: Include text labels below visualization (bool).
    :param icon_ratio: Ratio of small shape sizes to overall image size (float).
    :param size_flux: Standard deviation by which small shapes vary in size (float).
    :param rand_alpha: Randomly adjust opacity of each shape placed (float).
    :param passes: Number of overlapping passes (int).
    :param mask_all: Opacity mask for individual small shapes (bool).
    :param inc_floor: Minimum step size in placing new shape (float).
    :param inc_ceiling: Maximum step size in placing new shape (float).
    :param kwargs: Additional arguments (dict).
    :return: Visualization (array).
    """
    if len(topics) == 0 or len(emotions) == 0:
        return None
    elif topics[0] is None:
        border_shape = False
    elif not set(topics) <= set(icons.keys()):
        return 'Error: Topics outside of presets.'
    elif not set(emotions) <= set(colors.keys()):
        return 'Error: Emotions outside of presets.'
    start_size = (
        500, 500
    )  # Start here because smaller values run into issues with sub-shape masking
    base_size = int(min(start_size) * icon_ratio)
    if topics[0] is None:
        icons_resized = np.ones((base_size, base_size)) * 255
        border_points = np.concatenate(
            (np.column_stack(
                (np.zeros(base_size), np.array(np.arange(0, base_size)))),
             np.column_stack((np.ones(base_size) * (base_size - 1),
                              np.array(np.arange(0, base_size)))),
             np.column_stack(
                 (np.array(np.arange(0, base_size)), np.zeros(base_size))),
             np.column_stack(
                 (np.array(np.arange(0, base_size)),
                  np.ones(base_size) * (base_size - 1))))).astype(int)
        icons_resized[border_points[:, 0], border_points[:, 1]] = 0
        icons_resized = [icons_resized]
    else:
        icons_resized = [
            cv2.resize(icons[topic], (base_size, base_size))
            for topic in topics
        ]
    colors_list = [colors[emotion] for emotion in emotions]
    color_icons = [
        fill_color(icon, color['rgb'], border_color)
        for icon, color in product(icons_resized, colors_list)
    ]

    canvas = np.zeros((start_size[0], start_size[1], 3))
    canvas[..., :] = background
    for p in range(passes):
        complete = False
        start = [
            random.randint(0, base_size // 4),
            random.randint(0, base_size // 4)
        ]
        while not complete:
            icon, icon_size = random.choice(color_icons), max(
                1, int(base_size * np.random.normal(1, size_flux)))
            icon_resized = cv2.resize(icon, (icon_size, icon_size),
                                      interpolation=cv2.INTER_NEAREST)
            adj_y = min(int(start[0] * np.random.normal(1, .025)),
                        start_size[0] - icon_size)
            mask = bg_mask(icon_resized, colors_list,
                           border_color) if mask_all else None
            increment = random.randint(int(inc_floor * icon_size),
                                       int(icon_size * inc_ceiling))
            alpha = random.random() if rand_alpha else 0
            if start[1] + icon_size < canvas.shape[1]:
                canvas = fill_canvas(canvas, background, mask, start_size,
                                     icon_resized, start, adj_y, icon_size,
                                     alpha)
                start[1] += increment
            elif start[0] + icon_size < canvas.shape[0]:
                start[0] += increment
                start[1] = increment
                canvas = fill_canvas(canvas, background, mask, start_size,
                                     icon_resized, start, adj_y, icon_size,
                                     alpha)
            else:
                complete = True

    if border_shape:
        canvas = apply_shape(canvas, icons, topics, start_size, border_color,
                             background)

    canvas = cv2.resize(canvas, size)

    if text:
        canvas = add_labels(canvas, topics, emotions, colors)

    return canvas
Ejemplo n.º 2
0
def string(topics,
           emotions,
           icons,
           colors,
           size,
           background=(255, 255, 255),
           n_lines=150,
           line_width_string=5,
           border_shape=True,
           border_color=None,
           text=True,
           offset_sd=0.2,
           **kwargs):
    """
    String doll visualization.

    :param topics: Topics to use (list).
    :param emotions: Emotions to use (list).
    :param icons: Shape icons (dict).
    :param colors: Emotion colors (dict).
    :param background: Background color in RGB (tuple).
    :param border_shape: Whether to apply icon shape as border (bool).
    :param border_color: Border color in RGB (tuple).
    :param text: Include text labels below visualization (bool).
    :param n_lines: Number of lines drawn (int).
    :param line_width_string: Width of lines (int).
    :param offset_sd: Standard deviation of offset for arc (float).
    :param kwargs: Additional arguments (dict).
    :return: Visualization (array).
    """
    if len(topics) == 0 or len(emotions) == 0:
        return None
    elif topics[0] is None:
        border_shape = False
    elif not set(topics) <= set(icons.keys()):
        return 'Error: Topics outside of presets.'
    elif not set(emotions) <= set(colors.keys()):
        return 'Error: Emotions outside of presets.'
    colors_list = [colors[emotion] for emotion in emotions]

    canvas = np.zeros((size[0], size[1], 3))
    canvas[..., :] = background

    # Get coordinates of shape boundaries to start and end curves
    if border_shape:
        # Load a boolean mask indicating outline region
        bool_mask = shape_bool_mask(icons, topics, size, border_color)[..., 0]
        canvas[bool_mask] = (245, 245, 245)

        border = cv2.resize(icons[topics[0]], size) / 255
        border_points = np.argwhere(~border.astype(bool)).tolist()
    else:
        border_points = np.concatenate(
            (np.column_stack(
                (np.zeros(size[0]), np.array(np.arange(0, size[1])))),
             np.column_stack((np.ones(size[0]) * (size[0] - 1),
                              np.array(np.arange(0, size[1])))),
             np.column_stack(
                 (np.array(np.arange(0, size[0])), np.zeros(size[1]))),
             np.column_stack((np.array(np.arange(0, size[0])),
                              np.ones(size[1]) * (size[1] - 1)))))
        border_points = border_points.tolist()

    # For n number of curves, select arbitrary start and end point on boundary, then one random midpoints
    for line in range(n_lines):
        start, end = random.sample(border_points,
                                   1)[0], random.sample(border_points, 1)[0]
        offset = np.random.normal(scale=offset_sd)
        mid1 = np.array([start[0] / 2 + end[0] / 2, start[1] / 2 + end[1] / 2
                         ]) * (1 + offset)
        points = [start, mid1, end]

        nPoints = len(points)
        xPoints = np.array([p[1] for p in points])
        yPoints = np.array([p[0] for p in points])

        t = np.linspace(0.0, 1.0, 50)

        polynomial_array = np.array([
            comb(nPoints - 1, i) * (t**(nPoints - 1 - i)) * (1 - t)**i
            for i in range(0, nPoints)
        ])

        xvals = np.dot(xPoints, polynomial_array)[:, None]
        yvals = np.dot(yPoints, polynomial_array)[:, None]

        curve_points = np.concatenate((xvals, yvals),
                                      axis=1).astype(np.int32)[None, ...]

        color = np.random.choice(colors_list)['rgb']

        cv2.polylines(canvas,
                      curve_points,
                      False, [color[2], color[1], color[0]],
                      line_width_string,
                      lineType=cv2.LINE_AA)
        cv2.polylines(
            canvas,
            curve_points,
            False,
            [int(color[2] * 1.5),
             int(color[1] * 1.5),
             int(color[0] * 1.5)],
            1,
            lineType=cv2.LINE_AA)

    if border_shape:
        canvas = apply_shape(canvas, icons, topics, size, border_color,
                             background)

    if text:
        canvas = add_labels(canvas, topics, emotions, colors)

    return canvas
Ejemplo n.º 3
0
def tiles(topics,
          emotions,
          icons,
          colors,
          size,
          background=(255, 255, 255),
          border_shape=True,
          border_color=None,
          text=True,
          line_width_tile=1,
          step_size=10,
          dir_prob=0.5,
          **kwargs):
    """
    Tile visualization.

    :param topics: Topics to use (list).
    :param emotions: Emotions to use (list).
    :param icons: Shape icons (dict).
    :param colors: Emotion colors (dict).
    :param background: Background color in RGB (tuple).
    :param border_shape: Whether to apply icon shape as border (bool).
    :param border_color: Border color in RGB (tuple).
    :param text: Include text labels below visualization (bool).
    :param line_width_tile: Line width (int).
    :param step_size: Step size separating lines (int).
    :param dir_prob: Probability of choosing first direction (float).
    :param kwargs: Additional arguments (dict).
    :return: Visualization (array).
    """
    if len(topics) == 0 or len(emotions) == 0:
        return None
    elif topics[0] is None:
        border_shape = False
    elif not set(topics) <= set(icons.keys()):
        return 'Error: Topics outside of presets.'
    elif not set(emotions) <= set(colors.keys()):
        return 'Error: Emotions outside of presets.'
    colors_list = [colors[emotion] for emotion in emotions]

    # Draw lines
    canvas = np.ones((size[0], size[1], 3))
    for i in range(0, size[0], step_size):
        for j in range(0, size[1], step_size):
            if random.uniform(0, 1) > dir_prob:
                cv2.line(canvas, (j, i), (j + step_size, i + step_size),
                         (0, 0, 0), line_width_tile)
            else:
                cv2.line(canvas, (j, i + step_size), (j + step_size, i),
                         (0, 0, 0), line_width_tile)
    canvas = np.uint8(canvas[..., 0])

    # Find connected components
    connections = measure.regionprops(measure.label(canvas, connectivity=1))

    # Canvas for output
    canvas = np.zeros((size[0], size[1], 3))
    canvas[..., :] = background

    for component in connections:
        fill = random.choice(colors_list)['rgb']
        canvas[component.coords[:, 0],
               component.coords[:, 1]] = [fill[2], fill[1], fill[0]]
    del connections
    gc.collect()

    if border_shape:
        canvas = apply_shape(canvas, icons, topics, size, border_color,
                             background)

    if text:
        canvas = add_labels(canvas, topics, emotions, colors)

    return canvas
Ejemplo n.º 4
0
def circle(topics,
           emotions,
           icons,
           colors,
           size,
           background=(255, 255, 255),
           min_rad_factor=.01,
           max_rad_factor=.09,
           n_circles=100,
           max_attempts=100,
           border_shape=True,
           border_color=None,
           border_width=1,
           text=True,
           **kwargs):
    """
    Circle packing visualization.

    :param topics: Topics to use (list).
    :param emotions: Emotions to use (list).
    :param icons: Shape icons (dict).
    :param colors: Emotion colors (dict).
    :param size: Size of output (tuple).
    :param background: Background color in RGB (tuple).
    :param border_shape: Whether to apply icon shape as border (bool).
    :param border_color: Border color in RGB (tuple).
    :param text: Include text labels below visualization (bool).
    :param min_rad_factor: Minimum ratio of circle radius to image size (float).
    :param max_rad_factor: Maximum ratio of circle radius to image size (float).
    :param n_circles: Number of circles (int).
    :param max_attempts: Maximum number of attempts to place each circle (int).
    :param border_width: Circle border width (int).
    :param kwargs: Additional arguments (dict).
    :return: Visualization (array).
    """
    if len(topics) == 0 or len(emotions) == 0:
        return None
    elif topics[0] is None:
        border_shape = False
    elif not set(topics) <= set(icons.keys()):
        return 'Error: Topics outside of presets.'
    elif not set(emotions) <= set(colors.keys()):
        return 'Error: Emotions outside of presets.'
    colors_list = [colors[emotion] for emotion in emotions]

    canvas = np.zeros((size[0], size[1], 3))
    canvas[..., :] = background

    if topics[0] is None:
        bool_mask = np.ones((size[0], size[1])).astype(bool)
        min_row, max_row = 0, size[0] - 1
        min_col, max_col = 0, size[1] - 1
    else:
        # Load a boolean mask indicating whether each coordinate is within desired outline shape
        bool_mask = shape_bool_mask(icons, topics, size, border_color)[..., 0]
        interior_coords = np.argwhere(bool_mask)
        min_row, max_row = np.min(interior_coords[:, 0]), np.max(
            interior_coords[:, 0])
        min_col, max_col = np.min(interior_coords[:, 1]), np.max(
            interior_coords[:, 1])
        canvas[bool_mask] = (245, 245, 245)

    # Choose a set of random radii and sort by largest first
    min_rad, max_rad = min_rad_factor * size[0], max_rad_factor * size[0]
    circles_to_place = (min_rad +
                        (max_rad - min_rad) * np.random.random(n_circles) *
                        np.random.random(n_circles)).astype('int')
    circles_to_place[::-1].sort()

    # For each circle, X number of attempts to place it without going outside boundary or overlapping another circle
    can_place = bool_mask
    fail_count = 0
    all_rows, all_cols = np.arange(size[0]), np.arange(size[1])
    for r in circles_to_place:
        if fail_count < n_circles / 10:
            placed, try_idx = False, 0
            row_try = np.random.uniform(min_row, max_row, max_attempts)
            col_try = np.random.uniform(min_col, max_col, max_attempts)
            try_coords = np.concatenate((row_try[:, None], col_try[:, None]),
                                        1).astype('int')
            while not placed and try_idx < max_attempts:
                try_center = try_coords[try_idx]
                # Get coordinates of circle with given center and radius
                spacing_mask = (all_cols[None, :] - try_center[1]) ** 2 + \
                              (all_rows[:, None] - try_center[0]) ** 2 < (r+border_width) ** 2
                circle_mask = (all_cols[None, :] - try_center[1]) ** 2 + \
                              (all_rows[:, None] - try_center[0]) ** 2 < r ** 2
                inner_mask = (all_cols[None, :] - try_center[1]) ** 2 + \
                             (all_rows[:, None] - try_center[0]) ** 2 < (r-border_width) ** 2
                no_conflicts = np.all(
                    np.logical_and(can_place, spacing_mask)[spacing_mask])
                if no_conflicts:
                    color = np.random.choice(colors_list)['rgb']
                    canvas[circle_mask] = [50, 50, 50]
                    canvas[inner_mask] = [color[2], color[1], color[0]]
                    can_place = np.logical_and(can_place, ~spacing_mask)
                    placed = True
                    fail_count = 0
                else:
                    try_idx += 1
            fail_count += 1

    if border_shape:
        canvas = apply_shape(canvas, icons, topics, size, border_color,
                             background)

    if text:
        canvas = add_labels(canvas, topics, emotions, colors)

    return canvas
Ejemplo n.º 5
0
def ae(topics,
       emotions,
       icons,
       colors,
       size,
       in_size=16,
       background=(255, 255, 255),
       border_shape=False,
       border_color=None,
       text=True,
       intensity_sd=.2,
       **kwargs):
    """
    Autoencoder visualization.

    :param topics: Topics to use (list).
    :param emotions: Emotions to use (list).
    :param icons: Shape icons (dict).
    :param colors: Emotion colors (dict).
    :param size: Size of output (tuple).
    :param in_size: Size of input, assuming square shape (int).
    :param background: Background color in RGB (tuple).
    :param border_shape: Whether to apply icon shape as border (bool).
    :param border_color: Border color in RGB (tuple).
    :param text: Include text labels below visualization (bool).
    :param intensity_sd: Standard deviation for random color intensity adjustment (float).
    :param kwargs: Additional arguments (dict).
    :return: Visualization (array).
    """
    if len(topics) == 0 or len(emotions) == 0:
        return None
    elif topics[0] is None:
        border_shape = False
    elif not set(topics) <= set(icons.keys()):
        return 'Error: Topics outside of presets.'
    elif not set(emotions) <= set(colors.keys()):
        return 'Error: Emotions outside of presets.'

    colors_list = [colors[emotion]['rgb'] for emotion in emotions]
    canvas = np.ones((in_size, in_size, 3))
    coords = np.reshape(
        np.indices((in_size, in_size)).transpose((1, 2, 0)),
        (in_size * in_size, 2))
    np.random.shuffle(coords)
    coords_split = np.array_split(coords, len(colors_list))
    for idx, c in enumerate(colors_list):
        canvas[coords_split[idx][:, 0], coords_split[idx][:, 1]] = c[::-1]
        canvas[coords_split[idx][:, 0],
               coords_split[idx][:, 1]] *= np.random.normal(
                   loc=1,
                   scale=intensity_sd,
                   size=(canvas[coords_split[idx][:, 0],
                                coords_split[idx][:, 1]].shape))

    img_proc = np.asarray(canvas, dtype='float32')[None, ...]
    img_proc = (img_proc / 127.5 - 1.0).astype(np.float32)

    with session.as_default():
        with session.graph.as_default():
            img_out = dec_model.predict(enc_model.predict(img_proc,
                                                          batch_size=1),
                                        batch_size=1)
    img_out = (img_out[0, ..., :3] * 127.5 + 127.5).astype(np.uint8)

    if border_shape:
        img_out = apply_shape(img_out, icons, topics, size, border_color,
                              background)

    if text:
        img_out = add_labels(img_out, topics, emotions, colors)

    return img_out
Ejemplo n.º 6
0
def carpet(topics, emotions, icons, colors, size, background=(255, 255, 255),
           border_shape=True, border_color=None, text=True,
           tile_ratio=.1, line_width=1, rotations=4, rot_degree=45, num_lines=3,
           **kwargs):
    """
    Carpet visualization.

    :param topics: Topics to use (list).
    :param emotions: Emotions to use (list).
    :param icons: Shape icons (dict).
    :param colors: Emotion colors (dict).
    :param size: Size of output (tuple).
    :param background: Background color in RGB (tuple).
    :param border_shape: Whether to apply icon shape as border (bool).
    :param border_color: Border color in RGB (tuple).
    :param text: Include text labels below visualization (bool).
    :param tile_ratio: Ratio of tile sizes to overall image size (float).
    :param line_width: Width of lines drawn (int).
    :param rotations: Number of rotations for lines (int).
    :param rot_degree: Degree of rotations for lines (int).
    :param num_lines: Number of lines (int).
    :param kwargs: Additional arguments (dict).
    :return: Visualization (array).
    """
    if len(topics) == 0 or len(emotions) == 0:
        return None
    elif topics[0] is None:
        border_shape = False
    elif not set(topics) <= set(icons.keys()):
        return 'Error: Topics outside of presets.'
    elif not set(emotions) <= set(colors.keys()):
        return 'Error: Emotions outside of presets.'
    colors_list = [colors[emotion] for emotion in emotions]

    canvas = np.zeros((size[0], size[1], 3))
    canvas[..., :] = background

    tile_size = int(size[0]*tile_ratio)
    num_tiles = (int(size[0]/tile_size), int(size[1]/tile_size))
    line_array = np.linspace(0, tile_size, num_lines)[:, None]

    for i in range(num_tiles[0]):
        for j in range(num_tiles[1]):
            x_start = j*tile_size
            y_start = i*tile_size
            all_start =  np.int32(line_array + [x_start, y_start])
            angle = random.choice(range(0, rotations*rot_degree, rot_degree))
            for line in range(num_lines):
                if angle == 0:
                    start = (all_start[0, 0], all_start[line, 1])
                    end = (all_start[num_lines-1, 0], all_start[line, 1])
                elif angle == rot_degree:
                    if line < num_lines - 1:
                        start = (all_start[0, 0], all_start[num_lines-1-line, 1])
                        end = (all_start[line+1, 0], all_start[num_lines-1, 1])
                    elif 0 < line < num_lines - 1:
                        start2 = (all_start[line, 0], all_start[0, 1])
                        end2 = (all_start[num_lines-1, 0], all_start[num_lines-line, 1])
                        cv2.line(canvas, start2, end2, (0, 0, 0), line_width)
                elif angle == rot_degree*2:
                    start = (all_start[line, 0], all_start[0, 1])
                    end = (all_start[line, 0], all_start[num_lines-1, 1])
                elif angle == rot_degree*3:
                    if line < num_lines - 1:
                        start = (all_start[0, 0], all_start[line+1, 1])
                        end = (all_start[line+1, 0], all_start[0, 1])
                    elif 0 < line < num_lines - 1:
                        start2 = (all_start[line, 0], all_start[num_lines-1, 1])
                        end2 = (all_start[num_lines-1, 0], all_start[line, 1])
                        cv2.line(canvas, start2, end2, (0, 0, 0), line_width)
                cv2.line(canvas, start, end, (0, 0, 0), line_width)
    canvas = np.uint8(canvas[..., 0])

    # Find connected components
    connections = measure.regionprops(measure.label(canvas, connectivity=1))

    # Canvas for output
    canvas = np.zeros((size[0], size[1], 3))
    canvas[..., :] = background

    for component in connections:
        fill = random.choice(colors_list)['rgb']
        canvas[component.coords[:, 0], component.coords[:, 1]] = [fill[2], fill[1], fill[0]]
    del connections
    gc.collect()

    if border_shape:
        canvas = apply_shape(canvas, icons, topics, size, border_color, background)

    if text:
        canvas = add_labels(canvas, topics, emotions, colors)

    return canvas