/* OpenCV bubble popping from Andy Best: http://andybest.net/2009/02/processing-opencv-tutorial-2-bubbles/ RSS Feed from Bruno Nadeau's romeFeeder: http://www.brunonadeau.com/romefeeder/ with some helpful changes from Paul Jebanasam Face detection from http://ubaa.net/shared/processing/opencv/opencv_detect.html */ import hypermedia.video.*; // Imports the OpenCV library import net.obxlabs.romefeeder.*; // romefeeder import com.sun.syndication.feed.synd.*; // ROME import net.nexttext.*; // NextText OpenCV opencv; // Creates a new OpenCV object PImage movementImg; // Creates a new PImage to hold the movement image int poppedBubbles; // Creates a variable to hold the total number of popped bubbles ArrayList bubbles; // Creates an ArrayList to hold the Bubble objects PImage bubblePNG; // Creates a PImage that will hold the image of the bubble PFont font; // Creates a new font object int time; // Create time variable int count = time; // Count variable is equal to time Feeder feeder; // the feeder int feedRate = 2*1000; // rate for displaying posts (in miliseconds) int feedLast = 0; // time of the last displayed post SyndEntry entry; // feed entry Book book; // the book TextObjectGroup txt; // the text object int nextHeight; // Text bounding box variable void setup() { size(640, 480); // Window size 640 x 480 opencv = new OpenCV(this); // Initialises the OpenCV library opencv.capture(width, height); // Sets the capture size to 640 x 480 movementImg = new PImage(width, height); // Initialises the PImage that holds the movement image poppedBubbles = 0; bubbles = new ArrayList(); // Initialises the ArrayList bubblePNG = loadImage("bubble.png"); // Load the bubble image into memory opencv.cascade(OpenCV.CASCADE_FRONTALFACE_ALT); // load the FRONTALFACE description file smooth(); // Anti aliasing nextHeight = 50; // First text bounding box = 50 book = new Book(this); // create the NextText book to handle the text PFont font = createFont("bluehigh.ttf", 12, true); // create and set the font textAlign(CENTER); // Text goes in the middle textFont(font, 42); // set the font size for the entries feeder = new Feeder(); // create the feeder feeder.verbose = true; // turn on output to the console feeder.sort(Feeder.PUBLISHED_DATE); //load entries and sort them by published date. default is unsorted, same as feed order feeder.load("http://feeds.thestranger.com/stranger/slog"); //load the feed feeder.setUpdateInterval(5*60*1000); //set the update interval to check for new posts in the loaded feed(s) in miliseconds feeder.startUpdate(); //start updating } void draw() { opencv.read(); // Captures a frame from the camera opencv.flip(OpenCV.FLIP_HORIZONTAL); // Flips the image horizontally image(opencv.image(), 0, 0); // Draws the camera image to the screen opencv.absDiff(); // Creates a difference image opencv.convert(OpenCV.GRAY); // Converts to greyscale opencv.blur(OpenCV.BLUR, 3); // Blur to remove camera noise opencv.threshold(20); // Thresholds to convert to black and white movementImg = opencv.image(); // Puts the OpenCV buffer into an image object Rectangle[] faces = opencv.detect(); // detect anything ressembling a FRONTALFACE noFill(); // draw detected face area(s) stroke(255,0,0); for(int i=0; i < faces.length; i++) { rect(faces[i].x, faces[i].y, faces[i].width, faces[i].height); } if (mousePressed) { // When the mouse is pressed time = second(); // Time is equal to clock second println(time); // Print clock second if(time > count+3) { // If time is 3 seconds more than count fill(0, 0, 0, 40); // overlay with semi-transparent background to create the shadowy effect for text noStroke(); rect(0, 0, width, height); book.step(); book.draw(); // draw the text // if there is another entry in the feeder and we waited long enough since the last displayed entry then display the next entry if ((feeder.hasNext()) && (millis()-feedLast >= feedRate)) { entry = feeder.next(); println(entry.getTitle()); println(" + " + entry.getPublishedDate() + "\n"); // add the entry title as text fill(250, int(random(190, 220)), 13, 150); stroke(62, 54, 21); txt = book.addText(entry.getTitle(), width/2, nextHeight, 30); float textHeight = txt.getBounds().height; nextHeight += int(textHeight); // update the feed timer feedLast = millis(); } bubbles.add(new Bubble(-bubblePNG.width, (int)random(0, height - 40), bubblePNG.width, bubblePNG.height)); // Adds a new bubble to the array with a random x position for (int i = 0; i < bubbles.size(); i++) { // For every bubble in the bubbles array Bubble _bubble = (Bubble) bubbles.get(i); // Copies the current bubble into a temporary object if (_bubble.update() == 1) { // If the bubble's update function returns '1' bubbles.remove(i); // then remove the bubble from the array _bubble = null; // and make the temporary bubble object null i--; // since we've removed a bubble from the array, we need to subtract 1 from i, or we'll skip the next bubble } else { // If the bubble's update function doesn't return '1' bubbles.set(i, _bubble); // Copys the updated temporary bubble object back into the array _bubble = null; // Makes the temporary bubble object null. } } opencv.remember(OpenCV.SOURCE, OpenCV.FLIP_HORIZONTAL); // Remembers the camera image so we can generate a difference image next frame. Since we've } } } void mouseReleased() { // If mouse button is released if(true) { count = time; // Reset count variable to equal time } }