Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Webcam Auto-Screensaver

by ailivac (Sexton)
on Sep 17, 2006 at 21:14 UTC ( #573441=CUFP: print w/ replies, xml ) Need Help??

This core of this program takes an set of three images, two references and one test, and classifies the test image as more similar to reference A or reference B. It then uses a loop to poll for new images (from an HTTP server) in real time and run commands when the images changes between the two states. A fun application of this is to monitor a webcam and turn the screensaver on and off depending on whether or not you're sitting in front of your computer. First, a module to summarize an image. This samples pixels at regular intervals and stores the values in an array or arrays:
# ImgSum.pm package ImgSum; use strict; use warnings; use Image::Magick; sub summary { my ($imgf, $res) = @_; my $img = new Image::Magick; $img->Read($imgf); my ($w, $h) = $img->Get(qw/rows columns/); my @sum; my $i = 0; for (my $y = 0; $y < $h; $y += $res) { for (my $x = 0; $x < $w; $x += $res) { my $px = $img->Get("pixel[$x,$y]"); my $rgb = [split/,/, $px]; $sum[$i++] = $rgb; } } return \@sum; } 1;
Next, a script to summarize an image file and store it for later use:
#!/usr/bin/perl # sum.pl use strict; use warnings; use ImgSum; use Data::Dumper; use Storable; my ($img, $res, $out) = @ARGV; # $res is the sampling resolution my $sum = ImgSum::summary($img, $res); store($sum, $out);
The next module takes two image summaries and calculates the average difference between them. It's an incredibly simple algorithm that has numerous shortcomings, but it works in simple situations.
# SumDif.pm package SumDiff; use strict; use warnings; use Data::Dumper; sub mean { my $tt = 0; my $s = 0; while (defined($_ = shift)) { $tt += $_; $s++; } return $tt/$s; } sub diffmap { my ($s1, $s2) = @_; my @diff; foreach my $i(0..$#$s1) { my $c1 = $s1->[$i]; my $c2 = $s2->[$i]; my @d = map { abs($c2->[$_] - $c1->[$_]) } (0..$#$c1); $diff[$i] = mean(@d); } return \@diff; } sub diffavg { return mean(@{diffmap(@_)}); } 1;
Finally, watch.pl downloads images and compares them with two references and runs a command whenever the current image changes from being more like one reference to being more like the other. You can use a program like spook to serve images captured from a webcam.
#!/usr/bin/perl # watch.pl use strict; use warnings; use ImgSum; use LWP::Simple; use SumDiff; use Storable; my @refs = map {retrieve($_)} ('sum-r0.dat', 'sum-r1.dat'); sub min { my $mni = 0; for my $i(0..$#_) { if ($_[$i] < $_[$mni]) { $mni = $i } } return $mni; } sub getclass { my $test = shift; my @diffs; for my $i(0..$#refs) { my $diff = SumDiff::diffavg($refs[$i], $test); $diffs[$i] = $diff; print "Difference to $i: $diff\n"; } return min(@diffs); } my $lc = 1; while (sleep 2) { my $stat = getstore('http://localhost:45005/webcam.jpg', 'current. +jpg'); print "HTTP status: $stat\n"; my $sum = ImgSum::summary('current.jpg', 4); my $cl = getclass($sum); print "Likely class: $cl\n"; if ($lc != $cl) { system('xscreensaver-command ' . ($cl?'-deactivate':'-activate')); $lc = $cl; } }
To use it:
( take a picture of the empty room, save it as ref0.jpg ) $ ./sum.pl ref0.jpg 4 sum-r0.dat ( take a picture of yourself, call it ref1.jpg ) $ ./sum.pl ref1.jpg 4 sum-r1.dat $ ./watch.pl
Now walk in front of and away from the camera slowly and your screensaver will turn on and off.

Comment on Webcam Auto-Screensaver
Select or Download Code

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: CUFP [id://573441]
Approved by chargrill
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (12)
As of 2015-07-06 16:37 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (77 votes), past polls