Multi Webcam Motion Detector
in
Share your Work
•
2 years ago
This is my first post and my first processing script beyond tinkering with an occasional sample. It's an insignificant contribution compared to some of the treasures created with this marvelous tool; but none the less I felt the need to share it (besides it's nice to save it to the "cloud" even if in just forum post form). I used the script located
here as a starting point, so thank you for the lesson
Daniel.
It is designed to work with as many as nine webcams, but I only have tested it with three (if anyone has a chance to test it with more please let me know the results). It is also designed to support an external text file for properties, and errors if the file isn't found (haven't bothered learning how to error check that). It seems to be a processor hog too, but results have been pleasing. Anyone have a tip on how to remedy that? One last design flaw/misfortune; I couldn't find a quick easy way to have separate windows for each webcam feed and didn't want to bother with creating a dynamic window with each cam in it just yet (maybe in version 2.0 or better yet 10.0), so you simply use the number keys to select between webcam feeds.
It is designed to work with as many as nine webcams, but I only have tested it with three (if anyone has a chance to test it with more please let me know the results). It is also designed to support an external text file for properties, and errors if the file isn't found (haven't bothered learning how to error check that). It seems to be a processor hog too, but results have been pleasing. Anyone have a tip on how to remedy that? One last design flaw/misfortune; I couldn't find a quick easy way to have separate windows for each webcam feed and didn't want to bother with creating a dynamic window with each cam in it just yet (maybe in version 2.0 or better yet 10.0), so you simply use the number keys to select between webcam feeds.
- import processing.video.*;
//Default Properties
float threshold=300;
int picdelay=2000;
int winwidth=640;
int winheight=480;
int startdelay=0;
int cameracount=9;
int nosettings=0;
String cams[]=Capture.list();
int maxcam=cams.length;
//Runtime Vars
int activecam=1;
String activecammsg = "";
int timer;
int today = day();
Capture[] video;
PImage[] prevFrame;
int[] picidx;
void setup() {
size(winwidth,winheight);
_loadproperties(); //Load Properties from text file
if (cameracount>maxcam){
cameracount=maxcam;
}
video = new Capture[cameracount];
prevFrame = new PImage[cameracount];
picidx = new int[cameracount];
for (int x=0;x<cameracount;x++) {
prevFrame[x]=createImage(width,height,RGB); //Create PreviousFrame Bucket for Camera x of y
video[x]=new Capture(this, width, height, 30); //Create Video Capture Object for Camera x of y
if (nosettings==0){
video[x].settings(); //Open Camera Settings Applet for Init
}
}
timer = millis();
frame.setTitle("Webcam Motion Detector - Camera " + activecam + " of " + cameracount);
}
void draw() {
if (startdelay > 0) { //Start Delay
delay(startdelay);
startdelay = 0;
}
for (int i=0;i<cameracount;i++) { //Iterate through cameras
if (video[i].available()) { //If Camera is Not Busy then Capture Previous Frame and New Frame
prevFrame[i].copy(video[i],0,0,video[i].width,video[i].height,0,0,video[i].width,video[i].height); // Before we read the new frame, we always save the previous frame for comparison!
prevFrame[i].updatePixels();
video[i].read();
}
if (i==(activecam-1)) { //Display Active Camera
loadPixels();
}
video[i].loadPixels();
prevFrame[i].loadPixels();
for (int x = 0; x < video[i].width; x ++ ) { //Loop through pixels to detect motion
for (int y = 0; y < video[i].height; y ++ ) {
int loc = x + y*video[i].width;
color current = video[i].pixels[loc];
color previous = prevFrame[i].pixels[loc];
pixels[loc] = current; //Set Display Window Pixels to Current Frame
float r1 = red(current); float g1 = green(current); float b1 = blue(current);
float r2 = red(previous); float g2 = green(previous); float b2 = blue(previous);
float diff = dist(r1,g1,b1,r2,g2,b2); //Color Difference
int milliseconds = (millis() - timer);
if (milliseconds >= picdelay) { //If Past Picture Delay Then Check for Motion
if (diff > threshold) { //If Color Difference is Greater Than Threshold then Save Picture
timer = millis();
int dy = day();
int mn = month();
int yr = year();
int now = dy;
if (today!=now) {
picidx[i]=1; //Increment picture index
}
String file = nf(mn,2);
file += nf(dy,2);
file += nf(yr,2);
file += "\\";
video[i].save(file + "cam" + i + "_" + picidx[i] + ".JPG"); //Save Picture
picidx[i]+=1;
}
}
}
}
if (i==(activecam-1)) { //Display Active Camera
updatePixels();
}
}
}
void keyPressed() { //Camera display Selection via Keyboard Numbers
if ((keyCode>=49)&&(keyCode<=57)){
int var = keyCode-48;
if (var<=cameracount) {
activecam=var;
frame.setTitle("Webcam Motion Detector - Camera " + activecam + " of " + cameracount);
}
}
if (keyCode==27){
_abort();
// key=0;
}
}
void _loadproperties(){ //Read properties from text file
String properties[]=loadStrings("properties.txt");
int arrlen = properties.length;
if (boolean(arrlen)) {
for (int x=0;x<arrlen;x++){
_loadproperty(properties[x]);
}
}
}
void _loadproperty(String prop) { //Set default varible from property
String values[]=split(prop,"=");
int arrlen = values.length;
if (values[0].equals("threshold")==true) {
threshold=float(values[1]);
}
if (values[0].equals("picdelay")==true) {
picdelay=int(values[1]);
}
if (values[0].equals("winwidth")==true) {
winwidth=int(values[1]);
}
if (values[0].equals("winheight")==true) {
winheight=int(values[1]);
}
if (values[0].equals("startdelay")==true) {
startdelay=int(values[1]);
}
if (values[0].equals("cameracount")==true) {
cameracount=int(values[1]);
}
if (values[0].equals("nosettings")==true) {
nosettings=int(values[1]);
}
}
void _abort() {
for (int i=0;i<cameracount;i++) { //Iterate through cameras
delay(picdelay/2);
if (video[i].available()!=true) {
do
{
delay(picdelay/2);
}
while (video[i].available()!=true);
}
video[i].stop();
}
}