Skip to content

Instantly share code, notes, and snippets.

@mverleg
Created September 12, 2018 20:05
Show Gist options
  • Save mverleg/8abdf0f005f285730790ea4c2daa0c06 to your computer and use it in GitHub Desktop.
Save mverleg/8abdf0f005f285730790ea4c2daa0c06 to your computer and use it in GitHub Desktop.
Voronoiify an image
"""
This divides the images in small patches by means of minimal distance to random points.
It then computes the average color of each patch, and gives the whole patch that color.
This code is NOT fast, O(N^2) for N number of pixels (~1min). It's pretty short and easy though.
"""
from random import randint, seed
from time import time
from matplotlib.pyplot import subplots, show
from numpy import zeros, array, int32
from scipy.misc import imread
def voronoi(img, centers):
partof = zeros((img.shape[0], img.shape[1], 2,))
sums = dict((center, array([0, 0, 0, 0], dtype=int32)) for center in centers)
for px in range(img.shape[0]):
for py in range(img.shape[1]):
min_xy = (-1, -1)
min_dist = 1e100
for cx, cy in centers:
dist = (cx - px) ** 2 + (cy - py) ** 2
if dist < min_dist:
min_xy = cx, cy
min_dist = dist
partof[px, py, :] = min_xy
pix = img[min_xy]
sums[min_xy] += array([pix[0], pix[1], pix[2], 1])
avgs = dict((k, [s[0] // s[3], s[1] // s[3], s[2] // s[3]]) for (k, s) in sums.items())
for px in range(img.shape[0]):
for py in range(img.shape[1]):
img[px, py, :] = avgs[tuple(partof[px, py, :])]
return img
if __name__ == '__main__':
img = imread('your_image_name_here.png')
fig, (before, after) = subplots(2, 1, figsize=(8, 12), tight_layout=True)
before.imshow(img)
centercnt = int((img.shape[0] * img.shape[1]) / 200)
seed(42424242)
centers = set()
while len(centers) < centercnt:
centers.add((randint(0, img.shape[0] - 1), randint(0, img.shape[1] - 1)))
print('voronoi for {} centers on {}x{} img'.format(centercnt, img.shape[0], img.shape[1]))
t0 = time()
voro = voronoi(img, centers)
print('voronoi took {:.3f}s'.format(time() - t0))
after.imshow(voro)
show()
@mverleg
Copy link
Author

mverleg commented Sep 12, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment