Пример #1
0
def test_compute_residuals(control_network, sensors):
    # sensor.groundToImage.side_effect = [csmapi.ImageCoord(-0.1, 7.8), csmapi.ImageCoord(0.7, 6.6), csmapi.ImageCoord(1.5, 5.4),
    #                                     csmapi.ImageCoord(2.3, 4.2), csmapi.ImageCoord(3.1, 4.9), csmapi.ImageCoord(5.8, 3.7),
    #                                     csmapi.ImageCoord(6.6, 2.5), csmapi.ImageCoord(7.4, 1.3), csmapi.ImageCoord(8.2, 0.1)]

    sensors['a'].groundToImage.side_effect = [
        csmapi.ImageCoord(-0.1, 7.8),
        csmapi.ImageCoord(5.8, 3.7)
    ]
    sensors['b'].groundToImage.side_effect = [
        csmapi.ImageCoord(0.7, 6.6),
        csmapi.ImageCoord(3.1, 4.9),
        csmapi.ImageCoord(6.6, 2.5)
    ]
    sensors['c'].groundToImage.side_effect = [
        csmapi.ImageCoord(1.5, 5.4),
        csmapi.ImageCoord(7.4, 1.3)
    ]
    sensors['d'].groundToImage.side_effect = [
        csmapi.ImageCoord(2.3, 4.2),
        csmapi.ImageCoord(8.2, 0.1)
    ]

    V = bundle.compute_residuals(control_network, sensors)
    assert V.shape == (18, )
    np.testing.assert_allclose(V, [
        0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, -0.9, -0.8, -0.7, -0.6,
        -0.5, -0.4, -0.3, -0.2, -0.1
    ])
Пример #2
0
def _(dem, image_pt, camera, max_its=20, tolerance=0.001):
    if not isinstance(image_pt, csmapi.ImageCoord):
        # Support a call where image_pt is in the form (x,y)
        image_pt = csmapi.ImageCoord(*image_pt)

    intersection = generate_ground_point(0.0, image_pt, camera)
    iterations = 0
    semi_major, semi_minor = get_radii(camera)
    ecef = pyproj.Proj(proj='geocent', a=semi_major, b=semi_minor)
    lla = pyproj.Proj(proj='latlon', a=semi_major, b=semi_minor)
    while iterations != max_its:
        lon, lat, alt = pyproj.transform(ecef, lla, intersection.x,
                                         intersection.y, intersection.z)

        px, py = dem.latlon_to_pixel(lat, lon)
        height = dem.read_array(1, [px, py, 1, 1])[0][0]

        next_intersection = camera.imageToGround(image_pt, float(height))
        dist = max(abs(intersection.x - next_intersection.x),
                   abs(intersection.y - next_intersection.y),
                   abs(intersection.z - next_intersection.z))

        intersection = next_intersection
        iterations += 1
        if dist < tolerance:
            break
    return intersection
Пример #3
0
def generate_ground_point(dem, image_pt, camera):
    '''
    Generates a longitude, latitude, and altitude coordinate for a given x, y
    pixel coordinate

    Parameters
    ----------
    dem : float or object
          Either a float that represents the height above the datum or a
          GeoDataset object generated from Plio off of a Digital Elevation
          Model (DEM)
    image_pt : tuple
               Pair of x, y coordinates in pixel space
    camera : object
             USGSCSM camera model object
    max_its : int, optional
              Maximum number of iterations to go through if the height does not
              converge
    tolerance : float, optional
                Number of decimal places to solve to when solving for height

    Returns
    -------
    : object
      CSM EcefCoord containing the newly computed lon, lat, and alt values
      corresponding to the original image_pt coordinates
    '''
    if not isinstance(image_pt, csmapi.ImageCoord):
        # Support a call where image_pt is in the form (x,y)
        image_pt = csmapi.ImageCoord(*image_pt)

    return camera.imageToGround(image_pt, dem)
Пример #4
0
def generate_gcps(camera, nnodes=5, semi_major=3396190, semi_minor=3376200):
    ecef = pyproj.Proj(proj='geocent', a=semi_major, b=semi_minor)
    lla = pyproj.Proj(proj='latlon', a=semi_major, b=semi_minor)

    isize = camera.getImageSize()
    isize = [isize.samp, isize.line]
    x = np.linspace(0, isize[1], 10)
    y = np.linspace(0, isize[0], 10)
    boundary = [(i,0.) for i in x] + [(isize[1], i) for i in y[1:]] +\
               [(i, isize[0]) for i in x[::-1][1:]] + [(0.,i) for i in y[::-1][1:]]
    gnds = np.empty((len(boundary), 3))
    for i, b in enumerate(boundary):
        gnd = camera.imageToGround(csmapi.ImageCoord(*b), 0)
        gnds[i] = [gnd.x, gnd.y, gnd.z]
    lons, lats, alts = pyproj.transform(ecef, lla, gnds[:, 0], gnds[:, 1],
                                        gnds[:, 2])
    lla = np.vstack((lons, lats, alts)).T

    tr = zip(boundary, lla)

    gcps = []
    for i, t in enumerate(tr):
        l = '<GCP Id="{}" Info="{}" Pixel="{}" Line="{}" X="{}" Y="{}" Z="{}" />'.format(
            i, i, t[0][1], t[0][0], t[1][0], t[1][1], t[1][2])
        gcps.append(l)

    return gcps
Пример #5
0
def generate_latlon_boundary(camera,
                             nnodes=5,
                             semi_major=3396190,
                             semi_minor=3376200,
                             n_points=10):
    '''
    Generates a latlon bounding box given a camera model

    Parameters
    ----------
    camera : object
             csmapi generated camera model

    nnodes : int
             Not sure

    semi_major : int
                 Semimajor axis of the target body

    semi_minor : int
                 Semiminor axis of the target body

    n_points : int
               Number of points to generate between the corners of the bounding
               box per side.

    Returns
    -------
    lons : list
           List of longitude values

    lats : list
           List of latitude values

    alts : list
           List of altitude values
    '''
    isize = camera.getImageSize()
    isize = (isize.line, isize.samp)

    boundary = generate_boundary(isize, nnodes=nnodes, n_points=n_points)

    ecef = pyproj.Proj(proj='geocent', a=semi_major, b=semi_minor)
    lla = pyproj.Proj(proj='latlon', a=semi_major, b=semi_minor)

    gnds = np.empty((len(boundary), 3))

    for i, b in enumerate(boundary):
        # Could be potential errors or warnings from imageToGround
        try:
            gnd = camera.imageToGround(csmapi.ImageCoord(*b), 0)
        except:
            pass

        gnds[i] = [gnd.x, gnd.y, gnd.z]

    lons, lats, alts = pyproj.transform(ecef, lla, gnds[:, 0], gnds[:, 1],
                                        gnds[:, 2])
    return lons, lats, alts
Пример #6
0
def triangulate_ground_pt(cameras, image_pts):
    """
    Given a set of cameras and image points, find the ground point closest
    to the image rays for the image points.

    This function minimizes the sum of the squared distances from the ground
    point to the image rays.

    Parameters
    ----------
    cameras : list
              A list of CSM compliant sensor model objects
    image_pts : list
                A list of x, y image point tuples

    Returns
    -------
     : tuple
       The ground point as an (x, y, z) tuple
    """
    if len(cameras) != len(image_pts):
        raise ValueError(
            "Lengths of cameras ({}) and image_pts ({}) must be the "
            "same".format(len(cameras), len(image_pts)))

    M = np.zeros((3, 3))
    b = np.zeros(3)
    unit_x = np.array([1, 0, 0])
    unit_y = np.array([0, 1, 0])
    unit_z = np.array([0, 0, 1])
    for camera, image_pt in zip(cameras, image_pts):
        if not isinstance(image_pt, csmapi.ImageCoord):
            image_pt = csmapi.ImageCoord(*image_pt)
        locus = camera.imageToRemoteImagingLocus(image_pt)
        look = np.array(
            [locus.direction.x, locus.direction.y, locus.direction.z])
        pos = np.array([locus.point.x, locus.point.y, locus.point.z])
        look_squared = np.dot(look, look)
        M[0] += look[0] * look - look_squared * unit_x
        M[1] += look[1] * look - look_squared * unit_y
        M[2] += look[2] * look - look_squared * unit_z
        b += np.dot(pos, look) * look - look_squared * pos
    return tuple(np.dot(np.linalg.inv(M), b))
Пример #7
0
def generate_latlon_footprint(camera,
                              nnodes=5,
                              semi_major=3396190,
                              semi_minor=3376200):
    ecef = pyproj.Proj(proj='geocent', a=semi_major, b=semi_minor)
    lla = pyproj.Proj(proj='latlon', a=semi_major, b=semi_minor)

    isize = camera.getImageSize()
    isize = [isize.samp, isize.line]
    x = np.linspace(0, isize[1], 10)
    y = np.linspace(0, isize[0], 10)
    multipoly = ogr.Geometry(ogr.wkbMultiPolygon)
    boundary = [(i,0.) for i in x] + [(isize[1], i) for i in y[1:]] +\
               [(i, isize[0]) for i in x[::-1][1:]] + [(0.,i) for i in y[::-1][1:]]
    ring = ogr.Geometry(ogr.wkbLinearRing)
    for i in boundary:
        gnd = camera.imageToGround(csmapi.ImageCoord(*i), 0)
        lons, lats, alts = pyproj.transform(ecef, lla, gnd.x, gnd.y, gnd.z)
        ring.AddPoint(lons, lats)
    poly = ogr.Geometry(ogr.wkbPolygon)
    poly.AddGeometry(ring)
    multipoly.AddGeometry(poly)
    return multipoly
Пример #8
0
 def func(row, args):
     camera = args[0]
     imagecoord = csmapi.ImageCoord(float(row[1]), float(row[0]))
     # An elevation at the ellipsoid is plenty accurate for this work
     gnd = getattr(camera, 'imageToGround')(imagecoord, 0)
     return [gnd.x, gnd.y, gnd.z]