Dense star fields, as beautiful as they are, can also be very annoying. Whether you’re processing an image of a faint galaxy or of a diffuse nebula, overpowering stars will often make it hard for the target to stand out. One way to address this issue is to completely remove the stars using StarNet++, which of course is at the cost of losing the natural beauty of the stars. A great compromise is to reduce the size of the stars, which is what we’ll cover in this tutorial. Side note : if you have a nVidia graphics card, I highly recommend enabling GPU acceleration for StarNet++, as it will make it run much faster.
Making a good star mask is by far the most important step in star reduction. A bad mask will cause webbing artifacts and will completely destroy the stars.
Step 1 : The first step is to run StarNet++ on a copy of your image (called “Starless”). This image will be used at the end of the tutorial.
Step 2 : Create the actual star mask by subtracting this “Starless” image from the original image with PixelMath. Make sure to check Create new image and set Color space to grayscale (I’ll call this image “StarMask”).
You might notice that the stars that are in front (or behind) bright objects aren’t properly represented in the mask. This is due to the nature of Starnet : it doesn’t simply remove the stars, it also replaces them in a content-aware way. Since we want the stars in the mask to be independent from what’s around them, we need to “equalize” the brightness values of the mask across the image. You could achieve this with a luminance mask and some curves, but in this tutorial I’ll use PixelMath.
Step 3 : Apply the PixelMath expression “mean(Starless*$T,$T)” to the star mask. Check Rescale result and Replace target image.
Notice how muted the stars in the center are on the image on the left.
In order to avoid destroying the stars completely, you will need to protect the star cores. Here’s a way to do it :
Step 4 : Make a copy of your star mask and invert it (Ctrl + I). I’ll call this image “StarCores”.
Step 5 : The black pixels in this image will be protected in the final mask. You may leave this image as is but you can also crush the shadows for better core protection or lift the highlights if you want to target the edges more aggressively. An easy way to achieve this is to use CurvesTransformation.
Step 6 : Create a new mask by using the PixelMath expression “StarMask*StarCores”. This will produce a contours based mask (I’ll call it “ContoursMask”).
A multiscale approach
We’ll get back to the mask but first let me introduce what I mean by “multiscale star reduction”. Often you’ll find yourself with large stars you may not want to reduce – or with small stars you may want to reduce less. In both cases, a multiscale approach is needed to differentiate the stars by their size.
In this tutorial I’ll show you how to protect the big stars but you can then of course adapt this method to protect the small stars instead (more on that later). The idea is to create a second mask that will map where the big stars are, and combine it with the first mask so that the resulting mask doesn’t contain the big stars.
There are several tools in PixInsight that allow you to create such a mask (MultiscaleMedianTransform is one of them), but I found that an approach based on MorphologicalTransformation was the most easy-to-use solution.
Step 1 : Make a copy of the “StarMask” image (not the contours mask !). I’ll call this image “BigStars”. Apply MorphologicalTransformation in Closing mode to it. The key is to change the Structuring Element size to your liking : a small structuring element won’t do much, while a large structuring element will erase the small stars.
This will require some trial and error to get it where you want it, but note that it doesn’t need to perfect (see below)
Step 2 : You now need to binarize this image, since the goal is to completely remove those stars from the final mask. This will also allow you to have greater control over which stars you want to protect. Apply Binarize to “BigStars” with whatever settings you want.
Step 3 : Apply the PixelMath expression “$T*~BigStars” to the “ContoursMask” image. $T is short for [target image], and ~ is the invert operand : you’re multiplying the contours mask with the inverted big stars map, which effectively erases the big stars from the mask.
Now that we have a mask, we can finally reduce the stars. This is actually very straightforward : apply the contours mask to your image and use PixelMath to replace the image with the starless image. The PixelMath expression is simply “Starless”. Feel free to run this process multiple times to get it where you like it.
This is after running the expression twice
Extra : protecting the small stars
The small stars often start to look weird (in a muted way) after multiple iterations, which is why you may want to differentiate them from the other stars in order to reduce them less. The same technique that was used to remove the big stars from the mask can be applied.
Step 1 : Create a copy of “StarMask” (I’ll call it “NotSmallStars”). We’re going to run MorphologicalTransformation in Closing mode again, but this time instead of using a large structuring element, we will use a 3×3 square. The image will contain every star except the small ones.
Step 2 : Binarize the image. I suggest using a 0.01 threshold.
Step 3 : This time, since we want to remove the small stars, we will simply multiply this image with the contours mask (and not the inverted image like we did with “BigStars). Apply the PixelMath expression “$T*NotSmallStars” to the contours mask.
Here’s a comparison showing the effects of those final adjustments
This concludes my tutorial on how to do star reduction. Feel free to contact me on Discord (ForaxX#0335) or Instagram (@thecoldestnights) if you have any questions/comments/suggestions regarding this article.