Repaired HSV Separation Script

Bob Andersson

Well-known member
Dec 22, 2012
67
0
Hi folks,

The star colours above might be a bit of a shock to some so I thought it might be useful to rustle up a few line plots. To prepare them I used the RGB "FITS" file, as generated by PixInsight, which had had some preliminary white balancing but, of course, the white balance tweaks I applied later on in Photoshop won't be reflected in the data you are about to view. First I'll set the scene:



This crop is from the final image that left Photoshop and serves purely to show the stars that were sampled. The RGB "FITS" file was passed through my Repaired HSV Separation Script with "Clip Shadows" set at 0.00206 and the "Max Repair Radius" set at 16. The "Repair Level" was set at a very aggressive 0.21685 - in other words I was telling the script that if at any pixel any of the red, green or blue values exceeded that value then the script should attempt to use the colour information from surrounding pixels which were less exposed. On the line plots 0.21685 corresponds roughly to a pixel value of only 14,000!

Here is the result at Line A, quite a blue star:



As with all these plots the vertical scale for the two halves differs. There is something odd going on with my original data at pixels 10 and 11 with the red rather under-represented but with the "Repair Level" set to a pixel value equivalent on the plot of 14,000 the script has looked further out. The relative RGB intensities at pixels 10 and 11 in the repaired plot are much closer to those at pixels 8, 9 and 13 in the original so the script has done its job.

One further point when interpreting these plots. The line plots are just a one dimensional snapshot across various stars so while looking at the relative RGB intensities below the 14,000 cutoff is useful please bear in mind that the script attempts to sample suitable values in a circular search pattern up to, but usually not as far as, the "Max Repair Radius", and doesn't just sample along a one dimensional line.

Now for Line B. This is an orange star on my final JPEG:



It's brighter than the star sampled at Line A so pixels 9, 10 and 11 have all fallen foul of that 14,000 cutoff as can be seen on the "original" section of the plot. On the "repaired" section of the plot it can be seen that the script has again successfully used the RGB proportions further away from the over-exposed core. That has had the effect of reducing both the green and blue values near the core but that is exactly what is intended as it is quite obvious that the sensor is becoming saturated in the original.

Now for the star at Line C:



The same behaviour from the script is evident, with the outlying colour successfully replacing that of the over-exposed core.

Now to the brightest star in the field. Here is the plot for Line D:



The plot from the original data shows just how overexposed the star was. But again I'd argue that the script has done a good job in using a sample of the relative RGB intensities away from the overexposed core. This plot also shows the effect of the script's attempt to repair the intensity (Repaired V). The intensity is only a little more peaked than with the original data but I would rather that than create on obviously artificial result. That intensity repair process also explains why the vertical scales on the two line plots for each star differ as the small increase in luminance for the bright stars results, after the image has been rescaled, in everything else getting a little dimmer.

Finally a couple of "two for the price of one" plots:





Line E is unremarkable except that the same red deficiency that the star at Line A suffered from appears to be evident in the brighter of the two stars and has been corrected. Line F crosses a very red star and the loss of colour at the core of that star has successfully been corrected in the repaired image. It does look very red in that final image but the relative RGB values at pixel 6 (and pixel 9 although that would have been rejected by the script) suggest that the redness is genuine and not an artefact.

I hope this has been useful for those trying to understand what the Repaired HSV Separation Script is all about. I've certainly benefited from preparing the plots.

Bob.

The plots were prepared using an evaluation copy of <Edited by moderator: Advertising of competing software products is not allowed>

Edit: When I published this post earlier today the star identified as Line C had been incorrectly annotated in the opening JPEG. That error has now been corrected and the text updated.
 

Bob Andersson

Well-known member
Dec 22, 2012
67
0
Hi folks,

The main purpose of the Repaired HSV Separation Script is to prepare an HSV separation which is a little more tolerant of loss of sensor linearity and resultant colour shifts in the cores of the brighter stars. The V component reflects the "brightness" and so it can be recombined with the H (Hue) and Sv (Saturation) components after it has been stretched. Typically the resultant image still needs some manual clean-up of the very brightest stars but, as I demonstrated in my last post, without the script a lot more such cleaning would be needed.

There is a question mark hanging over just how well the V image represents brightness, however, as it isn't defined as the sum of the RGB components but as the highest value of any of R, G or B. As a result there is a suspicion that applying a non-linear stretch to V will result in some odd changes. Of course, applying a similar non-linear stretch to a regular RGB image induces significant changes as well so I thought the easiest way to try and lay to rest any fears that stretching a V image, and by association using the Repaired HSV Separation Script as part of the workflow, is inappropriate would be to prepare a comparison:



The script was used to prepare an HSV separation using the same parameters as before but with the "V - no repairs" option checked and it was that V image which was given a regular histogram stretch before being recombined with the (repaired) H and Sv images. Normally I would use a "repaired" V image but I wanted to avoid any extra shifts in pixel brightness other than those induced by the stretch. I also did a regular histogram stretch of the original RGB image. In order to try and make the comparison meaningful I fine tuned the stretches so that most stars were of similar brightness. Processing in Photoshop to produce the animation was identical and minimal for both the regular and V-stretched images so there are some residual issues like poor white balance but the purpose was to provide a valid comparison rather than a pretty picture. I would also typically blend in a small proportion of a stretched version, using the Masked Stretch script, of the "Repaired RGB" that the script produces as without it some of the brighter stars can look a little flat but that's not the purpose of the exercise here.

The loss of star colour in the regular histogram stretch is obvious and, incidentally, is why such a stretch is so tolerant of any loss of sensor linearity at high intensities and any over-exposure. But looking beyond that, and also any residual clean up that is needed in the V-stretched part of the animation, I think it is fair to say that the relative brightnesses of the stars is maintained well enough when following the V-stretch workflow.

Bob.
 

Bob Andersson

Well-known member
Dec 22, 2012
67
0
Hi folks,

I've released a minor update to my Repaired HSV Separation Script - v 1.0.3 is functionally exactly the same as v 1.0.2 but no longer generates the "assigned to undeclared variable" warnings that the stricter PI v 1.8 compiler was issuing.

I've also taken the opportunity to change the file name to "RepairedHSVSeparation.js" in line with the version distributed with PI (the name originally had spaces in it thus: "Repaired HSV Separation.js").

All the download links in this thread have been updated but to save you searching you can download the update from here.

Bob.
 

Torsinadoc

Well-known member
Oct 6, 2013
98
0
I I tried M51 data. When I recombined the stretched repaired V, the new combined image isn't correct (labeled piximathcombined).  No issues with extracting the repaired frames or masked stretch. Now sure what I did wrong

Alan
 

Attachments

Bob Andersson

Well-known member
Dec 22, 2012
67
0
.
Difficult to know - did you use the PI ChannelCombination process using the HSV Color Space to combine the H, Sv and (stretched) V components? Normally I wouldn't ask but as you've labelled the final image "piximathcombined" that raised a question in my mind.

Bob.
 

Bob Andersson

Well-known member
Dec 22, 2012
67
0
Hi folks,

Because the script described in this thread retains the relative intensities of red, green and blue almost perfectly during stretching for each pixel I've had some fairly colourful results so I've been doing some number crunching to help me understand why! Here's a graph showing the normalised sensitivities of my "Astro" filters and a generic Bayer filter. As I'm sure most know, Bayer matrix filters are most commonly found in regular digital cameras such as DSLRs and smartphones.



The "astro" curves were generated from published data for my Astrodon Tru-Balance E filters and have had the sensitivity of my FLI ML16803 camera factored in. The most notable differences are that there is significant overlap in the Bayer responses (dashed lines) while the astro curves (solid lines) have less overlap and a well separated red response. Some astro RGB filter sets have a red response tuned to include slightly shorter wavelengths.

The next stage was to count a lot of virtual photons by splitting the passbands into 10nm chunks and then using the excellent Spectral Calculator here with the following the result:



I've assumed that stars are black body radiators, which isn't a perfect assumption, but I think it allows a meaningful comparison between the star colours as seen through a Bayer matrix and my astro filters. I white balanced the results at 5800K, typical of a G2V star such as the Sun. The spectral types are rough estimates (from this page) - the colours were calculated directly from the assumed temperatures.

Comparing the leftmost two columns it is obvious that the astro filters I use (column A) are better able to generate colour than the Bayer filters (Column B). Referring back to the filter passbands that should be no surprise. The effect on the coolest and hottest objects is quite startling and while I doubt I actually see many (any?) objects as cool as 2000K there are red stars out there, either naturally as with carbon stars or as a result of intervening dust.

My next task was to see whether a simple adjustment on an already stretched image would allow me to "convert" the star colours from my astro filters to those typical of a Bayer matrix. Only done by eye but, using a well known photo-editing program, a Hue/Saturation layer with a saturation setting of -34 and an Exposure layer with a minor Gamma adjustment setting of 1.04 got me close, as I hope can be seen from the rightmost pair of columns. I guess, but haven't verified, that the same adjustment could be done on the linear data using PixInsight but as the stretch preserves the ratios of red, green and blue anyway I am happier making the adjustment, if at all, towards the end of the workflow.

If all an image contains is black body radiators, or reasonable simulacrums thereof, then I'd be done and dusted if, and it's a big if, I wanted to do that conversion all the time but as I think I've shown in the image above an H-alpha emitting region (which typically emits H-beta as well) doesn't respond very gracefully and arguably should be excluded from such manipulation.

All theory so far so how does this work in practice? Here's Albireo, as captured a few days ago and with full-fat colour as delivered by my astro filters and use of the Repaired HSV Separation Script:



And here it is after those saturation and gamma adjustments to emulate what might be seen through a Bayer matrix filter set:



In summary, if you find that using the Repaired HSV Separation Script gives more colourful stars than you think appropriate then have a look at your RGB filter passbands. They might be the cause and if so then it may be that a simple saturation adjustment is all that's needed to emulate a more "natural" view.

Bob.
 

Bob Andersson

Well-known member
Dec 22, 2012
67
0
Hi folks,

As you might guess quite a lot of numbers were needed to create the graph and artificial star colour images in the preceding post. I've at last got around to finding out if there's a way to simulate the response of a terrestrial Bayer filter using data from my TruBalance E RGB filters. The short answer is Yes but there are two health warnings. Firstly, this is specific to my combination of filters and camera, an FLI ML16803, as different filters and cameras will have different response curves. Secondly, the conversion only works well for black-body radiators such as stars.

Here's the recipe:

Code:
To convert black-body colours from those provided by TruBalance E filters in front of
an ML16803 to simulate the colours provided by a typical Bayer matrix sensor use:

	G' = (R + G)/(1 + (R/G)^0.6)
	R' = (R + G) - G'
	B' = G'/((G'/B)^0.7)

	cf = (R + G + B)/(R' + G' + B')

	R'' = cf * R'
	G'' = cf * G'
	B'' = cf * B'

where 	R, G and B are the values from the sensor
	R', G' and B' are intermediate values during the calculation
	cf  is a compensation factor to account for changes is total "brightness"
and	R'', G'' and B'' are the converted values simulating a Bayer matrix sensor

For clarification, (R/G)^0.6 means the value of (R/G) raised to the power 0.6.

The source RGB image should be white balanced beforehand and, of course, the black level should be properly set
The formula above was a combination of perspiration and inspiration. Converting the TruBalance filters' red/green ratio to simulate the Bayer ratio was an easy find. The green/blue conversion was a pig until I realised that I also needed to compensate for any change in "brightness" with the change in the red/green values. For some reason once that was done the relatively simple formula you see above worked a treat. The correspondence between the theoretically derived TruBalance E response after conversion with the (also) theoretically derived Bayer numbers was so good (typically fractions of a percent) that there must be some more basic principle at work but working that out is above my pay grade!  :)

It's possible to use PixelMath to do the sums and that's what I've done to produce the comparison below. At some point in the future a short script will be a time saver.

It all looks very arbitrary but the proof of the pudding is in the eating! Here's Albireo, framed to include some other strongly coloured stars, in a before and after animation.



Both images were prepared using an identical Repaired HSV Separation Script workflow except that the Bayer simulation image was converted using the recipe above before stretching.

If I were to summarise, the Repaired HSV Separation Script workflow is almost too good at preserving colour! It shows up any boost in colour saturation caused by the RGB filters in use having passbands more widely spaced than is normal for a terrestrial camera but, on the plus side, it's a lot easier to tone down the colour later on than it is to try and recover colour that may already have been largely lost. Whether or not to tone down the star colours to values more acceptable to a wider viewing public is a matter of taste.  8)

Bob.
 

stille

Member
Sep 30, 2019
7
2
In the latest PixInsight version(v1.8.8-6), Repaired HSV Separation fails as follows:

Processing script file: /opt/PixInsight/src/scripts/RepairedHSVSeparation.js
*** Error [000]: /opt/PixInsight/src/scripts/RepairedHSVSeparation.js, line 123: Error: Settings.read(): invalid argument type: integer value expected.
 
  • Like
Reactions: akoenig

mchandler1

New member
Aug 16, 2020
3
0
In the latest PixInsight version(v1.8.8-6), Repaired HSV Separation fails as follows:

Processing script file: /opt/PixInsight/src/scripts/RepairedHSVSeparation.js
*** Error [000]: /opt/PixInsight/src/scripts/RepairedHSVSeparation.js, line 123: Error: Settings.read(): invalid argument type: integer value expected.
Did anyone ever respond? Getting that same error on 1.8.8-5 now..