Nasa’s Jupiter mission Juno just released a bunch of raw images from it’s approach. I found out on Twitter, where else?:
This is a mini guide of how I attempted to extract a single image of Jupiter. On linux. I think. This might actually be wrong, but in the end I wound up with something that looks right, so hopefully it is at least barking in the correct direction.
Step 1. Download images
Download the images. Their site has 5 links to image data and 1 link to metadata. For this we can just get #5 and the metadata
Step 2. Unpack
mkdir juno mv approach_movie_images5.zip juno mv approach_movie_metadata.zip juno cd juno unzip *zip
Step 3 Find a good image.
According to NASAs website, above, some cool images are at this time stamp:
So let’s find what image file that might be in
grep 2016-06-29T20.25 *.json jcijson/JNCE_2016181_00C1586_V01.json: "IMAGE_TIME": "2016-06-29T20:25:02.559", jcijson/JNCE_2016181_00C1586_V01.json: "START_TIME": "2016-06-29T20:25:02.559", jcijson/JNCE_2016181_00C1586_V01.json: "STOP_TIME": "2016-06-29T20:25:33.063",
Ok. So I will try looking in JNCE_2016181_00C1588_V01.png
Step 4. Figure out how the image is stored.
What exactly is JNCE_2016181_00C1588_V01.png ?
$ file JNCE_2016181_00C1588_V01.png JNCE_2016181_00C1588_V01.png: PNG image data, 1648 x 31488, 8-bit grayscale, non-interlaced
Uhm…. so it’s an image file that is 1648 pixels across… and Thirty One Thousand pixels high? That’s nuts.
Step 6. Learn rudimentary NASA-speak
Now, also read NASA’s website above. They link to a paper at http://link.springer.com/article/10.1007/s11214-014-0079-x
Junocam: Juno’s Outreach Camera,Hansen, C.J., Caplinger, M.A., Ingersoll, A. et al. Space Sci Rev (2014). doi:10.1007/s11214-014-0079-x
The important parts are as follows:
- Juno spins around taking pictures that are very very narrow.
- Juno splits images into 128-pixel-tall “Framelets”
- Juno takes images with one giant camera, that has three color filters on different parts of it, Red, Green, and Blue.
- Juno has to ‘bump’ the images up and down a few pixels to correct for blur caused by spinning, this is called TDI or something.
This basically means each “framelet” could be a black and white image, but each black and white image could represent either red, blue, or green. By combining three such black and white images with coloring applied appropriately, you can get a full color image.
Now open up one of the .json metadata files you unpacked from metadata.zip and read it
$ less JNCE_2016181_00C1586_V01.json
The important bits are as follows:
"FILTER_NAME": [ "BLUE", "GREEN", "RED" ], "LINES": 31488, "LINE_SAMPLES": 1648, "RECORD_BYTES": 1648, "SAMPLE_BITS": 8,
Basically this gives some hints. First off, the order of the framelets will be blue, green, red. So the first framelet will be a grayscale image representing blue, the second a grayscale image representing green, and a third for red.
Next it tells us that we are not imagining things, there really are 31488 lines of data, and each line is 1648 pixels wide, and each pixel (called a Sample) is 8 bits. 256 shades of gray.
With this wild guessing, we are ready to move to the next step.
Step 7. Split the image into framelets
Try splitting the 31,000 pixel high image into 128 pixel high chunks.
This is where Web Search and ImageMagick come in handy.
$ convert -crop 1648x128 `ls |grep C1588` out%06d.tiff
This produces a bunch of out000001.tiff, out000002.tiff, etc etc. Why .tiff? So I can use image filename filters easily to hit only these framelets instead of my raw Juno .pngs.
Step 8, explore framelets
Any image viewer will do, my favorite tool for this is called “feh”, https://feh.finalrewind.org/ b/c its so fast
$ feh *.tiff
Eventually I find three nice images.
out000056.tiff, out000058.tiff, and out000063.tiff.
Step 9, crop framelets
These files are still way too big! They are still 1600 pixels across, and I only need a few hundred. Again ImageMagick and Web Search help us.
$ convert out000063.tiff -crop 200x128+1000+0 63c.tiff $ convert out000058.tiff -crop 200x128+1000+0 58c.tiff $ convert out000056.tiff -crop 200x128+1000+0 56c.tiff
Step 10, figure out colors
But which should be red, green, and blue?
Here is the trick.
Let’s say you had framelets 0, 1,and 2. Well we know what the order of colors is supposed to be from the JSON metadata. It is supposed to be
So 0 would be Blue, 1 would be Green, and 2 would be Red. This pattern repeats for all numbers, like 3 would be Blue again. 5 would be… well, 5 divide by 3, has remainder 2, so it would be same as 2, which is Red.
Framelet 0 Blue,
Framelet 1 Green,
Framelet 2 Red,
Framelet 3 Blue,
Framelet 4 Green,
Framelet 5 Red,
Framelet 6 Blue,
etc etc etc
Now let’s use Remainder, aka Modular Arithmetic, to figure out where 56, 58, and 63 fall in the pattern.
$ python Python 2.7.11+ (default, Apr 17 2016, 14:00:29) [GCC 5.3.1 20160413] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> print (56%3,58%3,63%3) (2, 1, 0)
OK. So, 56 is remainder 2, which is Red, 58 is remainder 1, which is Green, and 63 is remainder 0, which is Blue. In math language they might say
Some people pronounce the three line thing as “is congruent to”.
Anyways, our grayscale images should be like this
This kind of make sense! If you look at the red image close enough, you can see the Great Spot. This spot is much weaker or invisible in the blue and green images… after all it is the Great Red Spot and there isn’t much green or blue in it.
Step 11, make colors happen
Again, Imagemagick and Web search
convert -combine 56t.tiff 58t.tiff 63t.tiff outjup.tiff
But here is the tricky bit.
ImageMagick convert expects the images to be in order of RGB, or Red Green Blue. So that is why we are careful above to flip the order around.
ImageMagick RGB -> 56= red, 58 = green, 63 = blue
But what is our output? Well it’s a bit like this:
Wow, that’s not what we wanted! Looks like some kinda crazy interdimensional stoplight.
Step 12, slide the images together
The images are offset improperly, either because I have no idea what I’m doing when I split them, or because of TDI bumping rows up and down to compensate for the spin blur.
So let’s fix it. If you have photoshop or know some other good picture manipulation program, that is probably easy. But you can also use the command line, and, again, Imagemagick
$ convert 63c.tiff -scale 800% 63s.tiff $ convert 58c.tiff -scale 800% 58s.tiff $ convert 56c.tiff -scale 800% 56s.tiff $ convert 63s.tiff -page +20+100 -background none -flatten 63t.tiff #blue $ convert 58s.tiff -page +18-491 -background none -flatten 58t.tiff #green $ convert 56s.tiff -page -2-176 -background none -flatten 56t.tiff #red $ convert -combine 56t.tiff 58t.tiff 63t.tiff outjup.tiff
This is basically nudging each of the three images around a bit, then running Combine on them all. It takes a bit of trial and error, in fact those commands are better put into a bash script like so
convert out000063.tiff -crop 200x128+1000+0 63c.tiff convert out000058.tiff -crop 200x128+1000+0 58c.tiff convert out000056.tiff -crop 200x128+1000+0 56c.tiff convert 63c.tiff -scale 800% 63s.tiff convert 58c.tiff -scale 800% 58s.tiff convert 56c.tiff -scale 800% 56s.tiff convert 63s.tiff -page +20+100 -background none -flatten 63t.tiff #blue convert 58s.tiff -page +18-491 -background none -flatten 58t.tiff #green convert 56s.tiff -page -2-176 -background none -flatten 56t.tiff #red convert -combine 56t.tiff 58t.tiff 63t.tiff outjup.tiff feh outjup.tiff
Then you can repeatedly run the script
$ bash ./convert.bash
Step 13. Result
Well, I can’t say it’s perfect, the edges have some blue and red mismatch. But it’s at the very least, a nice shade of brown.
Zoomed in you can really see the flaws of trying to combine red, green, and blue that are not exact. Especially at the edges of the planet.
But anyways… at least it looks a bit like Jupiter! Hope you liked this, thanks for reading.