Shallow Thoughts : tags : crittercam
Akkana's Musings on Open Source Computing and Technology, Science, and Nature.
Mon, 22 Dec 2014
I'm working on my Raspberry Pi crittercam again. I got a battery, so
it can be a standalone box -- it was such a hassle to set it up with
two power cords dangling from it at all times -- and set it up to run
automatically at boot time.
But there was one aspect of the camera that wasn't automated: if close
enough to the house to see the wi-fi router, I want it to mount a
filesystem from our server and store its image files there. That
makes it a lot easier to check on its progress, and also saves wear
on the Pi's SD card.
Only one problem: I was using sshfs to mount the disk remotely, and
ssh always prompts me for a password.
Now, there are a gazillion tutorials on how to set up an ssh key.
Just do a web search for ssh key
or
passwordless ssh key
. They vary a bit in their details,
but they're all the same in the important aspects. They're all the
same in one other detail: none of them work for me. I generate a new
key (various types) with no pass phrase, I copy it to the server's
authorized keys file (several different ways, two possible filenames),
I try to ssh -- and I'm prompted for a password.
After much flailing I finally found out what was missing.
In addition to those two steps, you need to modify your
.ssh/config file to tell it which key to use.
This is especially critical if you have multiple keys on the client
machine, or if you've named the file anything but the default id_dsa
or id_rsa.
So here are the real steps for making an ssh key.
Assume the server, the machine to which you want to ssh,
is named "myserver". But these steps are all run on the client
machine, the one from which you want to run ssh.
ssh-keygen -t rsa -C "Comment"
When it prompts you for a filename, give it a full pathname,
e.g.
~/.ssh/id_rsa_myserver.
Type in a pass phrase, or hit return twice if you want to be able to
ssh without a password.
Update May 2016: this now fails with
Saving key ~/.ssh/id_rsa_myserver failed: No such file or directory
(duh, of course the file doesn't exist, I'm asking you to create it).
To get around this, specify the file on the command line:
ssh-keygen -t rsa -C "Comment" -f ~/.ssh/id_rsa_myserver
Update, April 2018: Do use RSA: DSA keys have now been deprecated.
If you make a DSA rather than an RSA key, ssh will just ignore it
and prompt you for a login password. No helpful error message or anything
explaining why it's ignored.
Now copy your key to the remote machine:
ssh-copy-id -i .ssh/id_rsa_myserver user@myserver
You can omit the
user@ if you're using the same username on
both machines. You'll have to type in your password on myserver.
Then on the local machine,
edit ~/.ssh/config, and add an entry like this:
Host myserver
User my_username
IdentityFile ~/.ssh/id_rsa_myserver
The User line is optional, and refers to your username on myserver
if it's different from the one on the client. For instance, on the
Raspberry Pi, everything has to run as root because most of the
hardware and camera libraries can't work any other way. But I
want it using my user ID on the server side, not root.
Update July 2021: You may need one more step. Keyed ssh will fail
silently if it doesn't like the permissions in the .ssh/ directory.
If it's still prompting you for a password, try, on the remote server:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
Eliminating strict host key checking
Of course, you can use this to go the other way too, and ssh to your Pi
without needing to type a password every time. If you do that, and if
you have several Pis, Beaglebones, plug computers or other little
Linux gizmos which sometimes share the same IP address, you may run
into the annoying whine ssh is prone to:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
The only way to get around this once it happens is by editing
~/.ssh/known_hosts, finding the line corresponding to the pi,
and removing it (or just removing the whole file).
You're supposed to be able to turn off this check with
StrictHostKeyChecking no
, but it doesn't work.
Fortunately, there's a trick I discovered several years ago
and discussed in
Three SSH tips.
Here's how the Pi entry ends up looking in my desktop's
~/.ssh/config:
Host pipi
HostName pi
User pi
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
IdentityFile ~/.ssh/id_pi
Tags: ssh, linux, raspberry pi, crittercam, security, maker
[
16:25 Dec 22, 2014
More linux |
permalink to this entry |
]
Mon, 22 Sep 2014
I had the opportunity to borrow a commercial crittercam
for a week from the local wildlife center.
Having grown frustrated with the high number of false positives on my
Raspberry Pi based
crittercam, I was looking forward to see how a commercial camera compared.
The Bushnell Trophycam I borrowed is a nicely compact,
waterproof unit, meant to strap to a tree or similar object.
It has an 8-megapixel camera that records photos to the SD card -- no
wi-fi. (I believe there are more expensive models that offer wi-fi.)
The camera captures IR as well as visible light, like the PiCam NoIR,
and there's an IR LED illuminator (quite a bit stronger than the cheap
one I bought for my crittercam) as well as what looks like a passive IR sensor.
I know the TrophyCam isn't immune to false positives; I've heard
complaints along those lines from a student who's using them to do
wildlife monitoring for LANL.
But how would it compare with my homebuilt crittercam?
I put out the TrophyCam first night, with bait (sunflower seeds) in
front of the camera. In the morning I had ... nothing. No false
positives, but no critters either. I did have some shots of myself,
walking away from it after setting it up, walking up to it to adjust
it after it got dark, and some sideways shots while I fiddled with the
latches trying to turn it off in the morning, so I know it was
working. But no woodrats -- and I always catch a woodrat or two
in PiCritterCam runs. Besides, the seeds I'd put out were gone,
so somebody had definitely been by during the night. Obviously
I needed a more sensitive setting.
I fiddled with the options, changed the sensitivity from automatic
to the most sensitive setting, and set it out for a second night, side
by side with my Pi Crittercam. This time it did a little better,
though not by much: one nighttime shot with a something in it,
plus one shot of someone's furry back and two shots of a mourning dove
after sunrise.
What few nighttime shots there were were mostly so blown out you
couldn't see any detail to be sure. Doesn't this camera know how to
adjust its exposure? The shot here has a creature in it. See it?
I didn't either, at first. It's just to the right of the bush.
You can just see the curve of its back and the beginning of a tail.
Meanwhile, the Pi cam sitting next to it caught eight reasonably exposed
nocturnal woodrat shots and two dove shots after dawn.
And 369 false positives where a leaf had moved in the wind or a dawn
shadow was marching across the ground. The TrophyCam only shot 47
photos total: 24 were of me, fiddling with the camera setup to get
them both pointing in the right direction, leaving 20 false positives.
So the Bushnell, clearly, gives you fewer false positives to hunt
through -- but you're also a lot less likely to catch an actual critter.
It also doesn't deal well with exposures in small areas and close distances:
its IR light source seems to be too bright for the camera to cope with.
I'm guessing, based on the name, that it's designed for shooting
deer walking by fifty feet away, not woodrats at a two-foot distance.
Okay, so let's see what the camera can do in a larger space. The next
two nights I set it up in large open areas to see what walked by. The
first night it caught four rabbit shots that night, with only five
false positives. The quality wasn't great, though: all long exposures
of blurred bunnies. The second night it caught nothing at all
overnight, but three rabbit shots the next morning. No false positives.
The final night, I strapped it to a piñon tree facing a little
clearing in the woods. Only two morning rabbits, but during the night
it caught a coyote. And only 5 false positives. I've never caught a
coyote (or anything else larger than a rabbit) with the PiCam.
So I'm not sure what to think. It's certainly a lot more relaxing to
go through the minimal output of the TrophyCam to see what I caught.
And it's certainly a lot easier to set up, and more waterproof, than
my jury-rigged milk carton setup with its two AC cords, one for the Pi
and one for the IR sensor. Being self-contained and battery operated
makes it easy to set up anywhere, not just near a power plug.
But it's made me rethink my pessimistic notion that I should give up
on this homemade PiCam setup and buy a commercial camera.
Even on its most sensitive setting, I can't make the TrophyCam
sensitive enough to catch small animals.
And the PiCam gets better picture quality than the Bushnell, not to
mention the option of hooking up a separate camera with flash.
So I guess I can't give up on the Pi setup yet. I just have to come up
with a sensible way of taming the false positives. I've been doing a lot
of experimenting with SimpleCV image processing, but alas, it's no better
at detecting actual critters than my simple pixel-counting script was.
But maybe I'll find the answer, one of these days. Meanwhile, I may
look into battery power.
Tags: crittercam, nature, raspberry pi, photography, maker
[
14:29 Sep 22, 2014
More hardware |
permalink to this entry |
]
Thu, 03 Jul 2014
In my last crittercam installment,
the
NoIR night-vision crittercam, I was having trouble with false positives,
where the camera would trigger repeatedly after dawn as leaves moved
in the wind and the morning shadows marched across the camera's field of view.
I wondered if a passive infra-red (PIR) sensor would be the answer.
I got one, and the answer is: no. It was very easy to hook up, and
didn't cost much, so it was a worthwhile experiment; but it gets
nearly as many false positives as camera-based motion detection.
It isn't as sensitive to wind, but as the ground and the foliage heat
up at dawn, the moving shadows are just as much a problem as they were
with image-based motion detection.
Still, I might be able to combine the two, so I figure it's worth
writing up.
Reading inputs from the HC-SR501 PIR sensor
The PIR sensor I chose was the common HC-SR501 module.
It has three pins -- Vcc, ground, and signal -- and two potentiometer
adjustments.
It's easy to hook up to a Raspberry Pi because it can take 5 volts
in on its Vcc pin, but its signal is 3.3v (a digital signal -- either
motion is detected or it isn't), so you don't have to fool with
voltage dividers or other means to get a 5v signal down to the 3v
the Pi can handle.
I used GPIO pin 7 for signal, because it's right on the corner of the
Pi's GPIO header and easy to find.
There are two ways to track a digital signal like this. Either you can
poll the pin in an infinfte loop:
import time
import RPi.GPIO as GPIO
pir_pin = 7
sleeptime = 1
GPIO.setmode(GPIO.BCM)
GPIO.setup(pir_pin, GPIO.IN)
while True:
if GPIO.input(pir_pin):
print "Motion detected!"
time.sleep(sleeptime)
or you can use interrupts: tell the Pi to call a function whenever it
sees a low-to-high transition on a pin:
import time
import RPi.GPIO as GPIO
pir_pin = 7
sleeptime = 300
def motion_detected(pir_pin):
print "Motion Detected!"
GPIO.setmode(GPIO.BCM)
GPIO.setup(pir_pin, GPIO.IN)
GPIO.add_event_detect(pir_pin, GPIO.RISING, callback=motion_detected)
while True:
print "Sleeping for %d sec" % sleeptime
time.sleep(sleeptime)
Obviously the second method is more efficient. But I already had a
loop set up checking the camera output and comparing it against
previous output, so I tried that method first, adding support to my
motion_detect.py
script. I set up the camera pointing at the wall, and, as root, ran the script
telling it to use a PIR sensor on pin 7, and the local and remote
directories to store photos:
# python motion_detect.py -p 7 /tmp ~pi/shared/snapshots/
and whenever I walked in front of the camera, it triggered and took
a photo. That was easy!
Reliability problems with add_event_detect
So easy that I decided to switch to the more efficient interrupt-driven
model. Writing the code was easy, but I found it triggered more often:
if I walked in front of the camera (and stayed the requisite 7 seconds
or so that it takes raspistill to get around to taking a photo),
when I walked back to my desk, I would find two photos, one showing my
feet and the other showing nothing. It seemed like it was triggering
when I got there, but also when I left the scene.
A bit of web searching indicates this is fairly common: that with RPi.GPIO
a lot of people see triggers on both rising and falling edges -- e.g. when
the PIR sensor starts seeing motion, and when it stops seeing motion
and goes back to its neutral state -- when they've asked for just
GPIO.RISING. Reports for this go back to 2011.
On the other hand, it's also possible that instead of seeing a GPIO
falling edge, what was happening was that I was getting multiple calls
to my function while I was standing there, even though the RPi hadn't
finished processing the first image yet. To guard against that, I put
a line at the beginning of my callback function that disabled further
callbacks, then I re-enabled them at the end of the function after the
Pi had finished copying the photo to the remote filesystem. That reduced
the false triggers, but didn't eliminate them entirely.
Oh, well, The sun was getting low by this point, so I stopped
fiddling with the code and put the camera out in the yard with a pile
of birdseed and peanut suet nuggets in front of it. I powered on,
sshed to the Pi and ran the motion_detect script, came back inside
and ran a tail -f on the output file.
I had dinner and worked on other things, occasionally checking the
output -- nothing! Finally I sshed to the Pi and ran ps aux
and discovered the script was no longer running.
I started it again, this time keeping my connection to the Pi active
so I could see when the script died. Then I went outside to check the
hardware. Most of the peanut suet nuggets were gone -- animals had
definitely been by. I waved my hands in front of the camera a few
times to make sure it got some triggers.
Came back inside -- to discover that Python had gotten a segmentation
fault. It turns out that nifty GPIO.add_event_detect() code isn't all
that reliable, and can cause Python to crash and dump core. I ran it
a few more times and sure enough, it crashed pretty quickly every time.
Apparently GPIO.add_event_detect
needs a bit more debugging,
and isn't safe to use in a program that has to run unattended.
Back to polling
Bummer! Fortunately, I had saved the polling version of my program, so
I hastily copied that back to the Pi and started things up again.
I triggered it a few times with my hand, and everything worked fine.
In fact, it ran all night and through the morning, with no problems
except the excessive number of false positives, already mentioned.
False positives weren't a problem at all during the night. I'm fairly
sure the problem happens when the sun starts hitting the ground. Then
there's a hot spot that marches along the ground, changing position in
a way that's all too obvious to the infra-red sensor.
I may try cross-checking between the PIR sensor and image changes from
the camera. But I'm not optimistic about that working: they both get
the most false positives at the same times, at dawn and dusk when the
shadow angle is changing rapidly. I suspect I'll have to find a
smarter solution, doing some image processing on the images as well
as cross-checking with the PIR sensor.
I've been uploading photos from my various tests here:
Tests of the
Raspberry Pi Night Vision Crittercam.
And as always, the code is on
github:
scripts/motioncam with some basic documentation on my site:
motion-detect.py:
a motion sensitive camera for Raspberry Pi or other Linux machines.
(I can't use github for the documentation because I can't seem to find
a way to get github to display html as anything other than source code.)
Tags: crittercam, hardware, raspberry pi, nature, photography, maker
[
20:13 Jul 03, 2014
More hardware |
permalink to this entry |
]
Thu, 26 Jun 2014
When I built my
http://shallowsky.com/blog/hardware/raspberry-pi-motion-camera.html
(and part
2), I always had the NoIR camera in the back of my mind. The NoIR is a
version of the Pi camera module with the infra-red blocking
filter removed, so you can shoot IR photos at night without disturbing
nocturnal wildlife (or alerting nocturnal burglars, if that's your target).
After I got the daylight version of the camera working, I ordered a NoIR
camera module and plugged it in to my RPi. I snapped some daylight
photos with raspstill and verified that it was connected and working;
then I waited for nightfall.
In the dark, I set up the camera and put my cup of hot chocolate in
front of it. Nothing. I hadn't realized that although CCD
cameras are sensitive in the near IR, the wavelengths only slightly
longer than visible light, they aren't sensitive anywhere near
the IR wavelengths that hot objects emit. For that, you need a special
thermal camera. For a near-IR CCD camera like the Pi NoIR, you need an
IR light source.
Knowing nothing about IR light sources, I did a search and came up
with something called a
"Infrared IR 12 Led Illuminator Board Plate for CCTV Security CCD Camera"
for about $5. It seemed similar to the light sources used on a few
pages I'd found for home-made night vision cameras, so I ordered it.
Then I waited, because I stupidly didn't notice until a week and a half
later that it was coming from China and wouldn't arrive for three weeks.
Always check the shipping time when ordering hardware!
When it finally arrived, it had a tiny 2-pin connector that I couldn't
match locally. In the end I bought a package of female-female SchmartBoard
jumpers at Radio Shack which were small enough to make decent contact
on the light's tiny-gauge power and ground pins.
I soldered up a connector that would let me use a a universal power
supply, taking a guess that it wanted 12 volts (most of the cheap LED
rings for CCD cameras seem to be 12V, though this one came with no
documentation at all). I was ready to test.
Testing the IR light
One problem with buying a cheap IR light with no documentation:
how do you tell if your power supply is working? Since the light is
completely invisible.
The only way to find out was to check on the Pi. I didn't want to have
to run back and forth between the dark room where the camera was set
up and the desktop where I was viewing raspistill images. So I
started a video stream on the RPi:
$ raspivid -o - -t 9999999 -w 800 -h 600 | cvlc -vvv stream:///dev/stdin --sout '#rtp{sdp=rtsp://:8554/}' :demux=h264
Then, on the desktop: I ran vlc, and opened the network stream:
rtsp://pi:8554/
(I have a "pi" entry in /etc/hosts, but using an IP address also works).
Now I could fiddle with hardware in the dark room while looking through
the doorway at the video output on my monitor.
It took some fiddling to get a good connection on that tiny connector
... but eventually I got a black-and-white view of my darkened room,
just as I'd expect under IR illumination.
I poked some holes in the milk carton and used twist-ties to seccure
the light source next to the NoIR camera.
Lights, camera, action
Next problem: mute all the blinkenlights, so my camera wouldn't look
like a christmas tree and scare off the nocturnal critters.
The Pi itself has a relatively dim red run light, and it's inside the
milk carton so I wasn't too worried about it.
But the Pi camera has quite a bright red
light that goes on whenever the camera is being used.
Even through the thick milk carton bottom, it was glaring and obvious.
Fortunately, you can
disable
the Pi camera light: edit /boot/config.txt and add this line
disable_camera_led=1
My USB wi-fi dongle has a blue light that flickers as it gets traffic.
Not super bright, but attention-grabbing. I addressed that issue
with a triple thickness of duct tape.
The IR LEDs -- remember those invisible, impossible-to-test LEDs?
Well, it turns out that in darkness, they emit a faint but still
easily visible glow. Obviously there's nothing I can do about that --
I can't cover the camera's only light source! But it's quite dim, so
with any luck it's not spooking away too many animals.
Results, and problems
For most of my daytime testing I'd used a threshold of 30 -- meaning
a pixel was considered to have changed if its value differed by more
than 30 from the previous photo. That didn't work at all in IR: changes
are much more subtle since we're seeing essentially a black-and-white
image, and I had to divide by three and use a sensitivity of 10 or 11
if I wanted the camera to trigger at all.
With that change, I did capture some nocturnal visitors, and some
early morning ones too. Note the funny colors on the daylight shots:
that's why cameras generally have IR-blocking filters if they're not
specifically intended for night shots.
Here are more photos, and larger versions of those:
Images from my
night-vision camera tests.
But I'm not happy with the setup. For one thing, it has far too many
false positives. Maybe one out of ten or fifteen images actually has
an animal in it; the rest just triggered because the wind made the
leaves blow, or because a shadow moved or the color of the light changed.
A simple count of differing pixels is clearly not enough for this task.
Of course, the software could be smarter about things: it could try to
identify large blobs that had changed, rather than small changes
(blowing leaves) all over the image. I already know
SimpleCV
runs fine on the Raspberry Pi, and I could try using it to do
object detection.
But there's another problem with detection purely through camera images:
the Pi is incredibly slow to capture an image. It takes around 20 seconds
per cycle; some of that is waiting for the network but I think most of
it is the Pi talking to the camera. With quick-moving animals,
the animal may well be gone by the time the system has noticed a change.
I've caught several images of animal tails disappearing out of the
frame, including a quail who visited yesterday morning. Adding smarts
like SimpleCV will only make that problem worse.
So I'm going to try another solution: hooking up an infra-red motion detector.
I'm already working on setting up tests for that, and should have a
report soon. Meanwhile, pure image-based motion detection has been
an interesting experiment.
Tags: crittercam, hardware, raspberry pi, photography, programming, maker
[
13:31 Jun 26, 2014
More hardware |
permalink to this entry |
]
Sat, 24 May 2014
I wrote recently about the hardware involved in my
Raspberry
Pi motion-detecting wildlife camera.
Here are some more details.
The motion detection software
I started with the simple and clever
motion-detection
algorithm posted by "brainflakes" in a Raspberry Pi forum.
It reads a camera image into a PIL (Python Imaging Library) Image object,
then compares bytes inside that Image's buffer to see how many pixels
have changed, and by how much. It allows for monitoring only a test
region instead of the whole image, and can even create a debug image
showing which pixels have changed. A perfect starting point.
Camera support
As part of the PiDoorbell project,
I had already written a camera wrapper that could control either a USB
webcam or the pi camera module, if it was installed.
Initially that plugged right in.
But I was unhappy with the Pi camera's images --
it can't focus closer than five feet (though a commenter to my
previous article pointed out that it's possible to
break
the seal on the lens and refocus it manually.
Without refocusing, the wide-angle lens means
that a bird five feet away is pretty small, and even when you get
something in focus the images aren't very sharp. And a web search for
USB webcams with good optical quality was unhelpful -- the few people
who care about webcam image quality seem to care mostly about getting
the widest-angle lens possible, the exact opposite of what I wanted
for wildlife.
Was there any way I could hook up a real camera, and drive it from the
Pi over USB as though it were a webcam? The answer turned out to be
gphoto2.
But only a small subset of cameras are controllable over USB with gphoto2.
(I think that's because the cameras don't allow control, not because
gphoto doesn't support them.) That set didn't include any of the
point-and-shoot cameras we had in the house; and while my Rebel DSLR
might be USB controllable, I'm not comfortable about leaving it out in
the backyard day and night.
With gphoto2's camera compatibility list in one tab and ebay in another,
I looked for a camera that was available, cheap
(since I didn't know if this was going to work at all),
and controllable. I ordered a used Canon A520.
As I waited for it to arrive, I fiddled with my USB-or-pi-camera
to make a start at adding gphoto2 support. I ended up refactoring the
code quite a bit to make it easy to add new types of cameras besides
the three it supports now -- pi, USB webcam, and gphoto2.
I called the module
pycamera.
Using gphoto2
When the camera arrived, I spent quite a while fiddling with gphoto2
learning how to capture images. That turns out to be a bit tricky --
there's no documentation on the various options, apparently because
the options may be different for every camera, so you have to run
$ gphoto2 --set-config capture=1 --list-config
to get a list of options the camera supports, and then, for each of
those options, run
$ gphoto2 --get-config name [option]
to see what values that option can take.
Dual-camera option
Once I got everything working, the speed and shutter noise of capturing
made me wonder if I should worry about the lifespan of the Canon if I
used it to capture snapshots every 15 seconds or so, day and night.
Since I still had the Pi cam hooked up, I fiddled the code so that I
could use the pi cam to take the test images used to detect motion,
and save the real camera for the high-resolution photos when something
actually changes. Saves wear on the more expensive camera, and it's
certainly a lot quieter that way.
Uploading
To get the images off the Pi to where other computers can see them,
I use sshfs to mount a filesystem from another machine on our local net.
Unfortunately, sshfs on the pi doesn't work quite right.
Apparently it uses out-of-date libraries (and gives a warning
to that effect).
You have to be root to use it at all, unlike newer versions of sshfs,
and then, regardless of the permissions of the remote filesystem or
where you mount it locally,
you can only access the mounted filesystem as root.
Fortunately I normally run the motion detector as root anyway, because
the picamera Python module requires it, and I've just gotten in the
habit of using it even when I'm not using python-picamera.
But if you wanted to run as non-root, you'd probably have to use
NFS or some other remote filesystem protocol. Or find a newer version
of sshfs.
Testing the gphoto setup
For reference, here's an image using the previous version of the setup,
with the Raspberry Pi camera module. Click on the image to see a crop of
the full-resolution image in daylight -- basically the best the camera can do.
Definitely not what I was hoping for.
So I eagerly set up the tripod and hooked up the setup with the Canon.
I had a few glitches in trying to test it. First, no birds; then later
I discovered Dave had stolen my extension cord, but I didn't discover
that until after the camera's batteries needed recharging.
A new extension cord and an external power supply for the camera,
and I was back in business the next day.
And the results were worth it. As you can see here, using a
real camera does make a huge difference. I used a zoom setting of 6
(it goes to 12). Again, click on the image to see a crop of the
full-resolution photo.
In the end, I probably will order one of the No-IR Raspberry pi cameras,
just to have an easy way of seeing what sorts of critters visit us at
night. But for daylight shots, an external camera is clearly the way
to go.
The scripts
The current version of the script is
motion_detect.py
and of course it needs my
pycamera
module.
And here's
documentation
for the motion detection camera.
Tags: crittercam, hardware, raspberry pi, photography, maker
[
20:09 May 24, 2014
More hardware |
permalink to this entry |
]
Thu, 15 May 2014
I've been working on an automated wildlife camera, to catch birds at
the feeder, and the coyotes, deer, rabbits and perhaps roadrunners (we
haven't seen one yet, but they ought to be out there) that roam the
juniper woodland.
This is a similar project to the
PiDoorbell project presented at PyCon, and my much earlier
proximity
camera project that used an Arduino and a plug computer
but for a wildlife camera I didn't want to use a sonar rangefinder.
For one thing, it won't work with a bird feeder -- the feeder is
always there, so the addition of a bird won't change anything as
far as a sonar rangefinder is concerned. For another, the rangefinders
aren't very accurate beyond about six feet.
Starting with a Raspberry Pi was fairly obvious.
It's low power, cheap, it even has an optional integrated camera module
that has reasonable resolution, and I could re-use a lot of the
camera code I'd already written for PiDoorbell.
I patched together some software for testing.
I'll write in more detail about the software in a separate article,
but I started with the simple
motion
detection code posted by "brainflakes" in the Raspberry Pi forums.
It's a slick little piece of code you'll find in various versions
all over the net; it uses PIL, the Python Imaging Library, to compare
a specified region from successive photos to see how much has changed.
One aside about the brainflakes code: most of the pages you'll find
referencing it tell you to install python-imaging-tk. But there's
nothing in the code that uses tk, and python-imaging is really all
you need to install. I wrote a GUI wrapper for my motion detection code
using gtk, so I had no real need to learn the Tk equivalent.
Once I had some software vaguely working, it was time for testing.
The hardware
One big problem I had to solve was the enclosure. I needed something
I could put the Pi in that was moderately waterproof -- maybe not
enough to handle a raging thunderstorm, but rain or snow can happen
here at any time without much warning. I didn't want to have to spend
a lot of time building and waterproofing it, because this is just a
test run and I might change everything in the final version.
I looked around the house for plastic objects that could be repurposed
into a camera enclosure. A cookie container from the local deli looked
possible, but I wasn't quite happy with it. I was putting the last of
the milk into my morning coffee when I realized I held in my hand a
perfect first-draft camera enclosure.
A milk carton must be at least somewhat waterproof, right?
Even if it's theoretically made of paper.
I could use the flat bottom as a place to mount the Pi camera with its
two tiny screw holes,
and then cut a visor to protect the camera from rain.
It didn't take long to whip it all together: a little work with an
X-acto knife, a little duct tape. Then I put the Pi inside it, took it
outside and bungeed it to the fence, pointing at the bird feeder.
A few issues I had to resolve:
Raspbian has rather complicated networking. I was using a USB wi-fi dongle,
but I had trouble getting the Pi to boot configured properly to talk
to our WPA router. In Raspbian networking is configured in about six
different places, any one of which might do something like prioritize
the not-connected eth0 over the wi-fi dongle, making it impossible
to connect anywhere. I ended up uninstalling Network Manager and
turning off ifplugd and everything else I could find so it would
use my settings in /etc/network/interfaces, and in the end, even
though ifconfig says it's still prioritizing eth0 over wlan0, I got
it talking to the wi-fi.
I also had to run everything as root.
The python-picamera module imports RPi.GPIO and
needs access to /dev/mem, and even if you chmod /dev/mem to give
yourself adequate permissions, it still won't work except as root.
But if I used ssh -X to the Pi and then ran my GUI program with sudo,
I couldn't display any windows because the ssh permission is for the
"pi" user, not root.
Eventually I gave up on sudo, set a password for root, and used
ssh -X root@pi
to enable X.
The big issue: camera quality
But the real problem turned out to be camera quality.
The Raspberry Pi camera module has a resolution of 2592 x 1944, or 5
megapixels. That's terrific, far better than any USB webcam. Clearly
it should be perfect for this tast.
Update: see below. It's not a good camera, but it turns out I had a
lens problem and it's not this bad.
So, the Pi camera module might be okay if all I want is a record of
what animals visit the house. This image is good enough, just barely,
to tell that we're looking at a house finch (only if we already rule
out similar birds like purple finch and Cassin's finch -- the photo
could never give us enough information to distinguish among similar birds).
But what good is that? I want decent photos that I can put on my web site.
I have a USB camera, but it's only one megapixel and gives lousy
images, though at least they're roughly in focus so they're better
than the Pi cam.
So now I'm working on a setup where I drive an external camera
from the Pi using gphoto2. I have most of the components working,
but the code was getting ugly handling three types of cameras instead
of just two, so I'm refactoring it. With any luck I'll have something
to write about in a week or two.
Meanwhile, the temporary code is in my
github rpi
directory -- but it will probably move from there soon.
I'm very sad that the Pi camera module turned out to be so bad. I was
really looking forward to buying one of the No-IR versions and setting up
a night wildlife camera. I've lost enthusiasm for that project
after seeing how bad the images were. I may have to investigate how
to remove the IR filter from a point-and-shoot camera, after I get
the daylight version working.
Update, a few days later: It turns out I had some spooge on the lens.
It's not quite as bad as I made it out to be.
Here's a sample.
It's still not a great camera, and it can't focus anywhere near as
close as the 2 feet I've seen claimed -- 5 feet is about the closest
mine can focus, which means I can't get very close to the wildlife,
which was a lot of the point of building a wildlife camera.
I've seen suggestions of putting reading glasses in front of the lens
as a cheap macro adaptor.
Instead, I'm going ahead with the gphoto2 option, which is about ready to
test -- but the noIR Pi camera module might be marginally acceptable for
a night wildlife camera.
Tags: crittercam, hardware, raspberry pi, photography, maker
[
13:30 May 15, 2014
More hardware |
permalink to this entry |
]