Python Collage and Contour

This set of Python programs is about creating a collage and then adding a contour to it.

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as im
import random

random.seed(123)
l = []
a = list(range(1, 37))
random.shuffle(a)

for i in a:
    if i == 35:
        continue
    image = im.imread('images/collagephoto{}.jpg'.format(i))
    l.append(image)

l1 = [l[i] for i in range(5)]
l2 = [l[i] for i in range(5, 10)]
l3 = [l[i] for i in range(10, 15)]
l4 = [l[i] for i in range(15, 20)]
l5 = [l[i] for i in range(20, 25)]
l6 = [l[i] for i in range(25, 30)]
l7 = [l[i] for i in range(30, 35)]

final = np.vstack([np.hstack(l1), np.hstack(l2), np.hstack(l3), np.hstack(l4), np.hstack(l5), np.hstack(l6), np.hstack(l7)])
fig = plt.figure(figsize=(10, 14), dpi=308)

plt.imshow(final)
plt.axis('off')

plt.savefig('collages/collage.jpg', bbox_inches='tight', pad_inches=0)
plt.show()

The contour can be anything, from a heart to a circle, you just need to plot with the right function and save the image. Notice that the contour image must have the same dimensions as the collage. In this implementation, I’m assuming the color of the plt.plot function is [111, 0, 255] (a kind of purple).

This way I’m able to eliminate the noise from the contour by imposing a limit to the G value of the pixels (the one which should be 0 in the purple color).

Also, if you still have problems, there are the complete_x and complete_y functions that can fix the exceptions of your collage.

import matplotlib.pyplot as plt
import matplotlib.image as im
import numpy as np

collage = im.imread('collages/collage.jpg')
countour = im.imread('collages/countour.jpg')

mask = np.any(countour != [255, 255, 255], axis=-1)

collage1 = collage.copy()
nice_points = []
for y in range(collage1.shape[0]):
    for x in range(collage1.shape[1]):
        if mask[y, x]:
            if countour[y, x][1] < 10:
                collage1[y, x] = countour[y, x]
            else:
                mask[y, x] = False

cancel = 1
counter = 0
counter_check = 0

collage2 = np.zeros_like(collage1)


def fill(collage1, n=1):
    global mask
    if n == 0:
        return collage1
    else:
        temp_collage = np.zeros_like(collage1)
        for y in range(1, collage1.shape[0]-1):
            for x in range(1, collage1.shape[1]-1):
                a = mask[y, x-1]
                b = mask[y-1, x]
                c = mask[y, x+1]
                d = mask[y+1, x]
                if (not mask[y, x]) and a and b and c and d:
                    temp_collage[y, x] = collage1[y-1, x]/4+collage1[y+1, x]/4+collage1[y, x-1]/4+collage1[y, x+1]/4
                    mask[y, x] = True
                else:
                    temp_collage[y, x] = collage1[y, x]
        return fill(temp_collage, n-1)


def check_position(y, x, collage):
    max_x = collage.shape[1]
    global counter_check
    if (not mask[y, x]) and mask[y, x-1]:
        for a in range(100):
            if mask[y, x + 1 + min(a, max_x-x-2)]:
                counter_check = counter_check + 1
                return True
    return False


def check_purple(y, x, collage):
    max_x = collage.shape[1]-1
    c = 0
    dp = 0
    if mask[y, x-1]:
        for r in range(x, max_x):
            if mask[y, r]:
                if dp > 10:
                    c = c + 1
                dp = 0
            else:
                dp = dp + 1
        return c
    return 17


temp_collage = fill(collage1)


for y in range(temp_collage.shape[0]):
    cancel = 1
    for x in range(temp_collage.shape[1]):
        if mask[y, x]:
            counter = counter + 1
            counter_check = 0
            if counter == 1:
                cancel = cancel * (-1)
            collage2[y, x] = temp_collage[y, x]
        else:
            condition = (check_position(y, x, temp_collage) or counter_check > 0)
            if not condition:
                counter = 0
            # print(cancel)
            if not 189 < y < 196:
                if check_purple(y, x, temp_collage) == 1 and not condition:
                    cancel = -1

            if check_purple(y, x, temp_collage) == 0:
                cancel = 1

            if cancel == 1:
                collage2[y, x] = [255, 255, 255]
            else:
                collage2[y, x] = temp_collage[y, x]


def complete_x(x_min, x_max, y, direction=1, delete=False):
    for x in range(x_min, x_max):
        c = 0
        while not mask[y+direction*c, x]:
            if delete:
                collage2[y + direction*c, x] = [255, 255, 255]
            else:
                collage2[y + direction*c, x] = temp_collage[y+direction*c, x]
            c = c + 1


def complete_y(y_min, y_max, x, direction=1, delete=False):
    for y in range(y_min, y_max):
        c = 0
        while not mask[y, x + direction*c]:
            if delete:
                collage2[y, x + direction*c] = [255, 255, 255]
            else:
                collage2[y, x + direction*c] = temp_collage[y, x + direction*c]
            c = c + 1

fig = plt.figure(figsize=(10, 10), dpi=300)
plt.imshow(collage2)
plt.axis('off')
plt.savefig('finalcollage.jpg', bbox_inches='tight', pad_inches=0)

plt.show()

P.S. Happy Easter!

Scroll to top