Image

Final Project – Shadowbox (aka Mystery Box) – Kevin Desautels, Dennis MacAvaney, Kierra Thomas

19 Dec

Final Project - Shadowbox (aka Mystery Box) -  Kevin Desautels, Dennis MacAvaney, Kierra Thomas

Shadowbox is an installation that manipulates shadows. It works best in a dark room with a single light source. The goal of this project was to produce a fun, interactive piece that is both reactive and somewhat unpredictable (to add interest).
The Box contains an Arduino, a webcam, 2 potentiometers, and has a frosted plastic screen on which to cast shadows. The frosted plastic aids the processing script in blob detection by filtering out color. One potentiometer controls the color of the projection, and one controls the shakiness of the edges drawn. The arduino then relays the raw information to a laptop, which runs a processing script. The processing script captures video frames from the webcam, and attempts to draw the edges of the shadows it views from the inside of the plastic screen, and then draw lines from the center of the blobs to the outer edge (to act as a fill).
Because of the roughness of the blobs detected by the processing code, the projected image is abstract and interacts somewhat unpredictably. Shadowbox is a good proof of the concept, but could use streamlining and more accurate interpretations of the shadows. This would help to produce a more consistently reactive and abstract result. More controls could be added to give the user more options.

ARDUINO CODE:

int colorPot=0;//determines color in Processing (float Color)
int weirdPot=0;//determines shaky-ness of edges (float Weird)

void setup(){
Serial.begin(9600);
}

void loop(){
colorPot=analogRead(A0);
weirdPot=(analogRead(A1)+9000);//adds 9000 to variable to differentiate from colorPot
colorPot=map(colorPot,510,1023,0,510);
Serial.println (colorPot);
delay(50);//for stability
Serial.println (weirdPot);
delay(50);
}

PROCESSING CODE:

import processing.video.*;
import blobDetection.*;
import processing.serial.*;

Capture cam;
BlobDetection theBlobDetection;
PImage img;
boolean newFrame=false;
Serial myPort;
float Temp=0;
float Color=0;
float Weird=0;

// ================================================== setup()
void setup()
{
println(Serial.list());//Select serial port
myPort = new Serial(this, Serial.list()[3], 9600);
size(640, 480);
String[] cameras = Capture.list(); //Select camera
if (cameras.length == 0) {
println(“There are no cameras available for capture.”);
exit();
} else {
println(“Available cameras:”);
for (int i = 0; i < cameras.length; i++) {
println(cameras[i]);
}
cam = new Capture(this, cameras[3]); //iSight
//cam = new Capture(this, cameras[15]); //webcam
cam.start();
}
// BlobDetection
// img which will be sent to detection (a smaller copy of the cam frame);
img = new PImage(80,60);
theBlobDetection = new BlobDetection(img.width, img.height);
theBlobDetection.setPosDiscrimination(false);//"true" makes blobs favor bright areas, mostly works
theBlobDetection.setThreshold(0.8f); //detection threshold
}

// ================================================== captureEvent()
void captureEvent(Capture cam)
{
cam.read();
newFrame = true;
}

// ================================================== draw()
void draw()
{
if (newFrame)
{
newFrame=false;
background(0, 255); //background color
img.copy(cam, 0, 0, cam.width, cam.height,
0, 0, img.width, img.height);
fastblur(img, 2);
theBlobDetection.computeBlobs(img.pixels);
drawBlobsAndEdges(false,true);
}
}

// ================================================== drawBlobsAndEdges()
void drawBlobsAndEdges(boolean drawBlobs, boolean drawEdges)
{
noFill();
Blob b;
EdgeVertex eA,eB,vA,vB;

Temp=0;
String inString=myPort.readString();//Read from serial port

if(inString!=null){
inString = trim(inString);
Temp = float(inString);

if(Temp<9000){//filter out colorPot value, set = float Color
Color=Temp;
}else{//filter out weirdPot value, set = float Weird
Weird=(Temp-9000);
Weird=map(Weird,550,1023,0,.02);
if(Weird<0){
Weird=0;}
println(Weird);
}
}else{
Temp=0;
}

for (int n=0 ; n<theBlobDetection.getBlobNb() ; n++)//blob-scanning
{
b=theBlobDetection.getBlob(n);
if (b != null)
{
if (drawEdges)//Edges
{
//====================================color scrolling
float R=0;
float G=0;
float B=0;
if(Color255){
B=(Color-255);
}else{
B=0;}
G=(255-R-B); //R+G+B = 256

strokeWeight(5);
stroke(R,G,B);
for (int m=0;m 0){
eB.x += random(-Weird,Weird);//adds random value to edge endpoint based on float Weird
eB.y += random(-Weird,Weird);
}
if (eA !=null && eB !=null){
line(
eA.x*width, eA.y*height,
eB.x*width, eB.y*height);
line(
b.x*width, b.y*height,
eB.x*width, eB.y*height);
}
}
}//end edge drawing
}
}//end blob-scanning loop
}
// The following code is unneccesary, but adds stability to edges
// Super Fast Blur v1.1
// by Mario Klingemann
//
// ==================================================
void fastblur(PImage img,int radius)
{
if (radius<1){
return;
}
int w=img.width;
int h=img.height;
int wm=w-1;
int hm=h-1;
int wh=w*h;
int div=radius+radius+1;
int r[]=new int[wh];
int g[]=new int[wh];
int b[]=new int[wh];
int rsum,gsum,bsum,x,y,i,p,p1,p2,yp,yi,yw;
int vmin[] = new int[max(w,h)];
int vmax[] = new int[max(w,h)];
int[] pix=img.pixels;
int dv[]=new int[256*div];
for (i=0;i<256*div;i++){
dv[i]=(i/div);
}

yw=yi=0;

for (y=0;y<h;y++){
rsum=gsum=bsum=0;
for(i=-radius;i>16;
gsum+=(p & 0x00ff00)>>8;
bsum+= p & 0x0000ff;
}
for (x=0;x>16;
gsum+=((p1 & 0x00ff00)-(p2 & 0x00ff00))>>8;
bsum+= (p1 & 0x0000ff)-(p2 & 0x0000ff);
yi++;
}
yw+=w;
}

for (x=0;x<w;x++){
rsum=gsum=bsum=0;
yp=-radius*w;
for(i=-radius;i<=radius;i++){
yi=max(0,yp)+x;
rsum+=r[yi];
gsum+=g[yi];
bsum+=b[yi];
yp+=w;
}
yi=x;
for (y=0;y<h;y++){
pix[yi]=0xff000000 | (dv[rsum]<<16) | (dv[gsum]<<8) | dv[bsum];
if(x==0){
vmin[y]=min(y+radius+1,hm)*w;
vmax[y]=max(y-radius,0)*w;
}
p1=x+vmin[y];
p2=x+vmax[y];

rsum+=r[p1]-r[p2];
gsum+=g[p1]-g[p2];
bsum+=b[p1]-b[p2];

yi+=w;
}
}
}

Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s