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

Showing posts with label video capture. Show all posts
Showing posts with label video capture. Show all posts

Friday, 16 January 2015

A Golan Levin video capture sketch translate to ruby-processing

#
# Background Subtraction
# by Golan Levin.
# translated to ruby-processing by Martin Prout
# Detect the presence of people and objects in the frame using a simple
# background-subtraction technique. To initialize the background, press a key.
#

load_library :video
include_package 'processing.video'

attr_reader :background_pixels, :number_of_pixels, :video

def setup
  size(640, 480)
  init_video
end

def init_video
  # This the default video input, see the test_capture
  # example if it creates an error
  @video = Capture.new(self, width, height)
  # Start capturing the images from the camera
  video.start
  # Create array to store the background image
  @number_of_pixels = video.width * video.height
  @background_pixels = Array.new(number_of_pixels, 0)
  # Make the pixels[] array available for direct manipulation
  load_pixels
end

def capture  # captureEvent does not work like vanilla processing
  @video.read
  background 0
end

def draw
  return unless (video.available == true)
  capture
  video.load_pixels # Make the pixels of video available
  # Difference between the current frame and the stored background
  # current_sum = 0
  number_of_pixels.times do |i| # For each pixel in the video frame...
    # Fetch the current color in that location, and also the color
    # of the background in that spot
    curr_color = video.pixels[i]
    bkgd_color = background_pixels[i]
    # Extract the red, green, and blue components of the current pixel's color
    curr_r = curr_color >> 16 & 0xff
    curr_g = curr_color >> 8 & 0xff
    curr_b = curr_color & 0xff
    # Extract the red, green, and blue of the background pixel's color
    bkgd_r = bkgd_color >> 16 & 0xff
    bkgd_g = bkgd_color >> 8 & 0xff
    bkgd_b = bkgd_color & 0xff
    # Compute the difference of the red, green, and blue values
    diff_r = (curr_r - bkgd_r).abs
    diff_g = (curr_g - bkgd_g).abs
    diff_b = (curr_b - bkgd_b).abs
    # Add these differences to the running tally
    # current_sum += diff_r + diff_g + diff_b
    # Render the difference image to the screen
    pixels[i] = (diff_r << 16) | (diff_g << 8) | diff_b
  end
  update_pixels # Notify that the pixels[] array has changed
  # p current_sum # Print out the total amount of movement
end

def key_pressed
  video.load_pixels
  @background_pixels = video.pixels.clone
end

Sunday, 11 January 2015

A simplified ASCII video capture sketch in ruby processing

In ruby it is often easier to see wood from trees, and code is somewhat self documenting:-
Character placement might be somewhat more regimented in this version, but it saves a heap of push pop matrix calls.
#
# Simplified ASCII Video capture sketch in ruby-processing
# by Martin Prout after a Ben Fry original
#
#
# Text chars have been used to represent images since the earliest computers.
# This sketch is a simple homage that re-interprets live video as ASCII text.
# See the key_pressed function for more options, like changing the font size.
#
load_library :video
include_package 'processing.video'

attr_reader :bright, :char, :cheat_screen, :font, :font_size, :letters, :video

# All ASCII characters, sorted according to their visual density
LETTER_STRING = %q{ .`-_':,;^=+/\"|)\\<>)iv%xclrs{*}I?!][1taeo7zjLunT#JCwfy325Fp6mqSghVd4EgXPGZbYkOA&8U$@KHDBWNMR0Q}
LETTER_ORDER = LETTER_STRING.scan(/./)
def setup
  size(640, 480)
  init_video
  @font_size = 1.5
  @font = load_font(data_path('UniversLTStd-Light-48.vlw'))
  # for the 256 levels of brightness, distribute the letters across
  # the an array of 256 elements to use for the lookup
  @letters = (0...256).map do |i|
    LETTER_ORDER[map1d(i, (0...256), (0...LETTER_ORDER.length))]
  end
  # current brightness for each point
  @bright = Array.new(video.width * video.height, 128)
end

def init_video
  # This the default video input, see the test_capture
  # example if it creates an error
  @video = Capture.new(self, 160, 120)
  # Start capturing the images from the camera
  video.start
  @cheat_screen = false
end

def capture  # captureEvent does not work like vanilla processing
  @video.read
  background 0
end

def draw
  return unless (video.available == true)
  capture
  hgap = width / video.width
  vgap = height / video.height
  scale([hgap, vgap].max * font_size)
  text_font(font, font_size)
  index = 0
  video.load_pixels
  (0...video.height).each do |y|
    # Move down for next line
    (0...video.width).each do |x|
      pixel_color = video.pixels[index]
      # Faster method of calculating r, g, b than red(), green(), blue()
      r = pixel_color >> 16 & 0xff
      g = pixel_color >> 8 & 0xff
      b = pixel_color & 0xff
      # Calculate brightness as luminance:
      # luminance = 0.3*red + 0.59*green + 0.11*blue
      # Or you could instead red + green + blue, and make the the values[] array
      # 256*3 elements long instead of just 256.
      pixel_bright = [0.3 * r, 0.59 * g, 0.11 * b].max
      # The 0.1 value is used to damp the changes so that letters flicker less
      diff = pixel_bright - bright[index]
      bright[index] += diff * 0.1
      fill(pixel_color)
      text(letters[bright[index]], x / font_size, y / font_size)
      # Move to the next pixel
      index += 1
    end
  end
  set(0, height - video.height, video) if cheat_screen
end

MESSAGE = <<-EOS
Controls are:
  g to save_frame, f & F to set font size
  c to toggle cheat screen display
EOS

def key_pressed
  case key
  when 'g' then save_frame
  when 'c' then @cheat_screen = !cheat_screen
  when 'f' then @font_size *= 1.1
  when 'F' then @font_size *= 0.9
  else
    warn MESSAGE
  end
end

Followers

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