And so the detection of bright and dark spots on an image taken from JPEG started.
On this enlarged fragment of the source image you can see the blur and noise I am standing against.
Bright spots
First step to detect any bright spot is to find local brightness maximums (pixels that are brighter than their surrounding pixels).
Then it must be determined whether it is a blurred dot (interested), a spill (not interested) or a noise (not interested).
I didn't make much elaborate detection mechanism in this. I just took close area surrounding the local maximum, calculated the average brightness of pixels in specific distances, and compared that with increasing distance from the maximum the brightness of pixels is decreasing. If yes, the local maximum is a center of blurred point.
byte pixelBrightness = pixel[ R ] * 0.2126f
+ pixel[ G ] * 0.7152f
+ pixel[ B ] * 0.0722f;
...
if ( pixelBrightness > maxSurroundingBrightness // Check there is no pixel around brighter than this one
&& avgCloseSurroundingBrightness > avgFarSurroundingBrightness // Check the brightness is reducing with greater distance
&& 0.9f * pixelBrightness > avgFarSurroundingBrightness ) // Checks the brightness difference is large enough enought (i.e. filters out a noise)
{
/// code for adding star
}
Dark spots
Now this was a challenge. Here are no dots I could easily detect (and if yes, they aren't interesting for my purpose). Everything - noise, areas between arms, areas outside the Galaxy, areas of dust - are dark spills. The only clue for detecting the dust I had was the color tone. The dust on the image is reddish or brownish, while other areas are bluish. So here I was reading color channels and comparing them against each other. The supperiority of red appeared to not immediatelly mean a red dust, but it could be an orange core, or some bright dot that was more to the orange. To filter this out I added weights for each color and later also a top limit for overall brightness of pixel, securing I will take areas that are much more reddish, but not too bright to be a dust. At the end I discovered that some dust areas are more blue than red and had to tweak the weights even more.
if ( 1.03f * pixel[ R ] >= pixel[ B ] // Allowing little blue tone
&& 1.25f * pixel[ R ] >= pixel[ G ] // Allowing some orange tone
&& pixel[ R ] > MIN_PIXEL_BRIGHTNESS_FOR_DUST // Avoid black color (and its noise)
&& pixelBrightness < MAX_PIXEL_BRIGHTNESS_FOR_DUST ) // Avoid white color
{
/// code for adding dust
}
Finally the image was parsed with a relatively satisfying result:
On the left is a small fraction of the Galaxy where I was testing the detection. You can see the white pixels hitting the blurred white spots.
On the right is a test of full galaxy - white pixels representing bright spots, red pixels tracking the dust in arms.
(Because of drawing performace only every 10th red dot is displayed)