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);
}
}
September 14th, 2009 at 2:18 am
Hi, I’m alvin from singapore..this is very interesting,
what sofeware are you using? can change other things? eg: plant, flower?
do you sell them?
September 23rd, 2009 at 10:03 am
Hi Alvin
Currently A Fish this Big is run using Processing. You can substitute the fish images for other things as long as they are .png Currently we are not marketing this as a product but more of an art project but we are always looking for ways to expand this further. You can check out the website for more details. http://www.toobigfora.net for any updates.