def generate(self): ''' Generate stippled image. ''' self._logger.log(Logger.INFO, "Generating stippled image.") self.voronoi = Voronoi(self.points, self.image.width, self.image.height) self.pre_compute() for index_iteration in range(self.max_iterations): self._logger.log( Logger.INFO, str(index_iteration) + " iteration: moving points to new positions.") self.plot("test/image_" + str(index_iteration) + ".png") self.move_points()
def testVoronoi(self): """ I ve tested how voronoi package works but it has problems when dataset of points is greater than 20 """ print("test using voronoi lib") self._loadMap() # print("len self map:", len(self.map)) print(self.map) raw_points = self.map points = self.fuse( raw_points.copy(), 6 ) # here is magic of rounding problem is that i have to specify round radius (2nd param) by my self # Define a bounding box polygon = Polygon([(0.0, 0.0), (0.0, 400.0), (400.0, 0.0), (400.0, 400.0)]) # Initialize the algorithm v = Voronoi(polygon) # Create the diagram v.create_diagram(points=points, vis_steps=False, verbose=False, vis_result=True, vis_tree=True) # Get properties edges = v.edges vertices = v.vertices arcs = v.arcs points = v.points print("voronoi properties:") print("edges:", edges) print("vertices:", vertices) print("arcs:", arcs) print("points:", points) print(v.points[0].get_coordinates()) for point in v.points: print(f"{(point.x, point.y)} \t {point.cell_size()}")
def voronoi(self): test = set() for e in self.edges: i = 0 for u in bresenham_line(*e.points): if i % 20 == 0: test.add(u) i += 1 v = Voronoi(test) v.process() self.bbb = [] voronoi_res = [] ddd = {} for e in v.output: p01 = round(e.points[0].x), round(e.points[0].y) p02 = round(e.points[1].x), round(e.points[1].y) if p01 == p02: continue if p01 in ddd: ddd[p01] += 1 else: ddd[p01] = 1 p1 = Point(*p01) p2 = Point(*p02) voronoi_res.append(Segment(p1, p2)) for e in voronoi_res: p1 = e.points[0] p2 = e.points[1] if self.check_point_inside_polygon(p1) and \ self.check_point_inside_polygon(p2) and \ not self.check_point_on_edge(p1) and \ not self.check_point_on_edge(p2): self.bbb.append(e) self.filter_bbb(voronoi_res, ddd)
def tessellate(sources, planesize, num_facets, threshold=0, host=0): """ sources: the list of sources to be used as facets planesize: the size of the plane (used to cut the lines to size once the Voronoi is formed) num_facets: the maximum number of facets to be generated by the final output threshold: the minimum pixel intensity for it to be considered a potential facet centre host: 0 for CPU, 1 for GPU """ #objects above the threshold seleected stellars = source_gen(sources, threshold) print len(stellars) #voronoi found Voronoi(stellars, (0, len(stellars) - 1)) #append sources to cell, recentre and compute error source_to_cell(stellars, sources, planesize) recenter(stellars) e = 0 for p in stellars: e += p[8] if (host == 0): print 'cpu merge' e = cell_merge(stellars, num_facets, e) if (host == 1): from gpu_merge import gpu_merge print 'gpu merge' e = gpu_merge(stellars, num_facets, e, len(sources)) cells = gen_cells(stellars, planesize) return cells ###############################################################################
from voronoi import Voronoi from voronoi.graph.bounding_circle import BoundingCircle # Define a set of points points = [ (1, 2), (7, 13), (12, 6), (5, 5), ] # Define a bounding circle bounding_circle = BoundingCircle(5., 5., 9.) v = Voronoi(bounding_circle) v.create_diagram(points=points, vis_before_clipping=True, vis_steps=True, verbose=True, vis_result=True, vis_tree=True) edges = v.edges vertices = v.vertices arcs = v.arcs points = v.points
from voronoi import Polygon, Voronoi, VoronoiObserver, TreeObserver, DebugObserver from voronoi.visualization import Presets # Define some points (a.k.a sites or cell points) points = [ (2.5, 2.5), (4, 7.5), (7.5, 2.5), (6, 7.5), (4, 4), (3, 3), (6, 3) ] # Define a bounding box / polygon polygon = Polygon([ (2.5, 10), (5, 10), (10, 5), (10, 2.5), (5, 0), (2.5, 0), (0, 2.5), (0, 5) ]) # Initialize the algorithm v = Voronoi(polygon) # Attach a Voronoi observer that visualizes the Voronoi diagram every step v.attach_observer( VoronoiObserver( # Settings to pass into the visualizer's plot_all() method. # - By default, the observer uses a set of minimalistic presets that are useful for visualizing during # construction, clipping and the final result. Have a look at Presets.construction, Presets.clipping and # Presets.final. # - These settings below will update the default presets used by the observer. For example, by default, # the arc_labels are not shown, but below we can enable the arc labels. Other parameters can be found in # the visualizer's plot_all() method. settings=dict(arc_labels=True, site_labels=True), # Callback that saves the figure every step
neurons = int(arg) if opt in ("-l", "--learning"): learning_rate = float(arg) if opt in ("-m", "--min_euclidean"): min_euclidean = float(arg) if opt in ("-s", "--spacial"): if arg == "line": spacial = SpacialGenerator.line if arg == "circle": spacial = SpacialGenerator.circle if opt in ("-e", "--epochs"): epochs = int(arg) dimensions = [x, y] som = SelfOrganisingMap(dimensions, neurons, learning_rate, min_euclidean) for i in range(epochs): if spacial == SpacialGenerator.line: point = spacial(1, 0, dimensions) elif spacial == SpacialGenerator.circle: point = spacial(dimensions) som.activate(point, i) self_organised_points = som.weight_vectors() Logger.output("points after som: {0}".format(self_organised_points)) voronoi = Voronoi(dimensions) voronoi.drawMosaic(self_organised_points)
class Stippling: ''' Compute stippling. ''' _logger = Logger() image = None pixels_by_gray_level = None total_points = 0 max_level = 256 pixel_distribution = None points = None max_iterations = 0 alpha = 2.0 voronoi = None def __init__(self, image=None, total_points=None, max_iterations=None, alpha=None, path=None): if path is None: self.total_points = total_points self.max_iterations = max_iterations self.alpha = alpha else: self.load(path) self.stippled_image = Image(image=np.ones(image.data.shape) * (self.max_level - 1)) self.image = image def generate(self): ''' Generate stippled image. ''' self._logger.log(Logger.INFO, "Generating stippled image.") self.voronoi = Voronoi(self.points, self.image.width, self.image.height) self.pre_compute() for index_iteration in range(self.max_iterations): self._logger.log( Logger.INFO, str(index_iteration) + " iteration: moving points to new positions.") self.plot("test/image_" + str(index_iteration) + ".png") self.move_points() def get_image(self): self.voronoi.compute_region_map(self.points) return self.voronoi.get_image() def pre_compute(self): ''' Pre compute stippled image. ''' self._logger.log(Logger.INFO, "Pre-computing stippled image.") total = 0 self.points = [] self.get_pixels_by_gray_level() self.compute_pixels_distribution() # Pre-compute stippled image. for index_level in range(self.max_level): index_pixel = 0 total_pixels = int(self.pixel_distribution[index_level]) random.shuffle(self.pixels_by_gray_level[index_level]) # Set points for each level. for _ in range(total_pixels): y = self.pixels_by_gray_level[index_level][index_pixel][0] x = self.pixels_by_gray_level[index_level][index_pixel][1] self.points.append((y, x)) total += 1 index_pixel += 1 def get_pixels_by_gray_level(self): ''' Get pixels by gray level. ''' self.pixels_by_gray_level = [[] for _ in range(self.max_level)] # Set pixels by gray level. for y in range(self.image.height): for x in range(self.image.width): self.pixels_by_gray_level[self.image.data[y][x]].append((y, x)) return self.pixels_by_gray_level def compute_pixels_distribution(self): ''' Compute pixels distribution. ''' # Compute how much pixels goes to each level. self.pixel_distribution = np.zeros(self.max_level) index_level = 0 total_points = self.total_points total_pixels = self.image.width * self.image.height if total_points > total_pixels: total_points = total_pixels # While there are points to distribute. while total_points > 0: # Calculate total of pixels to distribute in level. total_pixels_in_level = len(self.pixels_by_gray_level[index_level]) distributed_pixels_in_level = total_pixels_in_level * 1.0 / total_pixels distributed_pixels_in_level *= total_points distributed_pixels_in_level *= ( self.max_level - index_level)**self.alpha * 1.0 / self.max_level**self.alpha distributed_pixels_in_level = int(distributed_pixels_in_level) if distributed_pixels_in_level == 0: distributed_pixels_in_level = 1 # Add pixels to level. self.pixel_distribution[index_level] += distributed_pixels_in_level if self.pixel_distribution[index_level] > total_pixels_in_level: distributed_pixels_in_level -= self.pixel_distribution[ index_level] - total_pixels_in_level self.pixel_distribution[index_level] = total_pixels_in_level total_points -= distributed_pixels_in_level # Get next level. if index_level == 255: index_level = 0 else: index_level += 1 def plot(self, save_path=None): ''' Plot stippled image. ''' import matplotlib.pyplot as plt x = [point[1] for point in self.points] y = [self.image.height - point[0] for point in self.points] fig = plt.figure(frameon=False) plt.axis('off') ax = fig.add_subplot(1, 1, 1) plt.xlim(0, self.stippled_image.width) plt.ylim(0, self.stippled_image.height) plt.scatter(x, y, s=1) extent = ax.get_window_extent().transformed( fig.dpi_scale_trans.inverted()) if save_path != None: plt.savefig(save_path, bbox_inches=extent) plt.clf() plt.close('all') else: plt.show() def move_points(self): ''' Move points to new positions. ''' self.voronoi.compute_region_map(self.points) self.x_total_density_x = np.zeros(self.total_points) self.y_total_density_y = np.zeros(self.total_points) self.sum_x = np.zeros(self.total_points) self.sum_y = np.zeros(self.total_points) self.total_density = np.zeros(self.total_points) density = (1 - self.image.data * 1.0 / self.max_level)**self.alpha # Compute integrals to calculate new centroids. for y in range(self.image.height): for x in range(self.image.width): self.total_density[self.voronoi.region_map[y, x]] += density[y, x] self.x_total_density_x[self.voronoi.region_map[ y, x]] += x * density[y, x] self.y_total_density_y[self.voronoi.region_map[ y, x]] += y * density[y, x] self.sum_x[self.voronoi.region_map[y, x]] += x self.sum_y[self.voronoi.region_map[y, x]] += y # Compute new centroids. self.points = [] for index_region in range(self.total_points): self.compute_new_centers(index_region) def compute_new_centers(self, index_region): ''' Compute new centers. ''' if self.total_density[index_region] > 0: x = int(self.x_total_density_x[index_region] / self.total_density[index_region] + 0.5) y = int(self.y_total_density_y[index_region] / self.total_density[index_region] + 0.5) elif self.sum_x[index_region] > 0 and self.sum_y[index_region] > 0: x = int(self.x_total_density_x[index_region] / self.sum_x[index_region] + 0.5) y = int(self.y_total_density_y[index_region] / self.sum_y[index_region] + 0.5) else: x = np.random.random() * self.image.width - 1 y = np.random.random() * self.image.height - 1 if x > self.image.width - 1: x = self.image.width - 1 elif x < 0: x = 0 if y > self.image.height - 1: y = self.image.height - 1 elif y < 0: y = 0 self.points.append([y, x]) def save(self, path): ''' Save stippling result. ''' np.savez_compressed(path, points=np.array(self.points)) def load(self, path): ''' Load stippling result. ''' compressed_file = np.load(path) self.points = compressed_file["points"].tolist()
# Example: # points = [ # Point(27, 89), # Point(15, 95), # Point(49, 8), # Point(79, 63), # Point(54, 12), # Point(77, 92), # Point(62, 82), # Point(83, 71), # Point(58, 33), # Point(53, 59), # ] # Initialize the algorithm v = Voronoi(triangle) # Optional: attach observer that visualizes Voronoi diagram every step v.attach_observer( VoronoiObserver( # Settings to put into the visualizer settings=dict(polygon=True, edges=True, vertices=True, sites=True, outgoing_edges=False, border_to_site=False, scale=1, edge_labels=False, site_labels=False,
import math import pygame, sys import random import heapq from pygame.locals import * from voronoi import Voronoi import circle pygame.init() screenrez = (500, 500) width, height = screenrez window = pygame.display.set_mode(screenrez) pygame.display.set_caption("Voronoi") screen = pygame.display.get_surface() clock = pygame.time.Clock() v = Voronoi() scanline = 0 numPoints = 12 events = [] points = [] #points are y,x so they can be ordered by heapq def randColour(): return (int(random.random() * 255), int(random.random() * 255), int(random.random() * 255)) def generatePoints(): global events, points
from voronoi import Voronoi, Visualizer from voronoi.contrib import BoundingCircle # Define a set of points points = [ (1, 2), (7, 13), (12, 6), (5, 5), ] # Define a bounding circle bounding_circle = BoundingCircle(5., 5., 9.) v = Voronoi(bounding_circle) v.create_diagram(points=points, ) edges = v.edges vertices = v.vertices arcs = v.arcs points = v.sites # Plotting Visualizer(v, canvas_offset=1) \ .plot_polygon()\ .plot_sites(points, show_labels=True) \ .plot_edges(edges, show_labels=False) \ .plot_vertices(vertices) \ .plot_border_to_site() \ .show()
] # Define a bounding box polygon = Polygon([ (2.5, 10), (5, 10), (10, 5), (10, 2.5), (5, 0), (2.5, 0), (0, 2.5), (0, 5), ]) # Initialize the algorithm v = Voronoi(polygon) # Create the diagram v.create_diagram(points=points, vis_steps=False, verbose=False, vis_result=True, vis_tree=True) # Get properties edges = v.edges vertices = v.vertices arcs = v.arcs points = v.points # Calculate the sell size for each point for point in v.points: print(f"{(point.x, point.y)} \t {point.cell_size()}") # for point in v.points: