Astrophotographic denoising without machine learning

brainandforce
Wed, 19 Nov 2025 10:21:04 +0000
Signal and Image Processing

I’m on a quest to approach the hobby of astrophotography from a data science perspective. I’ve put several restrictions on myself (all processing is done with free software, no machine learned tools are allowed) because necessity is the mother of invention. And, honestly, I prefer my image processing tools to not be black boxes or subject to biases from training data.

I’ve found myself a bit dissatisfied with the denoisers that are readily available with the software I use, and I thought it would be interesting idea to not only implement described denoising methods in Julia, but try to build a denoising tool that is specifically designed for astrophotographers and their unique imaging techniques and processing needs.

The method I want to develop should:

assume the image is linear. This would be something run before stretching the image.

deal with shot (Poisson) noise as the dominant noise contribution. Most denoising algorithms are designed with additive white Gaussian noise in mind, which is not a good model for the noise in an astrophotograph. However, sky backgrounds (and thus the magnitude of shot noise) can vary due to differences in skyglow (the moon, light pollution, etc.).

be maximally informed by the collected data. We have access to not just an image, but many images (including calibration frames), so we can work with more statistical descriptors (such as pixel variance/standard deviation, skewness, etc.)

account for properties of the optical system, if known. It’s very easy to construct a point spread function from images of stars, or even from just knowing what optical system was used. Some denoisers (like TV) are good at preserving edges, but that may not make a lot of sense in the context of an oversampled image, where there is a limit to how sharp an edge can be.

I’ve been working on an implementation of total generalized variation denoising since it’s a pretty reliable method , and so far it kinda works? If I allow too many iterations, my stars turn into literal button cells though (probably because the stars are being treated as discontinuities in the image rather than smoothly varying, or more likely because I’ve done something very wrong in my implementation - any insights are appreciated):

I do find it interesting that it seems to blow all stars up to roughly the same size, regardless of their magnitude. Either way, I feel like TGV denoising is a good standard to hold any new method to.

12 posts - 5 participants

Read full topic