import numpy import time class SimulatedCamera(): """ Camera simulation for debugging purposes. """ def __init__(self, camera_config = None, size_x=1280, size_y=960, number_of_dead_pixels=100, noise=0.1, beam_size_x=100, beam_size_y=20): """ Initialize the camera simulation. :param size_x: Image width. :param size_y: Image height. :param number_of_dead_pixels: Number of simulated dead pixels. :param noise: How much noise to introduce. :param beam_size_x: Beam width. :param beam_size_y: Beam height. """ self.camera_config = camera_config self.channel_image = None self.width_raw = size_x self.height_raw = size_y self.noise = noise # double {0,1} noise amplification factor self.dead_pixels = self._generate_dead_pixels(number_of_dead_pixels) self.beam_size_x = beam_size_x self.beam_size_y = beam_size_y def _generate_dead_pixels(self, number_of_dead_pixel): dead_pixels = numpy.zeros((self.height_raw, self.width_raw)) for _ in range(number_of_dead_pixel): x = numpy.random.randint(0, self.height_raw) y = numpy.random.randint(0, self.width_raw) dead_pixels[x, y] = 1 return dead_pixels def get_image(self, raw=False): """ Get the simulated image. :param raw: If true, return a simulated camera wihtout the beam (just noise). :return: Camera image. """ if raw: image = numpy.zeros((self.size_y, self.size_x)) else: beam_x = numpy.linspace(-self.beam_size_x + numpy.random.rand(), self.beam_size_x + numpy.random.rand(), self.height_raw) beam_y = numpy.linspace(-self.beam_size_y + numpy.random.rand(), self.beam_size_y + numpy.random.rand(), self.width_raw) x, y = numpy.meshgrid(beam_y, beam_x) image = numpy.exp(-(x ** 2 + y ** 2)) # Add some noise if self.noise: image += numpy.random.random((self.height_raw, self.width_raw)) * self.noise # Add dead pixels image += self.dead_pixels image.clip(0, 0.9, out=image) image *= (numpy.power(2, 16) - 1) return self._get_image(image, raw=raw) def _get_image(self, value, raw=False): if value is None: return None # Convert type - we are using f because of better performance # floats (32bit-ones) are way faster to calculate than 16 bit ints, actually even faster than native # int type (32/64uint) since we can leverage SIMD instructions (SSE/SSE2 on Intels). value = value.astype('u2').astype(numpy.float32) # Shape image value = value[:(self.width_raw * self.height_raw)].reshape((self.height_raw, self.width_raw)) # Return raw image without any corrections if raw: return value if self.camera_config is not None: # Correct image if self.camera_config.parameters["mirror_x"]: value = numpy.fliplr(value) if self.camera_config.parameters["mirror_y"]: value = numpy.flipud(value) value = numpy.rot90(value, self.camera_config.parameters["rotate"]) return numpy.ascontiguousarray(value) simulated_camera = None def new_simulated_camera( camera_config = None, size_x=1280, size_y=960, number_of_dead_pixels=100, noise=0.1, beam_size_x=100, beam_size_y=20): global simulated_camera simulated_camera = SimulatedCamera(camera_config, size_x, size_y, number_of_dead_pixels, noise,beam_size_x, beam_size_y) return simulated_camera def get_image(raw=False): return simulated_camera.get_image(raw)