Masks are already possible in Siril

Playing with Siril, I think I’ve found a way to work with masks, thanks to the new command ‘iif’. It’s somewhat tedious because it’s by hand but… it’s a way. Perhaps it’s already known, but I didn’t find it elsewhere, and I thought it could be useful. The algorithm is:

  1. Extract the three channels of the RGB image (we’ll name them Ci)
  2. Extract the luminance (M) of the RGB image (from LAB color space)
  3. Modify M as you need to build the mask and save it
  4. For each channel
    a. In PixelMath, using single channel checked, add files Ci and M as variables, and operate Ci * M (we’ll name it R)
    b. Operate some transformation to R, with PixelMath o without it (for instance GHT)
    c. Save the result R
    d. In PixelMath, using single channel checked, add files Ci, M and R as variables, and operate iif(M>0, R, R+(Ci * ~M))
    e. Save the modified channel

And, is it possible to build a mask in Siril? Well, it depends on what you want. Some simple masks can be done.

  1. Luminance mask: Extract the luminance from LAB color space. With histogram transform handle the sliders to increase the signal of stars and nebulas. In PixelMath, invert the luminance (~). You should blur it afterwards (command gauss –sigma or wavelet transform, see later). You could handle background with this mask.
  2. Thresholded luminance: Extract the luminance from LAB color space. Suppose we accept that shadows are included in the interval [0-0.3] and lights are included in the interval [0.7-1], we can select to work only with midtones with iif(R<0.3 || R>0.7, 0, R), with the shadows with iif(R<0.3, R, 0), and with lights with iif(R>0.7, R, 0). You should blur it afterwards (command gauss –sigma or wavelet transform, see later).
  3. Stars mask with histogram transform: Extract the luminance from LAB color space. In PixelMath, invert the luminance (~). With histogram transform put midtones slider too far to the left to isolate stars and apply. You should blur it afterwards (command gauss –sigma or wavelet transform, see later).
  4. Stars mask with á trous wavelets transform: Extract the luminance from LAB color space. Open wavelets transform, put 6 layers and type BSpline (exponential), and analyse the luminance (for each layer put its slider in 1 and all the others in 0, and observe which structures contains); stars are few pixels structures and they are usually contained in the first layers. If you put sliders in these layers in 1, and the others in values <1 (or 0), all the structures disappear except stars. Prove to delete first layer (slider in 0), where usually stay the noise; if there is no change for the stars, keep the change. Continue modeling increasing non-zero layers to increase the signal of the stars. Finally apply. Close wavelets transform and reopen it to blur the mask and enlarge the stars; 6 layers, BSpline, delete first layer, put second layer slider in 0.01 and the third in 0.1 (it is an example, with wavelets you must prove everythin), and apply. Optionally, open histogram transform and increase black point slightly to delete the smaller dimmer stars. Then, in PixelMath invert the image (~).
  5. Nebula mask: Substract stars mask to an intact luminance of the original image. You should blur it afterwards (command gauss –sigma or wavelet transform after analyse where are the large structures).

Unfortunately there is no utility to compare original image and masks to know how well the masks cover the structures that we want to protect. So you still need to have other software open to perform some steps, such as fine-tuning the mask to the image (with curves or filters such as erosion/dilation). Wavelet transform also need some improvements.


As this is an 11 month old post, just checking if you are still available to discuss. For instance I am curious about the 4d operation, why that particular form, why not iif(M>0, R, Ci) ?

BTW, Thanks for your post very informative!

As you know, in a PixInsight type mask, black protects from any changes and white allows modifications. In the explanation we have separated the 3 RGB channels as C1, C2 and C3 (Ci). Suppose we use C1; If we multiply it by the mask, whatever is 1 in the mask will be equal to C1, whatever is 0 will turn C1 into 0 (without the possibility of being modified, that is, protected), and whatever is between the two will give an intermediate value . Any product or exponential operation will leave the areas set to 0 intact. Any value above 0 will have been transformed and we want to preserve that transformation. Therefore now to go back with the mask and remove it, any value above 0 will be part of the new channel, but the values ​​set to 0 must be recovered to their original value, and we do this with the operation R+(C1 * ~ M): C1 * ~M is everything that we wanted to protect with its real value (and that replaces everything in R that is 0 with the mask) and everything that we wanted to modify set to 0 or with intermediate values ​​(different degrees of protection ).

1 Like

Thanks for your reply, I’m going to have to work thru this with some sample data, I think my confusion is since R(i) = C(i) *M; C(i) remains intact after masking, so we don’t need to back out the operation (via C(i) *~M ) when reconstructing the final image. But I’ll try it both ways to learn from experience.

Again thanks, your post was very informative. I have been exploring how to perform masking with filter/NR operators within Siril, and found it challenging.

I can see that you and Gbert are fluent (or at least far beyond me) in Pixelmath. I have been using it at a very basic level to blend narrowband SHO images. Are either of you aware of any good tutorials or sites where I can learn more? Most of what I see are discussion oriented to Pixinsight and can be helpful, but I would prefer to find discussions that use the Siril implementation. The more basic, the better. This math stuff is hard. :slight_smile:

Here a tutorial dedicated to the pixel math tool of Siril

1 Like

Thanks. I will get on this right away.