Working with Images

The henrietta package contains some tools for reading images from a variety of file formats, displaying images, and making some very simple image analyses. This page summarizes the use of some of those tools.

In [1]:
import henrietta as hsl
import matplotlib.pyplot as plt
Created TAP+ (v1.0.1) - Connection:
        Host: gea.esac.esa.int
        Use HTTPS: False
        Port: 80
        SSL Port: 443

Reading and Writing Images

Astronomers often store images as FITS files. Less nerdy humans often store images as JPGs, PNGs, or GIFs. Ideally, we’d like to be able to play with all of these on equal footing. First, we can read an image in as a grayscale:

In [2]:
gray = hsl.read_gray('_static/rainbow.jpg')
print('The "gray" image is a {}, with shape of {}.'.format(type(gray), gray.shape))
read a (1041, 1280) grayscale image from _static/rainbow.jpg
The "gray" image is a <class 'numpy.ndarray'>, with shape of (1041, 1280).

That command read the image file in as a single image, with one number for the brightness of each pixel. Many images are in color. That means they actually contain three independent images inside them, one each for red, green, and blue. We can read these three separate images with the following:

In [3]:
r, g, b = hsl.read_rgb('_static/rainbow.jpg')
print('The "r" image is a {}, with shape of {}.'.format(type(r), r.shape))
print('The "g" image is a {}, with shape of {}.'.format(type(g), r.shape))
print('The "b" image is a {}, with shape of {}.'.format(type(b), r.shape))
read a (1041, 1280, 3) RGB image from _static/rainbow.jpg
The "r" image is a <class 'numpy.ndarray'>, with shape of (1041, 1280).
The "g" image is a <class 'numpy.ndarray'>, with shape of (1041, 1280).
The "b" image is a <class 'numpy.ndarray'>, with shape of (1041, 1280).

There’s also a simple wrapper to load in FITS images in a similar way:

In [4]:
anothergray = hsl.read_fits('_static/rainbow.fits')
print('The "anothergray" image is a {}, with shape of {}.'.format(type(anothergray), anothergray.shape))
read a (1041, 1280) grayscale image from _static/rainbow.fits
The "anothergray" image is a <class 'numpy.ndarray'>, with shape of (1041, 1280).

If we have an array, we can save it out to an image file too. The write_image function will do a pretty good job of figuring out the right way to save the image, based on the file extension you give it. For example, it will try to save as a JPG if your filename is image.jpg; it will try to save as a FITS if your filename is something.fits.

In [ ]:
hsl.write_image(gray, filename='test.jpg')
In [ ]:
hsl.write_image(gray, filename='test.fits')

If we want to save as a color image, we have to compile three images into one file with the right shape. compile_rgb is a simple tool to help with that.

In [ ]:
rgb = hsl.compile_rgb(r, g, b)
hsl.write_image(rgb, filename='colorful-test.png')

Being able to read and write images is a nice way to connect analyses you do in Python of collecting data (for example, taking a picture!) and with ways of sharing and visualizing imaging data.

Displaying Images

Images are simply two-dimensional arrays of numbers, with a value associated with each pixel. The plt.imshow function is great for displaying this kind of data, as shown in the following examples.

In [5]:
plt.figure(dpi=200)
plt.imshow(gray, cmap='gray')
plt.colorbar();
_images/images_15_0.png

We can display each of the red, green, and blue images in the same way.

In [ ]:
plt.figure(dpi=200)
plt.imshow(r, cmap='gray')
plt.title('(just the red)')
plt.colorbar();
In [ ]:
plt.figure(dpi=200)
plt.imshow(g, cmap='gray')
plt.title('(just the green)')
plt.colorbar();
In [ ]:
plt.figure(dpi=200)
plt.imshow(b, cmap='gray')
plt.title('(just the blue)')
plt.colorbar();

With these independent channels, we can combine the brightness in each of three colors into a single color image. The display_rgb function is designed to show how that process works.

In [6]:
hsl.display_rgb(r, g, b)
_images/images_21_0.png

The top panels show the brightness in each of the RGB channels as a simple grayscale. The middle panels show what those monochromatic images would look like if projected in red, green, or blue light. The bottom panel shows what we get when we superpose the three RGB color images, combining the contributions of each to each pixel. (I wonder what a rainbow looks like without the red light…)

Analyzing an Image

One of the basic questions we might ask about an image is “How bright is that thing in it?” We can see that visually by looking at the brightness of pixels by eye, but what if we wanted to combine all the light from a single object into one number? The simplest way to do that would be to sum all its pixels together. The Loupe tool provides a simple way to do this “aperture photometry” on an image.

In [7]:
%matplotlib notebook
import henrietta as hsl
In [8]:
# create a test image
stars = hsl.simulate_image('GJ 1132', pixelscale=2.0)
SELECT source_id,ra,ra_error,dec,dec_error,pmra,pmra_error,pmdec,pmdec_error,parallax,parallax_error,phot_g_mean_mag,phot_bp_mean_mag,phot_rp_mean_mag,radial_velocity,radial_velocity_error,phot_variable_flag,teff_val,a_g_val FROM gaiadr2.gaia_source WHERE CONTAINS(POINT('ICRS',gaiadr2.gaia_source.ra,gaiadr2.gaia_source.dec),CIRCLE('ICRS',153.71574311399957,-47.15671937038528,0.035355339059327376))=1 and phot_g_mean_mag < 20
querying Gaia DR2, centered on <SkyCoord (ICRS): (ra, dec) in deg
    (153.71574311, -47.15671937)> with radius 127.27922061357854 arcsec, for G<20

In the above cell, we made a simulated image. Below, we’ll run an interactive tool to measure the total brightness integrated over circular apertures. To measure the brightness of your star, hover your mouse over the star, and press a on the keyboard, to add an aperture. If you don’t like where it is, you can zap that aperture by pressing z.

In [12]:
p = hsl.Loupe(stars)
Please [a]dd or [z]ap an aperture at the cursor location.

You can then access out a table of all the results through the loupe’s measurements attribute.

In [ ]:
p.measurements

Play around! We may keep adding some bells and whistles to this tool, but the general interface will likely stay generally similar.