Catch of the Day from Winslow Porter on Vimeo.
Working with Matt, Winslow, and Meredith, we came up with the idea of using color tracking to help us show off how big of a fish we caught from our “fishing expedition”. Using the code to put a bounding box around an area as a starting point, we substituted the bounding box with various images of fish and than used the distance between our hands to determine the size of our fish (and one killer whale). Look! I caught a fish THIS big!
some major brainstorming session goin’ on here…
and on to our light-setup with our painted green squares.
Some problems we encountered were:
(1) getting our fish to size up or down proportionally;
(2) having our camera correctly track our color (this was solved partially through a more adequate lighting setup and using a brighter, more unusual color);
(3 the reflection off the green color we used;
(4) having our fish be correctly located within our hands.
and last but not least, our code.
import processing.video.*;
Capture video;
PImage fish;
int fish_Width;
int fish_Height;
float targetRed = 0.0; //set some numbers for the target you are chasing
float targetGreen = 0.0;
float targetBlue = 200.0;
int similarityThreshold = 60;
// recording movie: objects and variables
MovieMaker mm;// used for capturing video
boolean winslow = false;
boolean recordingStarted = false;
String title = “CrazyAnimation”;
int s,m,h;
void setup(){
size(640, 480); //give you Processingwindow a size
//imageMode(CENTER);
video = new Capture(this, width, height, 30); //initiate the video, resolution and frame rate
fish = loadImage(”fish/fish_0.png”);
s = second(); // Values from 0 – 59
m = minute(); // Values from 0 – 59
h = hour(); // Values from 0 – 23
println(”Press ‘E’ to enable recording”);
}
void captureEvent(Capture camera)
{
camera.read();
}
void draw(){
Rectangle myRect = null;
for(int row=0; row<video.height; row++) { //for each row
for(int col=0; col<video.width; col++) { //for each column
//get the color of this pixels
//find pixel in linear array using formula: pos = row*rowWidth+column
color pix = video.pixels[row*video.width+col];
//find the difference
int diff = (int) dist(targetRed,targetGreen,targetBlue, red(pix), green(pix), blue(pix));
if (diff < similarityThreshold){
if (myRect == null) myRect = new Rectangle(col,row,1,1); //if this is the first thing you found make a new rect
myRect.add(col,row);
}
}
}
image(video,0,0); //draw the video, this might be optional
fill(255,0,0);
if (myRect != null){
if(myRect.width <= 200)
{
fish = loadImage(”fish/fish_0.png”);
fish_Width = fish.width;
fish_Height = fish.height;
}
else if(myRect.width > 200 && myRect.width <= 300)
{
fish = loadImage(”fish/fish_1.png”);
fish_Width = fish.width;
fish_Height = fish.height;
}
else if(myRect.width > 300 && myRect.width <= 400 )
{
fish = loadImage(”fish/fish_2.png”);
fish_Width = fish.width;
fish_Height = fish.height;
}
else if(myRect.width > 400 && myRect.width <= 500)
{
fish = loadImage(”fish/fish_3.png”);
fish_Width = fish.width;
fish_Height = fish.height;
}
else if(myRect.width > 500)
{
fish = loadImage(”fish/fish_4.png”);
fish_Width = fish.width;
fish_Height = fish.height;
}
fish.resize(myRect.width,((fish_Height * myRect.width)/fish_Width));
image(fish, myRect.x, myRect.y – (fish.height/2));
// rect(myRect.x, myRect.x, myRect.width, myRect.height);
}
if(winslow == true){
mm.addFrame();
}
}
void mousePressed(){
//allow the target color to be changed
color pix = video.pixels[mouseY*video.width+mouseX];
targetRed = red(pix); //get the color of the pixel they clicked on
targetGreen = green(pix);
targetBlue = blue(pix);
}
void keyPressed(){
if (key == ’s’) {// start or stop the record head when the ’s’ is pressed
if( recordingStarted == true ){
if( winslow == true ){
winslow = false;
println( “Cut” );
}
else if( winslow == false ){
winslow = true;
println( “Rolling” );
}
}
else{
println( “Press ‘E’ to enable recording” );
}
}
if ( key == ‘e’ ) {// create new movie for saving
if( recordingStarted == false ){
recordingStarted = true;
// set specific compression and frame rate options, file will be saved in a folder called “movies”
mm = new MovieMaker( this, width, height, “movies/”+title+”_”+h+m+s+”.mov”, 15, MovieMaker.ANIMATION, MovieMaker.HIGH );
println();
println( “Press ‘S’ to start and stop the record head” );
println( “Press ‘X’ to save the movie and exit the sketch” );
}
}
if (key == ‘x’) {// Finish the movie if the ‘x’ is pressed
if(recordingStarted == true){
mm.finish();
if(winslow == true){
println(”Cut”);
}
println(”Print!”);
}
// Quit running the sketch once the file is written
println();
println(”close”);
exit();
}
if (keyCode == 38){
similarityThreshold++;
println(”New Threshold: ” + similarityThreshold);
}
else if (keyCode == 40){
similarityThreshold–;
println(”New Threshold: ” + similarityThreshold);
}
}
So using Eclipse in Processing for the first time is a bit of a confusing experience. First I had to import all the java files in Processing into Eclipse so that they can communicate. After doing the initial setup in Eclipse however, the code hints in Eclipse are great and I can see how this would save me some heartache in the future.
I did some initial pixel manipulations in Eclipse…using some code examples form the Processing book as well as from the class site.
Thinking of some reasons in the REAL world of why you would want to do this, there are a few that come to mind.
(1) CENSORSHIP: there are some things that big brother just doesn’t want you to recognize. that includes bleep words and bleep images. What you can’t see doesn’t exist. right?
(2) CHRISTMAS CARDS: sometimes something with a red and green tint just seems so much more holiday-esque
(3) PARTY PROJECTIONS: pixel manipulations blown up big are cool backgrounds.
(4) SCREENSAVERS: self-explanatory
constructing a machine using legos, we demonstrated the beauty of minimum constraint design.
lego machine 1 from Angela Chen on Vimeo.
lego machine 2 from Angela Chen on Vimeo.
and just in time, this new post from the nytimes from illustrator Christopher Niemann.
A Rube Goldberg type machine that cracks an egg in five steps (energy transfers). Created with team members Adi Marom and Adam Lassy.
Breakfast Machine from Angela Chen on Vimeo.
Working with Adam Havey, we came up with the idea of using your cellphone’s camera to contribute to your universal wishlist: a dynamic list that would be continually updated with photos of items that you see while you are out. Some possible iterations of the wishlist could be:
(a) shopping wishlist
(b) wedding registry
(c) grocery shopping
(d) birthday/anniversary lists
Using Wordpress’ Postie plugin, one can email photos taken with your camera as a post to your Wordpress blog. In refining your wishlist, one could even further narrow and categorize your photos by arranging it by color, location, date added, etc.