Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation

In Search of a Better Mousetrap

by liverpole (Monsignor)
on Dec 31, 2007 at 02:38 UTC ( #659688=CUFP: print w/replies, xml ) Need Help??

"Build a better mousetrap and the world will beat a path to your door." -- attributed to Ralph Waldo Emerson

The problem -- we had mice in our basement.

We'd seen one mouse, and didn't know if there were more.  When the mouse came upstairs briefly, and scared my 4-year-old, I knew it was time to take action.

I bought some old-fashioned traps (with the metal spring), and according to the hardware store salesman's advice, put it inside a box (so they wouldn't approach it from behind, and possibly avoid getting caught).

Within a few days, four traps had disappeared! (one of which was a "glue trap").  I didn't know if it was mice taking them, or some larger animal.  Had they sprung the traps, or gotten stuck and dragged them away?  My curiosity started me thinking, "is there a way I can monitor the traps with Perl?"

The result is the program described here, called "MouseCam".

My requirements for a Perl solution were straightforward.

First, I needed a program (hopefully freeware) to save images to a laptop PC.  (There may be some way to do the same thing with Perl, but I don't know what it is).

I would then write a Perl program that in server mode would deliver those images over the wireless LAN connection.

The client would fetch images once every second, save them all to disk, and display them as often as required.

Mice are nocturnal, so at night when they would most likely be out, nobody would be monitoring, and saving the images would be the only real important action (displaying would not be necessary).  However, the client would have to have a "purge" capability, so as to automatically delete images after a maximum number had accrued, so as to avoid ever filling up the disk).

Finally, the program would need to provide a playback capability.

The freeware image-capture program is called "Fwink" (available here)

It conveniently lets the user save images at a given interval (which in my case is always set to maximum frequency -- 1 second).

It might seem a small thing, but the fact that it saves each image to the same filename means that there's never a danger of using up disk space.

With some experimentation, I've found the best "Text Effect" setting is to have both date and time at the top of the image, with a text size of 28 pixels, and "None" for the "Background Style".

Fwink has worked equally well with both cameras I've used, a Creative, and a Logitech Quickcam Pro 4000.

As the program evolved, several "nice-to-have" features became evident.

Being able to monitor one remote camera was quite impressive, so I considered it would be even nicer to monitor up to four at once.

After playing with the opening "graphic" title screen, and creating some algorithms that nicely compressed it into a much smaller space, I got the idea of extending the idea (primarily to handle more than just 2 colors), and creating icons for each of the playback controls.

One common Perl/Tk control that I haven't had as much need for as much as the others is the "Scale" object.  In this project, I had the perfect chance to implement two of them; one for controlling the exact image, and the other for controlling the playback speed.

During the daytime, though, it would be nice to be able to monitor progress, at longer intervals (eg. once per minute uploads to a webservers).

Another thing I may sometime try to incorporate is an "image-detection" feature.  A couple of times, I've found places during playback where an insect or ladybug walked into camera range, and it would be fun to see if it's possible to reliably track such occurrences.

Once the camera was in place, I got luckier with the mousetraps.

After programming till late in the night, and much of the next day, I got to see the first mouse caught; observing how it approached the trap, lured by the smell of the peanut butter.

Altogether 6 mice were caught in the traps, 4 of which showed up in the "MouseCam" images.  The 2 which weren't recorded were because of human error (mine).  One of them was after a couple of days had passed, and I mistakenly concluded there were no more mice.  The other was because I was working on the program, and didn't expect any mice so early in the evening.

The more mice that were caught, the warier the mice became.  The 6th mouse approached the trap 5 times and appeared to either carefully lick the bait, or at least sniff at it, before finally getting caught on the 6th visit.

Writing "MouseCam" taught me some interesting things.

Unlike many Perl programs, this one has to function efficiently in realtime.

One of the most annoying problems with my program was that it couldn't go for very long without image distortion appearing.  Sometimes the image would only be off by a few pixels, sometimes most of the image was "skewed".  Often the image would have a partial discoloration, for example, it might be red starting part way through the picture.  And on occasion, half of the image or more would be missing.

I was mistaken in thinking the image distortion was caused by failure in transferring over the wireless LAN.  I finally realized it was due to my trying to read the image while another image was overwriting it (via "Fwink").  Once I debugged the problem and found that I could reliably save a copy of the image as soon as the modification time had changed, I never had another distortion problem again.

One major feature that I added late in the game was threads, which I was *sure* would speed up the image transfer.  I thought if the GUI could concentrate on rendering the image locally, and let a worker thread handle the socket transfers, everything would be more responsive.

Surprisingly, this wasn't so -- if anything the latency was worse, or at least the same -- and I soon went back to the original model for the sake of simplicity.

A while back, I had written some Perl code to read XPM images, so this program was a chance to further refine the algorithm for doing image compression for the initial "splash screen".  It was so much fun working on those algorithms that I extended them to handle multiple colors (up to 7), and created graphic "playback" icons.

In conclusion, I never did figure out how or why the mouse took the mousetraps.

Someday, I'm sure I'll find some of them (our basement is still filled with many boxes from our last move).

For now the mice seem to have all been caught.  The next time there are any signs of them in our basement, though, I'll be ready.

There would seem to be lots of potential uses for the MouseCam program.  It could be an inexpensive solution to a number of things; you only need a minimum of two computers (one of them a laptop), with Perl on both, and a wireless LAN, and voila, you've got yourself a home-surveillance system!

The program is available here.  I would post it here (in fact, I did try), but it apparently exceeds the maximum posting length before I realized it.

Update:  I've fixed some bugs, and added some improvements to the code, which I will continue to make available at the same location as above.  It wasn't until I ran it on a new machine that I realized there was an error in the definition of the "starting graphic" (since it's only saved as an XPM once, and thereafter read from disk).  It should now work in "client mode" on both Windows and Linux.  (In "server mode", it currently only runs on Windows).


Replies are listed 'Best First'.
Re: In Search of a Better Mousetrap
by ikegami (Pope) on Dec 31, 2007 at 03:43 UTC
    The code, hosted on PerlMonks. It just fits in a post on its own.
Re: In Search of a Better Mousetrap
by liverpole (Monsignor) on Dec 31, 2007 at 16:41 UTC
    Lots of great comments here!

    At Gavin's suggestion I just now posted two sets of pictures, those of the first mouse caught and the sixth mouse caught.  Warning -- the images are graphic; please don't view them if it bothers you to see a mouse killed!

    I didn't take the time to create the HTML to view it as a movie, so you have to single-step through it.  If you're so inclined, you can always save the images locally, and then view them with the MouseCam program.

    I didn't bother with mouse2 (which was only a single image, since when I caught it, I'd inadvertently set the maximum save to 7200 images (ie. 2 hours' worth), and thus didn't have any "live" shots of the mouse, if you'll forgive the pun).  I also have the "mouse4" sequence, which is fairly short; that mouse wasn't as careful as "mouse6" is, as I mentioned in the OP.

    shmem, you're right, I was interested in "how" they were stealing the traps (which I never did find out).  Someday, I may have more evidence, if the traps ever appear ...

    zentara, I'll take a look at your program.  I did think of using motion-detection, but I didn't have the time to try writing the algorithms, as I wanted to start catching mice as soon as I could.  (I also didn't mind saving all images, since it guaranteed I wouldn't miss any, and my "purge" algorithm worked fine anyway).  As for a light source, I had a lamp continually on in the basement, so the image would always have some light during nighttime hours.

    And kyle, you may be right, but fortunately I'm not squeamish about disposing of the mice (although my wife is a different story).  I've gotten lots of good information from people, and found that the common wisdom is correct -- the mice are the most happy with good ol' peanut butter.  I've also heard (though not tried it yet), that they enjoy a fatty piece of bacon.

      I was interested in "how" they were stealing the traps (which I never did find out.

      From my years of experience of winter camping ( and dealing with mice stealing food and socks from my floorless tipi), I can attest to the strength and survival drive of mice. Your trap's disappearance was probably caused by mice that were caught( but not only a foot caught), dragging them off to a safe location. Or else, you also have an infestation of the dreaded "giant New York cockroach"..... in that case...... move. :-)

      I'm not really a human, but I play one on earth. Cogito ergo sum a bum
Re: In Search of a Better Mousetrap
by McDarren (Abbot) on Dec 31, 2007 at 10:20 UTC
    You know, it was only yesterday that I noticed that you had not logged into PM for a while, and I started to wonder whether you had deserted us....

    Never in a million years would I have guessed that you've been busy in the basement all this time, chasing mice...

Re: In Search of a Better Mousetrap
by zentara (Archbishop) on Dec 31, 2007 at 14:39 UTC
    MouseTrap 2.0 is in the works. :-) I might try to use a motion capture program instead of a timed capture. I've been using a capture program called 'mvc' written by someone called Merlin. Sorry but the links to it seem to be broken, but the program works great. It detects motion, and takes a snapshot. It needs light though, unless you have a cool night vision camera. It won't take a picture, unless motion (or a light change) is detected.

    I put a copy at mvc-0.8.9

    I'm not really a human, but I play one on earth. Cogito ergo sum a bum
      You can probably do night vision monitoring with your current camera using little additional hardware. Most CCDs are actually quite sensitive to IR light, which is invisible to both human and mouse eyes. The only thing to watch out for is that some cameras have a physical IR filter over the lens (which can usually be removed with little fuss).

      Wire up a few IR LEDs or even an IR spotlight and the camera should pick up the full scene, day or night. It would be interesting to see how well mvc works in such a setup.

Re: In Search of a Better Mousetrap
by kyle (Abbot) on Dec 31, 2007 at 15:57 UTC

    Not Perl related, but mouse related...

    I notice that mouse traps increase in price the more humane you are and the more squeamish you are. The "drive them out without ever seeing them" is the most expensive. Live traps are more expensive than death traps. Covered death traps you can empty without ever seeing the mouse are more expensive than the old spring on the plank death traps. Etc.

    We tried live traps and death traps when we had mice. Baited live traps worked really well. Baited death traps would have the bait stolen and the trap left untriggered. The only use I found for the death traps was to leave them in any path I'd seen a mouse take (without bait). On their way to or from, they'd just walk over them and die.

    Good luck.

Re: In Search of a Better Mousetrap
by shmem (Canon) on Dec 31, 2007 at 13:24 UTC
    Within a few days, four traps had disappeared!

    That is the mystery I thought you were to solve monitoring the traps, instead of getting pictures of mouse executions..


    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
Re: In Search of a Better Mousetrap
by Gavin (Chancellor) on Dec 31, 2007 at 13:18 UTC
    ++ Fantastic liverpole

    But where's the link to "THE MOVIE" "The Moustrap"?
    We want to see them mices caught!
Re: In Search of a Better Mousetrap
by nimdokk (Vicar) on Dec 31, 2007 at 15:04 UTC
    Having recently dealt with mice, I found that a little device you plug into a wall socket that emits a tone that mice can hear and it drives them out of the walls (doesn't effect pets). It really seems to do the trick. I know it's not Perl-related but it is techy/geeky (electronic device) and it appears to be effective (haven't seen more mice since it was put in). Our two dogs and cat haven't indicated any more mice either :-)
Re: In Search of a Better Mousetrap
by sundialsvc4 (Abbot) on Jan 08, 2008 at 17:59 UTC

    A Java-programmer would have gotten a cat, instead.

      "A Java-programmer would have gotten a cat, instead."

      You mean a Tiger or perhaps here!
Re: In Search of a Better Mousetrap
by Anonymous Monk on Dec 31, 2007 at 14:06 UTC
    did you find their entry point? nest? Next time you should try the bucket method (bucket, water, sticks, peanutbutter, slippery bridge)
Re: In Search of a Better Mousetrap
by spx2 (Deacon) on Jan 12, 2008 at 17:34 UTC
    Absolutely fantastic!
    It was an entertaining read and also very interesting application of perl.
    "In conclusion, I never did figure out how or why the mouse took the mousetraps." -- the journey is more important than the destination :)
      I havent tried it yet , but yes its a very intresting read

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: CUFP [id://659688]
Approved by ikegami
Front-paged by derby
[shmem]: wait, what? you want that person to read the documentation for you?
[Lady_Aleena]: I might have to go with options instead of a straight list.
[Discipulus]: if more than 3 go for named variables LA
[Lady_Aleena]: Discipulus, it is at 2 now, but with what I am thinking about, it could go to 3. However, only 1 is needed. The second and third are optional.
[shmem]: straight list or named parameters - that depends on whether (and how many) optional arguments you have
[Discipulus]: if so a plain list is ok, imho
[Lady_Aleena]: shmem, I already have the plugin installed, just not active.
[shmem]: if you have 1 optional argument, place that at the end of the list. If you have more, go for named parameters.
[Lady_Aleena]: 1 manditory, 2 optional.
[Discipulus]: my ($need,$opta,$optb ) = @_; .. if $opta..

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (12)
As of 2017-04-27 12:19 GMT
Find Nodes?
    Voting Booth?
    I'm a fool:

    Results (506 votes). Check out past polls.