Esempio n. 1
0
  def project_point_through_rect_onto_camera(self, point, rect):
    """
    Find pixels covered by projection of a point through a rectangle
    """
    h, w = self.camera_shape
    x1 = w
    x2 = 0
    y1 = h
    y2 = 0

    for corner in rect:
      l = geom.Line.FromPoints(point, corner)
      p = geom.intersect_line_with_plane(l, self.camera_rect)

      x,y = self.point_to_camera_pixel(p)
      x = clamp(int(x+1e-5),0,w-1)
      y = clamp(int(y+1e-5),0,h-1)

      if x < x1:
        x1 = x
      if y < y1:
        y1 = y

      if x > x2:
        x2 = x
      if y > y2:
        y2 = y

    return [x1, y1, x2, y2]
Esempio n. 2
0
    def project_point_through_rect_onto_camera(self, point, rect):
        """
    Find pixels covered by projection of a point through a rectangle
    """
        h, w = self.camera_shape
        x1 = w
        x2 = 0
        y1 = h
        y2 = 0

        for corner in rect:
            l = geom.Line.FromPoints(point, corner)
            p = geom.intersect_line_with_plane(l, self.camera_rect)

            x, y = self.point_to_camera_pixel(p)
            x = clamp(int(x + 1e-5), 0, w - 1)
            y = clamp(int(y + 1e-5), 0, h - 1)

            if x < x1:
                x1 = x
            if y < y1:
                y1 = y

            if x > x2:
                x2 = x
            if y > y2:
                y2 = y

        return [x1, y1, x2, y2]
Esempio n. 3
0
    def mockup_calibration_matrix(self, dx=0.5, dy=0.5):
        """
    Create a theoretical calibration matrix for the designed spectrometer
    geometry.
    """
        h, w = self.camera_shape
        calib = np.zeros((h, w))

        d0 = lattice_constants[self.xtal_type]
        # XXX this assumes the crystal is cubic (all that we currently use are)
        #     it would be good to generalize this though
        d = d0 / norm(self.xtal_cut)

        images = self.image_points()
        bounds = []

        pixels = self.camera_pixel_locations(dx, dy)

        # find image points and xtal projection boundaries
        for xtal_plane, image, entrance_aperture in izip(
                self.xtal_rects, images, self.entrance_aperture):
            exit_projection = self.project_point_through_rect_onto_camera(
                image, self.exit_aperture)

            active_region = [
                geom.intersect_line_with_plane(
                    geom.Line.FromPoints(self.sample, corner), xtal_plane)
                for corner in entrance_aperture
            ]

            active_projection = self.project_point_through_rect_onto_camera(
                image, active_region)

            x1 = max(exit_projection[0], active_projection[0])
            y1 = max(exit_projection[1], active_projection[1])
            x2 = min(exit_projection[2], active_projection[2])
            y2 = min(exit_projection[3], active_projection[3])

            bounds.append([x1, y1, x2, y2])
            rw = x2 - x1
            rh = y2 - y1

            dn = pixels[y1:y2, x1:x2].reshape((rw * rh, 3)) - image
            length = np.sqrt((dn**2).sum(1))
            cos_theta = np.abs((dn * xtal_plane.n).sum(1)) / length
            energy = HC / (2 * d) / cos_theta
            energy = energy.reshape((rh, rw))

            calib[y1:y2, x1:x2] = energy

        self.images = images
        self.projection_bounds = bounds
        return calib
Esempio n. 4
0
  def mockup_calibration_matrix(self, dx=0.5, dy=0.5):
    """
    Create a theoretical calibration matrix for the designed spectrometer
    geometry.
    """
    h,w = self.camera_shape
    calib = np.zeros((h,w))

    d0 = lattice_constants[self.xtal_type]
    # XXX this assumes the crystal is cubic (all that we currently use are)
    #     it would be good to generalize this though
    d = d0 / norm(self.xtal_cut)

    images = self.image_points()
    bounds = []

    pixels = self.camera_pixel_locations(dx,dy)

    # find image points and xtal projection boundaries
    for xtal_plane, image, entrance_aperture in izip(self.xtal_rects, images, self.entrance_aperture):
      exit_projection = self.project_point_through_rect_onto_camera(image, self.exit_aperture)

      active_region = [
          geom.intersect_line_with_plane(
            geom.Line.FromPoints(self.sample, corner),
            xtal_plane
            )
          for corner in entrance_aperture
          ]

      active_projection = self.project_point_through_rect_onto_camera(image, active_region)

      x1 = max(exit_projection[0], active_projection[0])
      y1 = max(exit_projection[1], active_projection[1])
      x2 = min(exit_projection[2], active_projection[2])
      y2 = min(exit_projection[3], active_projection[3])

      bounds.append([x1,y1,x2,y2])
      rw = x2-x1
      rh = y2-y1

      dn = pixels[y1:y2, x1:x2].reshape((rw*rh,3)) - image
      length = np.sqrt((dn**2).sum(1))
      cos_theta = np.abs((dn*xtal_plane.n).sum(1)) / length
      energy = HC / (2 * d) / cos_theta
      energy = energy.reshape((rh,rw))

      calib[y1:y2,x1:x2] = energy

    self.images = images
    self.projection_bounds = bounds
    return calib
Esempio n. 5
0
    def calculate_projection_bounds(self):
        """
    Determine exposed region on camera from each xtal.

    Finds projection of specular radiation from source point
    through entrance aperture, off xtal, through exit aperture
    and onto camera.

    For now, this finds top left and bottom right corners (in camera coords)
    and assumes region to be rectangular.

    TODO: should be easy to extend this to calculate full trapezoidal region
          or, could add option to give largest rect inside, or smallest rect
          outside...
    """

        bounds = []
        images = self.image_points()

        for xtal_plane, image, entrance_aperture in izip(
                self.xtal_rects, images, self.entrance_aperture):
            # project image points through exit aperture onto camera
            exit_projection = self.project_point_through_rect_onto_camera(
                image, self.exit_aperture)

            # find region of crystals exposed by source
            active_region = [
                geom.intersect_line_with_plane(
                    geom.Line.FromPoints(self.sample, corner), xtal_plane)
                for corner in entrance_aperture
            ]

            # project images through active region on to camera
            active_projection = self.project_point_through_rect_onto_camera(
                image, active_region)

            # "intersect" (not complete intersection... see TODO above)
            x1 = max(exit_projection[0], active_projection[0])
            y1 = max(exit_projection[1], active_projection[1])
            x2 = min(exit_projection[2], active_projection[2])
            y2 = min(exit_projection[3], active_projection[3])

            # add it to the list
            bounds.append([x1, y1, x2, y2])

        return bounds
Esempio n. 6
0
  def calculate_projection_bounds(self):
    """
    Determine exposed region on camera from each xtal.

    Finds projection of specular radiation from source point
    through entrance aperture, off xtal, through exit aperture
    and onto camera.

    For now, this finds top left and bottom right corners (in camera coords)
    and assumes region to be rectangular.

    TODO: should be easy to extend this to calculate full trapezoidal region
          or, could add option to give largest rect inside, or smallest rect
          outside...
    """

    bounds = []
    images = self.image_points()

    for xtal_plane, image, entrance_aperture in izip(self.xtal_rects, images, self.entrance_aperture):
      # project image points through exit aperture onto camera
      exit_projection = self.project_point_through_rect_onto_camera(image, self.exit_aperture)

      # find region of crystals exposed by source
      active_region = [
          geom.intersect_line_with_plane(
            geom.Line.FromPoints(self.sample, corner),
            xtal_plane
            )
          for corner in entrance_aperture
          ]

      # project images through active region on to camera
      active_projection = self.project_point_through_rect_onto_camera(image, active_region)

      # "intersect" (not complete intersection... see TODO above)
      x1 = max(exit_projection[0], active_projection[0])
      y1 = max(exit_projection[1], active_projection[1])
      x2 = min(exit_projection[2], active_projection[2])
      y2 = min(exit_projection[3], active_projection[3])

      # add it to the list
      bounds.append([x1,y1,x2,y2])

    return bounds