Hi David,
You can certainly get a long way with cellphone photographs these days. Especially wide-field astrophotos like this. Your raw DNG file has all the required information. To bring out some of the detail you need to adjust some of the parameters that influence the histogram of intensity values.
You may want to start by seeing what exactly you can import from your DNG file:
Import["andromeda-raw-original.DNG", "Elements"]
This will give you a list of all the available import elements for this particular file.
{"BitDepth", "CameraTopOrientation", "Channels", "ColorProfileData", "ColorSpace",
"Data", "DateTime", "EmbeddedThumbnail", "Exif", "FilterPattern", "FlashUsed",
"GeoPosition", "GPSDateTime", "Graphics", "Image", "ImageSize", "MakerNote",
"MetaInformation", "RawData", "RawExif", "RawImage", "RedEyeCorrection",
"Summary", "Thumbnail"}
Lots of metadata! Of these, you might like to try
Import["andromeda-raw-original.DNG", "Summary"]
for a brief summary of primary properties of the image, or you can retrieve any specific properties using
Import["andromeda-raw-original.DNG", {{"DateTime", "GeoPosition"}}]
(Be aware that your GPS location when you took the photo is embedded in the file...)
To get the image we can use
dng = Import["andromeda-raw-original.DNG", "Image"];
The dimensions of the image are
ImageDimensions[dng]
{3024, 4032}
so we see that this is the full 12MP image (3024 x 4032 pixels).
The Mathematica function ImageAdjust
will be useful to shift the histogram of intensity values. Here is the histogram using the null (no adjustment) ImageAdjust
parameters, {0,0,1}
:
ImageHistogram[ImageAdjust[dng, {0, 0, 1}]]
When you run this you will see that most of the image intensity values are less than 0.1 (as you might expect in a mostly black image). We can use a very rough adjustment in order to see some detail. (You will notice that your histogram shows three colours (RGB, in this case) because this DNG has three channels - try ImageChannels[dng]
- the adjustments below may also be applied separately for the different channels.)
So, we'd like to do two things: increase the brightness of the image (basically multiply each pixel intensity value), and adjust the contrast (primarily to shift the blackpoint of this image - although there are other ways to achieve this too).
Firstly, lets just brighten the image:
ImageHistogram[ImageAdjust[dng, {0, 6, 1}]]
You will notice that the histogram is now 'fuller'. Values that ended up larger than 1 are clipped to 1. If you look at the image that this adjustment generates
ImageAdjust[dng, {0, 6, 1}]
you will notice two background features quite easily: the halo in the lower third, and the cloudy glow in the upper third. The halo is an artefact of the image. I'd guess that the sun had just set (~6pm on December 21st) in Seattle, with atmospherically diffracted light possibly causing this optical effect. Other sources are nearby streetlights, etc. Tricky to remove this though without interfering with the neat actual astronomical feature that you captured in the upper third: the Milky Way! (One way to avoid having sun-related optical effects is to take the images well after twilight has ended.)
We can shift the "blackpoint" of the image in a number of ways (to darken the background sky i.e. reduce sensor noise). One possible way is to introduce a contrast adjustment (the first value in the ImageAdjust
parameter list):
ImageHistogram[ImageAdjust[dng, {1.5, 6, 1}]]
or even with a bit of gamma correction
ImageHistogram[ImageAdjust[dng, {1.5, 6, 1.01}]]
The diffraction halo is still very clear, but the Milky Way is now a little clearer too.
You can read more on the parameters in ImageAdjust
here.
Using a combination of functions you can get rid of the halo, but it unfortunately also removes the background Milky Way. For example,
ImageSubtract[dng, 0.03] // ImageAdjust;
processed=ImageAdjust[%, {.4, 4, 1.04}]
will give you a pretty good wide-field view of the stars in your image. (ImageSubtract
has been used here to roughly adjust the blackpoint.)
And for the portion that involves Andromeda,
ImageTake[processed, {2050, 2640}, {660, 1350}]
gives