In this recitation, we worked on our exploring physical controllers to modify the way media is being shown. The type of media I chose was video. I built a circuit with Arduino using a potentiometer. The potentiometer would theoretically change the camera and apply a filter when inputted a specific value. The filter I chose was called time displacement, which warped the camera and made the movements lag behind, creating a weird visual.
After creating the circuit, I used an example code in processing to activate the webcam on my camera.
I then found the Time displacement code in example filters and merged it with the receive single value code and webcam code. The Arduino code was basic and just send a single value from the potentiometer. The send single value code was modified to print the potentiometer’s sensor value so processing knew which specific value it had to read to then activate the filter.
Arduino Code:
#include "SerialRecord.h"
// Change this number to send a different number of values
SerialRecord writer(1);
void setup() {
Serial.begin(9600);
}
void loop() {
int sensorValue = analogRead(0);
writer[0] = sensorValue;
writer.send();
Serial.print(sensorValue);
// This delay slows down the loop, so that it runs less frequently. This
// prevents it from sending data faster than a Processing sketch that runs at
// 60 frames per second will process it. It also makes it easier to debug the
// sketch, because values are received at a slower rate.
delay(20);
}
import processing.video.*;
import processing.serial.*;
import osteele.processing.SerialRecord.*;
String[] cameras = Capture.list();
Capture cam;
Serial serialPort;
SerialRecord serialRecord;
Capture video;
int signal = 0;
//the buffer for storing video frames
ArrayList frames = new ArrayList();
void setup() {
size(640, 480);
printArray(cameras);
cam = new Capture(this, 640, 480, cameras[0]); // use if camera trouble: cam = new Capture(this, 640, 480, cameras[0],30);
cam.start();
// This the default video input, see the GettingStartedCapture
// example if it creates an error
video = new Capture(this, width, height);
// Start capturing the images from the camera
video.start();
String serialPortName = SerialUtils.findArduinoPort();
serialPort = new Serial(this, serialPortName, 9600);
serialRecord = new SerialRecord(this, serialPort, 1);
}
void captureEvent(Capture camera) {
camera.read();
// Copy the current video frame into an image, so it can be stored in the buffer
PImage img = createImage(width, height, RGB);
video.loadPixels();
arrayCopy(video.pixels, img.pixels);
frames.add(img);
// Once there are enough frames, remove the oldest one when adding a new one
if (frames.size() > height/4) {
frames.remove(0);
}
}
void draw() {
background(0);
serialRecord.read();
int value = serialRecord.get();
if (value > 500000) {
int currentImage = 0;
loadPixels();
// Begin a loop for displaying pixel rows of 4 pixels height
for (int y = 0; y < video.height; y+=4) {
// Go through the frame buffer and pick an image, starting with the oldest one
if (currentImage < frames.size()) {
PImage img = (PImage)frames.get(currentImage);
if (img != null) {
img.loadPixels();
// Put 4 rows of pixels on the screen
for (int x = 0; x < video.width; x++) {
pixels[x + y * width] = img.pixels[x + y * video.width];
pixels[x + (y + 1) * width] = img.pixels[x + (y + 1) * video.width];
pixels[x + (y + 2) * width] = img.pixels[x + (y + 2) * video.width];
pixels[x + (y + 3) * width] = img.pixels[x + (y + 3) * video.width];
}
}
// Increase the image counter
currentImage++;
} else {
break;
}
}
updatePixels();
} else {
if (cam.available()) {
cam.read();
}
image(cam, 0, 0);
}
float a = map(value, 0, 1024, 0, height);
line(a, 0, a, height);
// Set the image counter to 0
// For recording an image sequence
//saveFrame("frame-####.jpg");
}
This recitation was a success as I was able to use a physical controller, the potentiometer, to control my video.
Leave a Reply