Saturday 22 August 2015

Advance and be Recognized

Another important component of my weather server (MetCommand-Home) is the sky-recognizer program.

Every five minutes, a webcam aimed out of an upstairs window snaps a shot of the sky. Usually, that's as far as it would get. But I wanted to have real observations, and not something I'd be having to update manually every few hours.

I finally settled on programming something, wxSky, that would do the job.

wxSky examines the pixels of an image and comes up with an observation. Currently, the list of observations is:

- Sunny (daytime only)
- Cloudy
- Twilight
- Clear (nighttime only)

The sky condition is gauged by examining the colour channels of the image, both separately and together. The rules are relatively simple and are accurate at least 90% of the time, although it can be difficult to detect clouds on a summer's night--contrast that with winter, when the ground is covered by snow and glowing in all the light pollution, and the clouds light up just fine. Partly cloudy would be more difficult to detect, and I find that, 90% of the time, sunny or cloudy does just fine.

It is, of course, a GUI program, with an editable parameters file, Linux-style (in fact, the production version runs on Linux).


wxSky v 1.27

It's difficult to see in this photo, but in the upper-left-hand corner of the window is mostly administrative stuff--the time and date; the latest observation, the middle is a view of the picture as nine averaged zones, with the Sweet Spot (more on this shortly) highlighted. Below that is a box simply recording the last five observations.

The upper right-hand corner is a view of the average values for the nine zones of the picture. Three buttons--R, G and B--are for selecting Red and/or Green and/or Blue channels.

Finally, there is one composite (master) value--displayed for R, G and B channels (and combined). These are averaged values for the entire picture.

Below that there is the same display, but for the Sweet Spot, which is a user-selectable zone (1/9 of the pic).

Why all the RGB breakouts? Because different sky conditions are based on colour-channel values. Twilight is a deep blue, a bit of green, and almost no red. Sunny is a deep blue with a good helping of green and a little red. Cloudy is almost equal values of red, green and blue; or, at night, with significant red, some green and almost no blue. Easy access to those values is important when calibrating the program to a new camera.

Why a Sweet Spot? Because your camera could be facing in any direction or (like mine) be partially obscured in a particular zone. I personally find that zone 7 (lower-left corner) has the best values.

The output of the program is a single text file simply containing one line with the date and time of the observation, and the observation itself. This is handed off to wxOCR, the LCD recognizer, for incorporation into an observations packet.

The weather server (Centretown Observatory) is available at:
http://mizar64.dyndns-home.com:64180/weather.html.

-Bill

Wednesday 19 August 2015

Avast, Damned Thing!

[Edit 2015-08-22: I see there is an existing product for OCR'ing LCDs called, coincidentally, WxOCR.  I will have to change the name of the program.]

I really should have blogged, before now, on the wonderful little OCR (WxOCR) program that reads my home weather station's statistics from snapped JPEGs. It was a couple of years in the making, and put my coding skills to the test; but it's been running for at least three years, and running very well.

The Hardware
I have a home weather station, which consists of several outdoor sensors, wirelessly linked to an LCD display pad. I also have a spare ancient laptop and a 1024x768 webcam.

The Mission
To deduce the values of the readings on the display, accurately, cheaply.

It's Dependable
(In essence) what happens is that at five-minute intervals, cron fires off a message telling a shell script to snap a picture of the weather station's LCD display. Having done so, the photo is handed off to WxOCR, which analyzes the green portion of the image (for maximum contrast, and it's configurable--you can use red, green, blue, or all channels). Data are defined as Groups, Characters and Segments; for each character, the expected location of each segment area is scanned and compared to a control value to determine whether it is lit, or extinguished. The LCD character has seven segments (we ignore any decimal point) which can correspond to the bits in a binary series; we add up the seven resulting bits to get a value from 0 to 127.  This is compared to a list of permissible values; if it's a match, then you've done one character, and move on to the next. If no match, a null is generated, which immediately halts processing for that number-group.

Later in the processing, the output values are herded into CSV format, along with the Sky Recognizer program's output, and handed off to the weather server.

So far, in about three years' operation, it has yielded probably hundreds of thousands of observations.  Most weeks, it is about 99.98% accurate.

It's Highly Configurable
All the configuration is via two files, one of which can be altered at any time and one of which is reserved by the system.  Most configuration directives are concerned with the placement of characters and segments.  Also, for each character, a control spot (a nearby area guaranteed always to be clear) can be defined by both position and dimension.  Characters can be configured horizontally or vertically, and optionally their individual segments can be defined.  Character groups can be interpreted is several modes: direct-read (for most things), darkest-segment-wins (useful for displays with a windrose), and (for precipitation) a running-totals mode.  A decimal point may be placed at any character position. Math (+-*/) can be performed on the character group at several points in its processing.

It's Error-Correcting
Because all of the values permissible must be defined, error-correction can be handled.  Partial characters, or characters with an extra segment in them, can be converted to their proper values.  In general, this works exceedingly well.

It's GUI
The program was designed from the outset to be a GUI program (screenshot below).  It's got everything I need to be able to position data groups quickly--or even the whole screen.  It even has 'second sky condition' buttons, plus a timer value; these are for situations where it's difficult for the system to detect; fog, snow, etc.

It's Linux
I need a rock-solid operating platform; but even the most-advanced Windows version needs to be rebooted regularly.  Therefore, WxOCR is built on Debian Linux and has essentially no downtime (it reboots weekly, three minutes early each Sunday morning).

But it ain't Perfect
It's a minor annoyance, but for whatever reason the character '2' is often missing the top bar, even though it's clearly in the image.  Technically, this shouldn't be happening.  It does anyway.  And, during the day, differences in lighting can throw off the threshold values established for each character. [Edit 2015-10-25: This is now essentially fixed.]

Nor Ever Will Be
It's almost impossible to get a perfect week's readings.  In fact, in all those three years, I've only seen it happen once.  This is for various reasons: the digits were themselves in transition as the pic was snapped; the camera shifted (damned cats); the contrast was poor in one particular image; and so on.  Plus, the camera can drift in aim and focus over time. I'd frankly like to see a commercial system (if one exists; I can't find one) with a better accuracy than WxOCR.

It's Still Evolving
I can still see more work I'd like to do on the program.  I'd like to add a four-way doodad for the individual characters in a group (refer to photo below).  I'd like to change slightly how the precipitation sensor works, to cut down on n/a readings from it.

It Needs to Go Open-Source
So far, I've not found another program that does what WxOCR does.  I really think this program needs to be open-sourced, and I'll do that in the near future.  I think it could really fill a (highly vertical, admittedly) need.

Here it is, in all its glory:


Image of WxOCRWxOCR v. 2.82