def add_bkg_ovv(im, proj=p): """ Receive the projected image (RGB) and add it to the overview """ # To handle cases where the projection was faster than subscribing, # we get called at subscription. If we receive None, we just need # to be a little bit more patient. if im is None: return if isinstance(proj.stream, stream.OpticalStream): bkg = self._bkg_opt else: bkg = self._bkg_sem insert_tile_to_image(im, bkg) logging.debug("Added overview projection %s", proj.name.value) # Normally not necessary as the image will not change, and the # projection + stream will go out of scope, which will cause # the VA to be unsubscribed automatically. But it feels cleaner. proj.image.unsubscribe(add_bkg_ovv) del self._bkg_ovv_subs[proj] # We could only do it when _bkg_ovv_subs is empty, as a sign it's # the last one... but it could delay quite a bit, and could easily # break if for some reason projection fails. self._update_ovv()
def _onNewImage(self, _): # update overview whenever the streams change, limited to a frequency of 1 Hz if self.curr_s and self.curr_s.image.value is not None: s = self.curr_s img = s.image.value logging.debug("Updating overview using image at %s", getBoundingBox(img)) if isinstance(s, acqstream.OpticalStream): insert_tile_to_image(img, self.im_opt) elif isinstance(s, acqstream.EMStream): insert_tile_to_image(img, self.im_sem) else: logging.info("%s not added to overview image as it's not optical nor EM", s) self._update_ovv()
def test_image_on_ovv(self): """ Tests insert_tile_to_image function """ # Insert tile into image ovv_im = model.DataArray(numpy.zeros((11, 11, 3), dtype=numpy.uint8)) ovv_im.metadata[model.MD_PIXEL_SIZE] = (1, 1) tile = model.DataArray(255 * numpy.ones((3, 3, 3), dtype=numpy.uint8)) tile.metadata[model.MD_POS] = (-3, 3) tile.metadata[model.MD_PIXEL_SIZE] = (1, 1) ovv_im_new = insert_tile_to_image(tile, ovv_im) # rectangle with edges (-4,4), (-2,4), (-4,2), (-4,2) should be white now # (6,6) is the center, so this corresponds to a rectangle with top left at (2,2) (=(1,1) when counting from 0) numpy.testing.assert_array_equal(ovv_im_new[1:4, 1:4, :], tile) numpy.testing.assert_array_equal(ovv_im_new[5:, 5:, :], numpy.zeros((6, 6, 3))) # Test tile that goes beyond the borders of the image top left ovv_im = model.DataArray(numpy.zeros((5, 5, 3), dtype=numpy.uint8)) ovv_im.metadata[model.MD_PIXEL_SIZE] = (1, 1) tile = model.DataArray(255 * numpy.ones((2, 2, 3), dtype=numpy.uint8)) tile.metadata[model.MD_POS] = ( -3, 3) # top-left corner, one pixel diagonal to start of ovv tile.metadata[model.MD_PIXEL_SIZE] = (1, 1) ovv_im_new = insert_tile_to_image(tile, ovv_im) self.assertEqual(ovv_im_new[0][0][0], 255) # first pixel white (all three dims), rest black numpy.testing.assert_array_equal( ovv_im.flatten()[3:], numpy.zeros(len(ovv_im.flatten()[3:]))) # Test tile that goes beyond the borders of the image bottom right ovv_im = model.DataArray(numpy.zeros((5, 5, 3), dtype=numpy.uint8)) ovv_im.metadata[model.MD_PIXEL_SIZE] = (1, 1) tile = model.DataArray(255 * numpy.ones((2, 2, 3), dtype=numpy.uint8)) tile.metadata[model.MD_POS] = ( 3, -3) # bottom-right corner, one pixel diagonal to end of ovv tile.metadata[model.MD_PIXEL_SIZE] = (1, 1) ovv_im_new = insert_tile_to_image(tile, ovv_im) self.assertEqual(ovv_im_new[4][4][0], 255) numpy.testing.assert_array_equal( ovv_im.flatten()[:-3], numpy.zeros(len(ovv_im.flatten()[3:]))) # Test tile that lies completely outside the overview image ovv_im = model.DataArray(numpy.zeros((5, 5, 3), dtype=numpy.uint8)) ovv_im.metadata[model.MD_PIXEL_SIZE] = (1, 1) tile = model.DataArray(255 * numpy.ones((2, 2, 3), dtype=numpy.uint8)) tile.metadata[model.MD_POS] = (10, -10) tile.metadata[model.MD_PIXEL_SIZE] = (1, 1) ovv_im_new = insert_tile_to_image(tile, ovv_im) numpy.testing.assert_array_equal(ovv_im_new, numpy.zeros((5, 5, 3)))
def test_image_on_ovv(self): """ Tests insert_tile_to_image function """ # Insert tile into image ovv_im = model.DataArray(numpy.zeros((11, 11, 3), dtype=numpy.uint8)) ovv_im.metadata[model.MD_PIXEL_SIZE] = (1, 1) tile = model.DataArray(255 * numpy.ones((3, 3, 3), dtype=numpy.uint8)) tile.metadata[model.MD_POS] = (-3, 3) tile.metadata[model.MD_PIXEL_SIZE] = (1, 1) ovv_im_new = insert_tile_to_image(tile, ovv_im) # rectangle with edges (-4,4), (-2,4), (-4,2), (-4,2) should be white now # (6,6) is the center, so this corresponds to a rectangle with top left at (2,2) (=(1,1) when counting from 0) numpy.testing.assert_array_equal(ovv_im_new[1:4, 1:4, :], tile) numpy.testing.assert_array_equal(ovv_im_new[5:, 5:, :], numpy.zeros((6, 6, 3))) # Test tile that goes beyond the borders of the image top left ovv_im = model.DataArray(numpy.zeros((5, 5, 3), dtype=numpy.uint8)) ovv_im.metadata[model.MD_PIXEL_SIZE] = (1, 1) tile = model.DataArray(255 * numpy.ones((2, 2, 3), dtype=numpy.uint8)) tile.metadata[model.MD_POS] = (-3, 3) # top-left corner, one pixel diagonal to start of ovv tile.metadata[model.MD_PIXEL_SIZE] = (1, 1) ovv_im_new = insert_tile_to_image(tile, ovv_im) self.assertEqual(ovv_im_new[0][0][0], 255) # first pixel white (all three dims), rest black numpy.testing.assert_array_equal(ovv_im.flatten()[3:], numpy.zeros(len(ovv_im.flatten()[3:]))) # Test tile that goes beyond the borders of the image bottom right ovv_im = model.DataArray(numpy.zeros((5, 5, 3), dtype=numpy.uint8)) ovv_im.metadata[model.MD_PIXEL_SIZE] = (1, 1) tile = model.DataArray(255 * numpy.ones((2, 2, 3), dtype=numpy.uint8)) tile.metadata[model.MD_POS] = (3, -3) # bottom-right corner, one pixel diagonal to end of ovv tile.metadata[model.MD_PIXEL_SIZE] = (1, 1) ovv_im_new = insert_tile_to_image(tile, ovv_im) self.assertEqual(ovv_im_new[4][4][0], 255) numpy.testing.assert_array_equal(ovv_im.flatten()[:-3], numpy.zeros(len(ovv_im.flatten()[3:]))) # Test tile that lies completely outside the overview image ovv_im = model.DataArray(numpy.zeros((5, 5, 3), dtype=numpy.uint8)) ovv_im.metadata[model.MD_PIXEL_SIZE] = (1, 1) tile = model.DataArray(255 * numpy.ones((2, 2, 3), dtype=numpy.uint8)) tile.metadata[model.MD_POS] = (10, -10) tile.metadata[model.MD_PIXEL_SIZE] = (1, 1) ovv_im_new = insert_tile_to_image(tile, ovv_im) numpy.testing.assert_array_equal(ovv_im_new, numpy.zeros((5, 5, 3)))
def _update_ovv(self): """ Update the overview image with the currently active stream. """ if self.curr_s and self.curr_s.image.value is not None: s = self.curr_s img = s.image.value if isinstance(s, acqstream.OpticalStream): self.im_opt = insert_tile_to_image(img, self.im_opt) elif isinstance(s, acqstream.EMStream): self.im_sem = insert_tile_to_image(img, self.im_sem) else: logging.info("%s not added to overview image as it's not optical nor EM", s) # Merge optical and sem overview images self.ovv_im = merge_screen(self.im_opt, self.im_sem) # Update display self.upd_stream.update(self.ovv_im) self.canvas.fit_view_to_content()