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!