Archive for the ‘’ Category

drive a webcam with python

Sunday, September 17th, 2006

I bought a USB webcam off of eBay quite some time ago, and I decided to connect it to my telescope with a little bit of hardware hackery. I’ll have to see about posting a writeup on how I did that at a later time. Anyway, when I installed my camera software, I quickly found how horrible the program was. It gave a tiny preview of what the camera saw, and had no way of capturing images or video without waaaay too many clicks of the mouse. That’s when I decided to write my own in Python.

The main libraries that I ended up using were VideoCapture, PIL, and pygame. As you’ll see, it’s not really difficult at all to make a useful webcam application.

Here’s the code:

from VideoCapture import Device
import ImageDraw, sys, pygame, time
from pygame.locals import *
from PIL import ImageEnhance

res = (640,480)
cam = Device()
screen = pygame.display.set_mode((640,480))
font = pygame.font.SysFont("Courier",11)

def disp(phrase,loc):
    s = font.render(phrase, True, (200,200,200))
    sh = font.render(phrase, True, (50,50,50))
    screen.blit(sh, (loc[0]+1,loc[1]+1))
    screen.blit(s, loc)

brightness = 1.0
contrast = 1.0
shots = 0

while 1:
    camshot = ImageEnhance.Brightness(cam.getImage()).enhance(brightness)
    camshot = ImageEnhance.Contrast(camshot).enhance(contrast)
    for event in pygame.event.get():
        if event.type == pygame.QUIT: sys.exit()
    keyinput = pygame.key.get_pressed()
    if keyinput[K_1]: brightness -= .1
    if keyinput[K_2]: brightness += .1
    if keyinput[K_3]: contrast -= .1
    if keyinput[K_4]: contrast += .1
    if keyinput[K_q]: cam.displayCapturePinProperties()
    if keyinput[K_w]: cam.displayCaptureFilterProperties()
    if keyinput[K_s]:
        filename = str(time.time()) + ".jpg"
        cam.saveSnapshot(filename, quality=80, timestamp=0)
        shots += 1
    camshot = pygame.image.frombuffer(camshot.tostring(), res, "RGB")
    screen.blit(camshot, (0,0))
    disp("S:" + str(shots), (10,4))
    disp("B:" + str(brightness), (10,16))
    disp("C:" + str(contrast), (10,28))

I decided to use pygame in order to build this because it can actually handle the fps that I need for video. I built something similar quite a while ago with wxPython, but it just wasn’t fast enough at image swapping to make it work well.

A couple of noteworthy points:

  • The function on line 15 is simply there to help automate displaying information on the screen. In my case, I display the number of screenshots I’ve saved to disk, and the current brightness and contrast levels. The function displays the text sent to it by writing it in dark gray, and then re-writing it in light gray over the top with a pixel offset. I found this helps a TON to make the text visible in different scenarios.
  • Line 26 is where I actually apply the contrast and brightness changes. Lines 30-33 set up the number keys 1-4 to adjust contrast/brightness on the fly. This is terribly useful, in my experience.
  • Lines 34 and 35 are setting up ‘q’ and ‘w’ to show the settings dialogs for the webcam… this is where you can set resolutions, exposure levels, etc.
  • On line 36, and those under the if statement, I save the current image and name it using the current time… this insures no overlapping image names.

If you’re trying to write a webcam app of your own, I hope this gets you pointed in the right direction. Let me know if you find this info useful!

filling a database with historic weather data

Saturday, September 2nd, 2006

I’m one of those people that just loves inclement weather. Maybe it’s because of where I grew up, but I’ve always adored a good thunderstorm. Whenever a storm is heading for my area, I check various sites online to get the latest radar and what-not, but sometimes you just aren’t near a computer (gasp!). Not only that, but most of radar loops you find only go back so far… maybe an hour or two. That’s why I decided to build my own solution, using data that the NOAA provides for free. Pretty much everything here is written in Python, the greatest language ever. :)

So first of all, I had to decide how to actually collect the data. There are a few methods, but one issue I faced is that I normally look at this stuff on my laptop. What if I have my laptop turned off? It’s just not a reliable platform to use for mining data. Happily, I have a dreamy webhost that gives me shell access. So there you go… the perfect spot to house the fruitage of my scripts. So what I’m going to do is build a script that runs regularly, contacts a weather site to scrape a radar image, and contacts the NOAA to get the latest weather data… temperature, barometer, etc. At that point, I want to insert this stuff into a database housed at the same host.

I’m going to take you through this as if you’re fairly new to Python, and the plan is to be really easy to understand. If it isn’t… well… you get what you pay for, right? :) Seriously though, if you end up with questions, just post them at the end of this article and I’ll answer them.

So I logged into my shell account at my webhost via SSH. I created a new text file called ‘radardl’ using the command vi radardl, and then made it executable with chmod +x radardl. As for the code that goes in that file…

import MySQLdb, time, os
from urllib import urlopen, urlretrieve

Nothing special here… just set it up to execute using your Python executable, and import the necessary modules. MySQLdb is used for working with the database, and urllib is used to get the web pages / images that we’ll need.

db = MySQLdb.connect(host=’dbhost’, user=’dbuser’, passwd=’dbpasswd’, db=’dbname’)
c = db.cursor()

This is the basic connection to your database. Obviously, you’ll need to set one up somewhere so that you’ll actually be able to do this. Replace the placeholders with your specific connection info. You’ll also need to create a new table to hold your data… I used something like, “create table weather (recorded timestamp primary key, temperature_string varchar(50), temp_f float, relative_humidity float, pressure_in float, heat_index_f float, windchill_f float, radar varchar(250))“. For simplicity, go ahead and use that command to create your table and you can modify it after we’re done.

j = urlopen(‘’)

Ok, this is where we download the current weather observations. Take a look at this page and select your state, then find the weather station closest to you. For me, it’s KTUL in Oklahoma. Just find your local page, and replace the url in the code. While you’re looking at it, take a look at all of the data that’s provided in there. It’s a wealth of observation data! I’m only capturing a couple of things with this code, but you can easily add what you want.

stats = {}
for l in j.readlines():
stats[l[l.find(“<")+1:l.find(">“)]] = l[l.find(“>”)+1:l.rfind(“<")] [/python] Now, you could use something fancy like the wonderful Elementtree library, but in my case my host doesn’t have it installed and I couldn’t do it myself. So instead I used the above code to give me a similar result. Basically, I search for the < and > characters in different ways in order to get the key name and the value. I then store those into the ‘stats’ array. This works great for the XML that the NOAA provides… but keep in mind that XML from other sources may not be so easy to parse.

rightnow = str(time.time())

for line in j.readlines():
if line.find(“img src=”) > -1:
img = line.strip()[11:-1]
urlretrieve(img, rightnow+”.gif”)

Ok… the thing is, everyone has their favorite weather radar, and I don’t want to advocate one over the other. I’d also prefer not to give this code out and have my favorite radar image source hammered over and over by everyone in the world. So basically… you need to find a site that will predictably show you their most current radar image for your area. Take a look at the page source and look for the line where the image is. As you can see above, I simply loop through every line on the page looking for “img src=”, because my particular source only shows one image on that page. I’ll have to leave it up to your imagination on how to scrape the image out of their code. Or, if the radar images don’t matter to you, you could skip this step altogether!

Incidentally, you might notice the variable ‘rightnow’. That is simply the current unix timestamp. I name my radar images using that variable so I always have a unique name for them.

if os.path.getsize(rightnow+”.gif”) > 0:
print “Got “+rightnow+”.gif”
c.execute(‘insert into weather values(now(),”‘ + stats[‘temperature_string’] + ‘”,”‘ + stats[‘temp_f’] + ‘”,”‘ + stats[‘relative_humidity’] + ‘”,”‘ + stats[‘pressure_in’] + ‘”,”‘ + stats[‘heat_index_f’] + ‘”,”‘ + stats[‘windchill_f’] + ‘”,”‘ + rightnow + ‘.gif”)’)
print rightnow+”.gif”+” Skipped”

And finally, I check to see if the image size is greater than 0 bytes. You’d be surprised how often empty images are saved. This just makes sure you’re not filling your database with useless information. Assuming it’s a good image, I insert the data from the NOAA’s XML page along with the name of the radar image I retrieved into the weather table.

And there you have it! Just create a cron job to run this script regularly (radar is generally updated every 6 minutes, but weather observations are only updated hourly) and watch this data accumulate in your new weather table. You can then go on to create neat graphs and other fancy things all based on your historic data. Enjoy!