Akkana's Musings on Open Source Computing and Technology, Science, and Nature.
Sun, 04 Oct 2015
For the animations
I made from the lunar eclipse last week, the hard part was aligning
all the images so the moon (or, in the case of the moonrise image, the
hillside) was in the same position in every time.
This is a problem that comes up a lot with astrophotography, where
multiple images are stacked for a variety of reasons: to increase
contrast, to increase detail, or to take an average of a series of images,
as well as animations like I was making this time.
And of course animations can be fun in any context, not just astrophotography.
In the tutorial that follows, clicking on the images will show a full
sized screenshot with more detail.
Load all the images as layers in a single GIMP image
The first thing I did was load up all the images as layers in a single image:
File->Open as Layers...
, then navigate to where the images are
and use shift-click to select all the filenames I wanted.
Work on two layers at once
By clicking on the "eyeball" icon in the Layers dialog, I could
adjust which layers were visible. For each pair of layers, I made
the top layer about 50% opaque by dragging the opacity slider (it's
not important that it be exactly at 50%, as long as you can see both
Then use the Move tool to drag the top image on top of the bottom image.
But it's hard to tell when they're exactly aligned
"Drag the top image on top of the bottom image":
easy to say, hard to do. When the images are dim and red like that,
and half of the image is nearly invisible, it's very hard to tell when
they're exactly aligned.
Use a Contrast display filter
What helped was a Contrast filter.
and in the dialog that pops up,
click on Contrast
, and click on the right arrow to move it to
The Contrast filter changes the colors so that dim red moon is fully
visible, and it's much easier to tell when the layers are
approximately on top of each other.
Use Difference mode for the final fine-tuning
Even with the Contrast filter, though, it's hard to see when the
images are exactly on top of each other. When you have them within a few
pixels, get rid of the contrast filter (you can keep the dialog up but
disable the filter by un-checking its checkbox in Active Filters
Then, in the Layers dialog, slide the top layer's Opacity back to 100%,
go to the Mode
selector and set the layer's mode to
In Difference mode, you only see differences between the two layers.
So if your alignment is off by a few pixels, it'll be much easier to see.
Even in a case like an eclipse where the moon's appearance is changing
from frame to frame as the earth's shadow moves across it, you can still
get the best alignment by making the Difference between the two layers
as small as you can.
Use the Move tool and the keyboard: left, right, up and down arrows move
your layer by one pixel at a time. Pick a direction, hit the arrow key
a couple of times and see how the difference changes. If it got bigger,
use the opposite arrow key to go back the other way.
When you get to where there's almost no difference between the two layers,
you're done. Change Mode back to Normal, make sure Opacity is at 100%,
then move on to the next layer in the stack.
It's still a lot of work. I'd love to find a program that looks for
circular or partially-circular shapes in successive images and does
the alignment automatically. Someone on GIMP suggested I might be
able to write something using OpenCV, which has circle-finding
primitives (I've written briefly before about
a wrapper that makes OpenCV easy to use from Python).
But doing the alignment by hand in GIMP, while somewhat tedious,
didn't take as long as I expected once I got the hang of using the
Contrast display filter along with Opacity and Difference mode.
Creating the animation
Once you have your layers, how do you turn them into an animation?
The obvious solution, which I originally intended to use, is to save
as GIF and check the "animated" box. I tried that -- and discovered
that the color errors you get when converting an image to indexed make
a beautiful red lunar eclipse look absolutely awful.
a series of JPEGs. That meant that I needed to export all the layers
from my GIMP image to separate JPG files.
GIMP doesn't have a built-in way to export all of an image's layers to
separate new images. But that's an easy plug-in to write, and a web
search found lots of plug-ins already written to do that job.
The one I ended up using was Lie Ryan's Python script in
to save different layers of a design in separate files;
though a couple of others looked promising (I didn't try them), such as
You can see the final animation here:
Lunar eclipse of
September 27, 2015: Animations.
[ 09:44 Oct 04, 2015
More gimp |
permalink to this entry |
Thu, 01 Oct 2015
The lunar eclipse on Sunday was gorgeous. The moon rose already in
eclipse, and was high in the sky by the time totality turned the
moon a nice satisfying deep red.
I took my usual slipshod approach to astrophotography. I had my 90mm
f/5.6 Maksutov lens set up on the patio with the camera attached,
and I made a shot whenever it seemed like things had changed
significantly, adjusting the exposure if the review image looked
like it might be under- or overexposed, occasionally attempting
to refocus. The rest of the time I spent socializing with friends,
trading views through other telescopes and binoculars, and enjoying an
apple tart a la mode.
So the images I ended up with aren't all they could be --
not as sharply focused as I'd like (I never have figured out a
good way of focusing the Rebel on astronomy images) and rather
Still, I took enough images to be able to put together a couple of
animations: one of the lovely moonrise over the mountains, and one
of the sequence of the eclipse through totality.
Since the 90mm Mak was on a fixed tripod, the moon drifted through the
field and I had to adjust it periodically as it drifted out.
So the main trick to making animations was aligning all the moon
images. I haven't found an automated way of doing that, alas,
but I did come up with some useful GIMP techniques, which I'm in
the process of writing up as a tutorial.
Once I got the images all aligned as layers in a GIMP image,
I saved them as an animated GIF -- and immediately discovered that
the color error you get when converting to an indexed GIF image
loses all the beauty of those red colors. Ick!
loads images one by one at fixed intervals. That worked a lot better
than the GIF animation, plus it lets me add a Start/Stop button.
animation function) here:
Lunar eclipse animations
[ 12:55 Oct 01, 2015
More science/astro |
permalink to this entry |
Sun, 27 Sep 2015
Every now and then I need to create a series of contrasting colors.
For instance, in my mapping app
when displaying several track logs at once, I want them to be different
colors so it's easy to tell which track is which.
Of course, I could make a list of five or ten different colors and
cycle through the list. But I hate doing work that a computer could
do for me.
Choosing random RGB (red, green and blue) values for the colors,
though, doesn't work so well. Sometimes you end up getting two similar
colors together. Other times, you get colors that just don't work
well, because they're so light they look white, or so dark they look
black, or so unsaturated they look like shades of grey.
What does work well is converting to the HSV color space:
hue, saturation and value.
Hue is a measure of the color -- that it's red, or blue, or
yellow green, or orangeish, or a reddish purple.
Saturation measures how intense the color is: is it a bright, vivid
red or a washed-out red? Value tells you how light or dark it is: is
it so pale it's almost white, so dark it's almost black, or somewhere
in between? (A similar model, called HSL, substitutes Lightness for Value,
but is similar enough in concept.)
If you're not familiar with HSV, you can get a good feel for it by
playing with GIMP's color chooser (which pops up when you click the
black Foreground or white Background color swatch in GIMP's toolbox).
The vertical rainbow bar selects Hue. Once you have a hue, dragging
up or down in the square changes Saturation;
dragging right or left changes Value.
You can also change one at a time by dragging the H, S or V sliders at
the upper right of the dialog.
Why does this matter? Because once you've chosen a saturation and value,
or at least ensured that saturation is fairly high and value is
somewhere in the middle of its range, you can cycle through hues
and be assured that you'll get colors that are fairly different each time.
If you had a red last time, this time it'll be a green, or yellow, or
blue, depending on how much you change the hue.
How does this work programmatically?
PyTopo uses Python-GTK, so I need a function that takes a gtk.gdk.Color
and chooses a new, contrasting Color. Fortunately, gtk.gdk.Color already
hue, saturation and
value built in.
Color.hue is a floating-point number between 0 and 1,
so I just have to choose how much to jump. Like this:
'''Returns a gtk.gdk.Color of similar saturation and value
to the color passed in, but a contrasting hue.
gtk.gdk.Color objects have a hue between 0 and 1.
if not color:
# How much to jump in hue:
jump = .37
return gtk.gdk.color_from_hsv(color.hue + jump,
What if you're not using Python-GTK?
No problem. The first time I used this technique, I was generating
colorsys module works fine for converting red, green, blue triples
to HSV (or a variety of other colorspaces) which you can then use in
whatever graphics package you prefer.
[ 13:27 Sep 27, 2015
More programming |
permalink to this entry |
Mon, 21 Sep 2015
The street for a substantial radius around my mailbox has a wonderful,
strong minty smell.
The smell is coming from a clump of modest little yellow flowers.
They're apparently Dyssodia papposa, whose common name is "fetid marigold".
It's in the sunflower family, Asteraceae, not related to Lamiaceae, the mints.
"Fetid", of course, means "Having an offensive smell; stinking".
When I google for fetid marigold, I find quotes like
"This plant is so abundant, and exhales an odor so unpleasant as to
sicken the traveler over the western prairies of Illinois, in
autumn." And nobody says it smells like mint -- at least, googling
for the plant and "mint" or "minty" gets nothing.
But Dave and I both find the smell very minty and pleasant,
and so do most of the other local people I queried.
What's going on?
Another local plant which turns strikingly red in autumn has an even
worse name: fetid goosefoot. On a recent hike, several of us made a
point of smelling it. Sure enough: everybody except one found it
minty and pleasant. But one person on the hike said "Eeeeew!"
It's amazing how people's sensory perception can vary. Everybody knows
how people's taste varies: some people perceive broccoli and cabbage
as bitter while others love the taste. Some people can't taste lobster
and crab at all and find Parmesan cheese unpleasant.
And then there's color vision.
Every amateur astronomer who's worked public star parties knows about
Albireo. Also known as beta Cygni, Albireo is a double star, the head
of the constellation of the swan or the foot of the Northern Cross.
In a telescope, it's a double star, and a special type of double:
what's known as a "color double", two stars which are very different
colors from each other.
Most non-astronomers probably don't think of stars having colors.
Mostly, color isn't obvious when you're looking at things at night:
you're using your rods, the cells in your retina that are sensitive
to dim light, not your cones, which provide color vision but need
a fair amount of light to work right.
But when you have two things right next to each other that are
different colors, the contrast becomes more obvious. Sort of.
Point a telescope at Albireo at a public star party and ask the
next ten people what two colors they see. You'll get at least six,
more likely eight, different answers. I've heard blue and red, blue
and gold, red and gold, red and white, pink and blue ... and white
and white (some people can't see the colors at all).
Officially, the bright component is actually a close binary, too close
to resolve as separate stars. The components are
Aa (magnitude 3.18, spectral type K2II) and
Ac (magnitude 5.82, spectral type B8).
(There doesn't seem to be an Albireo Ab.)
Officially that makes Albireo A's combined color yellow or amber.
The dimmer component, Albireo B, is magnitude 5.09 and spectral
type B8Ve: officially it's blue.
But that doesn't make the rest of the observers wrong. Color vision is
a funny thing, and it's a lot more individual than most people think.
Especially in dim light, at the limits of perception.
I'm sure I'll continue to ask that question when I show Albireo
in my telescope, fascinated with the range of answers.
In case you're wondering,
I see Albireo's components as salmon-pink and pale blue.
I enjoy broccoli and lobster but find bell peppers bitter.
And I love the minty smell of plants that a few people, apparently,
[ 16:09 Sep 21, 2015
More nature |
permalink to this entry |
Tue, 15 Sep 2015
I wrote last week about
Kobo e-reader's sqlite database by hand.
But who wants to remember all the table names and type out those queries?
I sure don't. So I wrote a Python wrapper that makes it much easier to
interact with the Kobo databases.
Happily, Python already has a module called sqlite3.
So all I had to do was come up with an API that included the calls
I typically wanted -- list all the books, list all the shelves,
figure out which books are on which shelves, and so forth.
The result was
which includes a main function that can list books, shelves, or shelf contents.
You can initialize kobo_utils like this:
koboDB = KoboDB("/path/where/your/kobo/is/mounted")
throws an exception if it can't find the
Then you can list books thusly:
or list shelf names:
which books are on which shelves:
shelves = koboDB.get_dlist("Shelf", selectors=[ "Name" ])
for shelf in shelves:
What I really wanted, though, was a way to organize my library,
taking the tags in each of my epub books and assigning them to
an appropriate shelf on the Kobo, creating new shelves as needed.
Using kobo_utils.py plus the
epub library I'd already written, that ended up being quite
[ 20:38 Sep 15, 2015
More tech |
permalink to this entry |
Thu, 10 Sep 2015
One of the adjustments we've had to make in moving to New Mexico is
getting used to the backward (compared to California) weather.
Like, rain in summer!
Not only is rain much more pleasant in summer, as a dramatic
thundershower that cools you off on a hot day instead of a constant
cold drizzle in winter (yes, I know that by now Calfornians need
a lot more of that cold drizzle! But it's still not very
pleasant being out in it). Summer rain has another unexpected effect:
flowers all summer, a constantly changing series of them.
Right now the purple asters are just starting up,
while skyrocket gilia and the last of the red penstemons add a note
of scarlet to a huge array of yellow flowers of all shapes and sizes.
Here's the vista that greeted us on a hike last weekend
on the Quemazon trail.
Down in the piñon-juniper where we live, things aren't usually
quite so colorful; we lack many red blooms, though we have just as many
purple asters as they do up on the hill, plus lots of pale trumpets
(a lovely pale violet gilia) and Cowpen daisy, a type of yellow sunflower.
But the real surprise is a plant with a modest name: snakeweed. It has
other names, but they're no better: matchbrush, broomweed. It grows
everywhere, and most of the year it just looks like a clump of bunchgrass.
Then come September, especially in a rainy year like this one,
and all that snakeweed suddenly bursts into a glorious carpet of gold.
We have plenty of other weeds -- learning how to identify Russian thistle
(tumbleweed), kochia and amaranth when they're young, so we can pull
them up before they go to seed and spread farther, has launched me on
a project of an Invasive Plants page for the nature center (we should be
ready to make that public soon).
But snakeweed, despite the name, is a welcome guest in our yard, and
it lifts my spirits to walk through it on a September evening.
By the way, if anyone in Los Alamos reads this blog, Dave and I are
giving our first planetarium show at the nature center tomorrow (that's
Unlike most PEEC planetarium shows, it's free! Which is probably just
as well since it's our debut. If you want to come see us, the info is here:
Night Sky Fiesta
[ 21:24 Sep 10, 2015
More nature |
permalink to this entry |
Thu, 03 Sep 2015
I've been enjoying reading my new Kobo Touch quite a lot. The screen
is crisp, clear and quite a bit whiter than my old Nook;
the form factor is great, it's reasonably responsive (though there
are a few places on the screen where I have to tap harder than other
places to get it to turn the page), and I'm happy with the choice of fonts.
But as I mentioned in my
previous Kobo article,
there were a few tweaks I wanted to make; and I was very happy with how
easy it was to tweak, compared to the Nook. Here's how.
Mount the Kobo
When you plug the Kobo in to USB, it automatically shows up as a
USB-Storage device once you tap "Connect" on the Kobo -- or as two
storage devices, if you have an SD card inserted.
Like the Nook, the Kobo's storage devices show up without partitions.
For instance, on Linux, they might be /dev/sdb and /dev/sdc, rather
than /dev/sdb1 and /dev/sdc1. That means they also don't present UUIDs
until after they're already mounted, so it's hard to make an entry for
them in /etc/fstab if you're the sort of dinosaur (like I am) who prefers
that to automounters.
Instead, you can use the entry in /dev/disk/by-id.
So fstab entries, if you're inclined to make them, might look like:
/dev/disk/by-id/usb-Kobo_eReader-3.16.0_N905K138254971:0 /kobo vfat user,noauto,exec,fmask=133,shortname=lower 0 0
/dev/disk/by-id/usb-Kobo_eReader-3.16.0_N905K138254971:1 /kobosd vfat user,noauto,exec,fmask=133,shortname=lower 0 0
One other complication, for me, was that the Kobo is one of a few
devices that don't work through my USB2 powered hub. Initially I
thought the Kobo wasn't working, until I tried a cable plugged
directly into my computer. I have no idea what controls which devices
work through the hub and which ones don't.
(The Kobo also doesn't give any indication when it's plugged in to a
wall charger, nor does
The sqlite database
Once the Kobo is mouted,
ls -a will show a directory
named .kobo. That's where all the good stuff is:
in particular, KoboReader.sqlite, the device's database,
and Kobo/Kobo eReader.conf, a human-readable configuration file.
Browse through Kobo/Kobo eReader.conf for your own amusement,
but the remainder of this article will be about KoboReader.sqlite.
I hadn't used sqlite before, and I'm certainly no SQL expert. But a
little web searching and experimentation taught me what I needed to know.
First, make a local copy of KoboReader.sqlite, so you don't risk
overwriting something important during your experimentation.
The Kobo is apparently good at regenerating data it needs, but
you might lose information on books you're reading.
To explore the database manually, run:
Some useful queries
Here are some useful sqlite commands, which you can generalize to
whatever you want to search for on your own Kobo. Every query (not .tables)
must end with a semicolon.
Show all tables in the database:
The most important ones, at least to me, are content (all your books),
Shelf (a list of your shelves/collections), and ShelfContent
(the table that assigns books to shelves).
Show all column names in a table:
There are a lot of columns in content
, so try
to see a much simpler table.
Show the names of all your shelves/collections:
SELECT Name FROM Shelf;
Show everything in a table:
SELECT * FROM Shelf;
Show all books assigned to shelves, and which shelves they're on:
SELECT ShelfName,ContentId FROM ShelfContent;
ContentId can be a URL to a sideloaded book, like
, or a UUID like
de98dbf6-e798-4de2-91fc-4be2723d952f for books from the Kobo store.
Show all books you have installed:
SELECT Title,Attribution,ContentID FROM content WHERE BookTitle is null ORDER BY Title;
One peculiarity of Kobo's database: each book has lots of entries,
apparently one for each chapter. The entries for chapters have the
chapter name as Title, and the book title as BookTitle. The entry
for the book as a whole has BookTitle empty, and the book title as Title.
For example, I have file:///mnt/sd/earnest.epub
sqlite> SELECT Title,BookTitle from content WHERE ContentID LIKE "%hamlet%";
HAMLET, PRINCE OF DENMARK|Hamlet
Scene II. Elsinore. A room of state in the Castle.|Hamlet
Scene III. A room in Polonius's house.|Hamlet
Scene IV. The platform.|Hamlet
Scene V. A more remote part of the Castle.|Hamlet
[ ... and so on ... ]
Scene II. A hall in the Castle.|Hamlet
Each of these entries has Title set to the name of the chapter (an act
in the play) and BookTitle set to Hamlet
, except for the final
entry, which has Title set to Hamlet
and BookTitle set to nothing.
That's why you need that query WHERE BookTitle is null
just want a list of your books.
Show all books by an author:
SELECT Title,Attribution,ContentID FROM content WHERE BookTitle is null
AND Attribution LIKE "%twain%" ORDER BY Title;
is where the author's name goes. LIKE %% searches
are case insensitive.
Of course, it's a lot handier to have a program that knows these queries
so you don't have to type them in every time (especially since the sqlite3
app has no history or proper command-line editing).
But this has gotten long enough, so I'll write about that separately.
[ 19:11 Sep 03, 2015
More tech |
permalink to this entry |
Wed, 26 Aug 2015
For several years I've kept a rooted Nook Touch for reading ebooks.
But recently it's become tough to use. Newer epub books no longer work
work on any version of FBReader still available for the Nook's ancient
Android 2.1, and the Nook's built-in reader has some fatal flaws: most
notably that there's no way to browse books by subject tag, and it's
painfully slow to navigate a library of 250 books when have to start
from the As and you need to get to T paging slowly
forward 6 books at a time.
The Kobo Touch
But with my Nook unusable, I borrowed Dave's Kobo Touch to see how
it compared. I like the hardware: same screen size as the Nook, but a
little brighter and sharper, with a smaller bezel around it, and
a spring-loaded power button in a place where it won't get pressed
accidentally when it's packed in a suitcase -- the Nook was always
coming on while in its case, and I didn't find out until I pulled it
out to read before bed and discovered the battery was too low.
The Kobo worked quite nicely as a reader, though it had a few of the
same problems as the Nook. They both insist on justifying both left
and right margins (Kobo has a preference for that, but it doesn't work
in any book I tried). More important is the lack of subject tags. The
Kobo has a "Shelves" option, called "Collections" in some versions,
but adding books to shelves manually is tedious if you have a lot of
books. (But see below.)
It also shared another Nook problem: it shows overall progress in the
book, but not how far you are from the next chapter break. There's
a choice to show either book progress or chapter progress,
but not both; and chapter progress only works for books in Kobo's
special "kepub" format (I'll write separately about that).
I miss FBReader's progress bar that shows both book and chapter progress,
and I can't fathom why that's not considered a necessary feature for
But mostly, Kobo's reader was better than the Nook's.
Bookmarks weren't perfect, but they basically worked, and I
didn't even have to spent half an hour reading the manual to use them
(like I did with the Nook). The font selection was great, and the
library navigation had one great advantage over the Nook: a slider
so you could go from A to T quickly.
I liked the Kobo a lot, and promptly ordered one of my own.
It's not all perfect
There were a few disadvantages. Although the Kobo had a lot more
granularity in its line spacing and margin settings, the smallest
settings were still a lot less tight than I wanted. The Nook only
offered a few settings but the smallest setting was pretty good.
Also, the Kobo can only see books at the top level of its microSD
card. No subdirectories, which means that I can't use a program like
rsync to keep the Kobo in sync with my ebooks directory on my computer.
Not that big a deal, just a minor annoyance.
More important was the subject tagging, which is really needed in
a big library. It was pretty clear Shelves/Collections were what I
needed; but how could I get all my books into shelves without
laboriously adding them all one by one on a slow e-ink screen?
It turns out Kobo's architecture makes it pretty easy to fix these problems.
While the rooted Nook community has been stagnant for years --
it was a cute proof of concept that, in the end, no one cared about
enough to try to maintain it -- Kobo readers are a lot easier to
hack, and there's a thriving
community on MobileReads which has been trading tips and patches
over the years -- apparently with Kobo's blessing.
The biggest key to Kobo's customizability is that you can mount it as
a USB storage device, and one of the files that exposes is the
device's database (an sqlite file). That means that well supported
programs like Calibre can update shelves/collections on a Kobo, access
its book list, and other nifty tricks; and if you want more, you can
write your own scripts, or even access the database by hand.
I'll write separately about some Python scripts I've written to
display the database and add books to shelves, and I'll just say here
that the process was remarkably straightforward and much easier than
I usually expect when learning to access a new device.
There's lots of other customizing you can do.
There are ways of installing alternative readers on the Kobo, or installing
Python so you can write your own reader. I expected to want that,
but so far the built-in reader seems good enough.
You can also patch the OS. Kobo updates are distributed as tarballs of
binaries, and there's a very well designed, documented and supported
(by users, not by Kobo) patching script distributed on MobileReads for
each new Kobo release. I applied a few patches and was impressed by
how easy it was. And now I have tight line spacing and margins, a
slightly changed page number display at the bottom of the screen
(still only chapter or book, not both), and a search that defaults to
my local book collection rather than the Kobo store.
Stores and DRM
Oh, about the Kobo store. I haven't tried it yet, so I can't report
on that. From what I read, it's pretty good as e-bookstores go,
and a lot of Nook and Sony users apparently prefer to buy from Kobo.
But like most e-bookstores, the Kobo store uses DRM, which makes
it a pain (and is why I probably won't be using it much).
They use Adobe's DRM, and at least Adobe's Digital Editions app works
in Wine under Linux. Amazon's app no longer does, and in case you're
wondering why I didn't consider a Kindle, that's part of it.
Amazon has a bad reputation for
removing rights to previously purchased ebooks
(as well as for spying on their customers' reading habits),
and I've experienced it personally more than once.
Not only can I no longer use the Kindle app under Wine, but Amazon no
longer lets me re-download the few Kindle books I've purchased in the
past. I remember when my mother used to use the Kindle app on Android
regularly; every few weeks all her books would disappear and she'd
have to get on the phone again to Amazon to beg to have them back.
It just isn't worth the hassle. Besides, Kindles can't read public
library books (those are mostly EPUBs with Adobe DRM); and a Kindle
would require converting my whole EPUB library to MOBI. I don't see
any up side, and a lot of down side.
The Adobe scheme used by Kobo and Nook is better, but I still plan to
avoid books with DRM as much as possible. It's not the stores' fault,
and I hope Kobo does well, because they look like a good company.
It's the publishers who insist on DRM. We can only hope that some day
they come to their senses, like music publishers finally did with MP3
versus DRMed music. A few publishers have dropped DRM already, and if
we readers avoid buying DRMed ebooks, maybe the message will
eventually get through.
[ 17:04 Aug 26, 2015
More tech |
permalink to this entry |