Experiments with ruby-processing (processing-2.2.1) and JRubyArt for processing-3.0

Monday 26 April 2010

Using the Voronoi library in ruby processing

This something I knocked up after reading a posting on the processing discourse (exhibition) posted by "guyy". The code is a lot simpler in ruby, and I much prefer the ruby processing control panel to controlP5 gui. You can get the voronoi mesh library here. In my revised version as of 30 April 2010, you can load a different image to work with.


load_libraries 'mesh', 'control_panel'
import 'megamu.mesh.Voronoi'

attr_reader :voronoi, :img, :ready, :upper, :lower, :lowskip, :highskip, :show, :points, :load_file

def setup()
 size(600, 600)
 frame_rate(10)
 #no_cursor()
 @ready = false
 @show = false
 @load_file = true
 setup_control
 @points = Array.new
 puts("done setup")
end

def setup_control
  control_panel do |c|
    c.title = "Control Panel"
    c.slider :upper, 50..255, 200
    c.slider :lower, 0..205, 150
    c.slider :lowskip, 1..20, 1
    c.slider :highskip, 1..20, 7
    c.button :change_image
    c.button :Go
    c.button :view_image
    c.button :save_voronoi
  end
end

def draw()
  background(0)
  stroke(128)
  if (load_file)
    no_loop
    file = select_input("Choose Image File")
    @img = load_image(file)
    @load_file = false
    loop
  end
  if (ready)
    display_voronoi
  end
  if(show && img)
    tint(255,100)
    image(img,0,0)
  end
end

def get_all_points()
  x_array = Array.new  # random array of x points
  y_array = Array.new  # random array of y points
  x = 0
  y = 0

  while(x < (width - highskip))
    x_array.push(x)
    x += rand(highskip) + lowskip
  end

  while(y < (height - highskip))
    y_array.push(y)
    y += rand(highskip) + lowskip
  end

  x_array.each do |pos_x|
    y_array.each do |pos_y|
      b = brightness(img.get(pos_x, pos_y))
      if (b <= upper && b >= lower)
        @points.push([pos_x, pos_y])
      end
    end
  end
  puts("total #{points.size()}")
end

def display_voronoi
  regions = voronoi.get_regions
  stroke(128)
  fill(0)  
  regions.each do |region|
    region_coordinates = region.get_coords
    region.draw(self)
  end

  edges = voronoi.get_edges
  
  edges.each do |edge|
    x0 = edge[0]
    y0 = edge[1]
    x1 = edge[2]
    y1 = edge[3]
    line(x0, y0, x1, y1)
  end

  fill(128)
  no_stroke
end

def mouse_pressed()
  no_loop
  b = brightness(img.get(mouse_x, mouse_y)) if img
  puts "Brightness = #{b}"
  loop
end

def Go()
  no_loop
  @ready = false
  @points.clear
  get_all_points if img
  @voronoi = Voronoi.new(@points.to_java(Java::float[]))
  @ready = true
  loop
end

def save_voronoi
  no_loop
  save_frame
  puts "finished!"
  loop
end

def change_image
  @load_file = !load_file      
end
def view_image
  @show = !show
end


Use this tool to create "voronoi portraits" from greyscale images. Here is the application in action with one of my context free "tree" images. In the screenshot below the view_image button has been selected, after the the voronoi was displayed.



If you move the mouse over regions in the original image, and press it the brightness is printed to the console (helps setting thresholds).

Here is what a saved voronoi image looks like (images are saved as a tif by default).


Here is an image you might recognize (Inverted using the Gimp)








No comments:

Post a Comment

Followers

Blog Archive

About Me

My photo
I have developed JRubyArt and propane new versions of ruby-processing for JRuby-9.1.5.0 and processing-3.2.2