Created
September 12, 2018 20:05
-
-
Save mverleg/8abdf0f005f285730790ea4c2daa0c06 to your computer and use it in GitHub Desktop.
Voronoiify an image
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
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() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Inspired by https://github.com/Grabot/ArtProject