Reputation: 318
I am working on simulation of stars on top of an image. The image is a grayscale matrix that is generated with normal distribution (mean, standard deviation). Now, given the pixel coordinates and star SNR I have to plant it as point source on top of image. Any suggestions how can I implement it such that it will be a useful simulation ? Can you suggest code samples ? I am developing in C++ but Matlab/pseudocode will be good also. thanks in advance
Upvotes: 1
Views: 92
Reputation: 60810
A star can be considered a point source. The optical system of the telescope/camera, if ideal optics, will project an Airy disk onto the imaging plane (film, CCD, what have you). Thus, you should generate an Airy disk and add it to the existing pixel values (multiple nearby stars will have overlapping disks, which should be added together).
I would simply generate this function and sample it at the pixel coordinates. Note that the Airy disk will get really close to zero at relatively short distances from the center, so you can define a small region, say 7x7 pixels, around this center where you evaluate the function. This will save a lot of computation.
To further simplify the implementation and the computational cost, you can approximate the Airy disk with a Gaussian. Note that any imperfection in the imaging optics (including the atmosphere) causes the projected dot to be less like an Airy disk and more like a Gaussian, so this is not at all a bad approximation.
Using DIPlib (I’m an author) you can add a Gaussian dot to an image with a call to dip::DrawBandlimitedPoint
:
constexpr std::size_t N = 10;
double coordinates[N][2] = {...};
double magnitudes[N] = {...};
dip::Image image({1024,1024});
for (std::size_t ii=0; ii<N; ++ii) {
dip::DrawBandlimitedPoint(image, {coordinates[ii][0], coordinates[ii][1]}, {magnitudes[ii]}, {1.0});
}
The {1.0}
in that function call is the sigma of the Gaussian dot. Adjust this value to match the optics you’re simulating. The code generates a single-precision floating-point image. You can convert it to an integer type after appropriate scaling, for example:
image *= 10;
image.Convert(dip::DT_UINT16);
Drawing Airy disks would be a bit more involved.
Upvotes: 2