Exemple #1
0
def getGdcTransformFromPixelTransform(imageSize, pixelTransform, refImageGdcTransform):
    '''Converts an image-to-image transform chained with a GDC transform
       to a pixel to GDC transform for this image.'''

    # Convert the image-to-image transform parameters to a class
    temp = numpy.array([tform[0:3], tform[3:6], tform[6:9]] )
    imageToRefTransform = transform.ProjectiveTransform(temp)

    newImageSize = ImageFetcher.miscUtilities.getImageSize(newImagePath)

    # Generate a list of point pairs
    imagePoints = []
    gdcPoints   = []

    # Loop through an evenly spaced grid of pixels in the new image
    # - For each pixel, compute the desired output coordinate
    pointPixelSpacing = (newImageSize[0] + newImageSize[1]) / 20 # Results in about 100 points
    for r in range(0, newImageSize[0], pointPixelSpacing):
        for c in range(0, newImageSize[1], pointPixelSpacing):
            # Get pixel in new image and matching pixel in the reference image,
            #  then pass that into the GDC transform.
            thisPixel       = numpy.array([float(c), float(r)])
            pixelInRefImage = pixelTransform.forward(thisPixel)
            gdcCoordinate   = refImageGdcTransform.forward(pixelInRefImage)

            imagePoints.append(thisPixel)
            gdcPoints.append(gdcCoordinate)

    # Compute a transform object that converts from the new image to projected coordinates
    imageToGdcTransform = transform.getTransform(numpy.asarray(worldPoints),
                                                 numpy.asarray(gdcPoints))

    return imageToGdcTransform
Exemple #2
0
def getPixelToGdcTransform(imagePath, pixelToProjectedTransform=None):
    '''Returns a pixel to GDC transform.
       The input image must either be a nicely georegistered image from Earth Engine
       or a pixel to projected coordinates transform must be provided.'''

    if pixelToProjectedTransform:
        # Have image to projected transform, convert it to an image to GDC transform.

        # Use the simple file info call (the input file may not have geo information)
        (width, height) = IrgGeoFunctions.getImageSize(imagePath)

        imagePoints = []
        gdcPoints = []

        # Loop through a spaced out grid of pixels in the image
        pointPixelSpacing = (width +
                             height) / 20  # Results in about 100 points
        for r in range(0, width, pointPixelSpacing):
            for c in range(0, height, pointPixelSpacing):
                # This pixel --> projected coords --> lonlat coord
                thisPixel = numpy.array([float(c), float(r)])
                projectedCoordinate = pixelToProjectedTransform.forward(
                    thisPixel)
                gdcCoordinate = transform.metersToLatLon(projectedCoordinate)

                imagePoints.append(thisPixel)
                gdcPoints.append(gdcCoordinate)
        # Solve for a transform with all of these point pairs
        pixelToGdcTransform = transform.getTransform(
            numpy.asarray(gdcPoints), numpy.asarray(imagePoints))

    else:  # Using a reference image from EE which will have nice bounds.

        # Use the more thorough file info call
        stats = IrgGeoFunctions.getImageGeoInfo(imagePath, False)
        (width, height) = stats['image_size']
        (minLon, maxLon, minLat, maxLat) = stats['lonlat_bounds']

        # Make a transform from ref pixel to GDC using metadata on disk
        xScale = (maxLon - minLon) / width
        yScale = (maxLat - minLat) / height
        transformMatrix = numpy.array([[xScale, 0, minLon],
                                       [0, -yScale, maxLat], [0, 0, 1]])
        pixelToGdcTransform = transform.LinearTransform(transformMatrix)

    return pixelToGdcTransform
Exemple #3
0
 def updateAlignment(self):
     toPts, fromPts = transform.splitPoints(self.extras.points)
     tform = transform.getTransform(toPts, fromPts)
     self.extras.transform = tform.getJsonDict()
Exemple #4
0
            289.4999999999986
        ],
        [
            -10824770.036926387,
            2994035.003758455,
            335.50000000000034,
            424.50000000000097
        ]
    ]

TO_PTS, FROM_PTS = transform.splitPoints(POINTS)
N = len(POINTS)


def testTransformClass(cls):
    tform = cls.fit(TO_PTS, FROM_PTS)
    toPtsApprox = transform.forwardPts(tform, FROM_PTS)
    #print toPtsApprox
    print ('%s: %e'
           % (cls.__name__,
              numpy.linalg.norm(toPtsApprox - TO_PTS) / N))

testTransformClass(transform.TranslateTransform)
testTransformClass(transform.RotateScaleTranslateTransform)
testTransformClass(transform.AffineTransform)
testTransformClass(transform.ProjectiveTransform)
testTransformClass(transform.QuadraticTransform)
testTransformClass(transform.QuadraticTransform2)

print transform.getTransform(TO_PTS, FROM_PTS)
Exemple #5
0
 def updateAlignment(self):
     toPts, fromPts = transform.splitPoints(self.extras.points)
     tform = transform.getTransform(toPts, fromPts)
     self.extras.transform = tform.getJsonDict()
Exemple #6
0
def qualityGdalwarp(imagePath, outputPath, imagePoints, gdcPoints):
    '''Use some workarounds to get a higher quality gdalwarp output than is normally possible.'''

    # Generate a high resolution grid of fake GCPs based on a transform we compute,
    # then call gdalwarp using a high order polynomial to accurately match our transform.

    #trans = transform.ProjectiveTransform.fit(numpy.asarray(gdcPoints),numpy.asarray(imagePoints))ls 
    trans = transform.getTransform(numpy.asarray(gdcPoints),numpy.asarray(imagePoints))
    transformName = trans.getJsonDict()['type']
    
    tempPath = outputPath + '-temp.tif'
    
    # Generate a temporary image containing the grid of fake GCPs
    cmd = ('gdal_translate -co "COMPRESS=LZW" -co "tiled=yes"  -co "predictor=2" -a_srs "'
           + OUTPUT_PROJECTION +'" '+ imagePath +' '+ tempPath)
    
    # Generate the GCPs in a grid, keeping the total under about 500 points so
    # that GDAL does not complain.
    (width, height) = IrgGeoFunctions.getImageSize(imagePath)
    xStep = width /22
    yStep = height/22
    MAX_DEG_SIZE = 20
    minLon = 999 # Keep track of the lonlat size and don't write if it is too big.
    minLat = 999 # - This would work better if it was in pixels, but how to get that size?
    maxLon = -999
    maxLat = -999
    for r in range(0,height,yStep):
        for c in range(0,width,xStep):
            pixel  = (c,r)
            lonlat = trans.forward(pixel)
            cmd += ' -gcp '+ str(c) +' '+str(r) +' '+str(lonlat[0]) +' '+str(lonlat[1])
            if lonlat[0] < minLon:
                minLon = lonlat[0]
            if lonlat[1] < minLat:
                minLat = lonlat[1]
            if lonlat[0] > maxLon:
                maxLon = lonlat[0]
            if lonlat[1] > maxLat:
                maxLat = lonlat[1]
    #print cmd
    os.system(cmd)
    if max((maxLon - minLon), (maxLat - minLat)) > MAX_DEG_SIZE:
        raise Exception('Warped image is too large to generate!\n'
                        '-> LonLat bounds: ' + str((minLon, minLat, maxLon, maxLat)))

    # Now generate a warped geotiff.
    # - "order 2" looks terrible with fewer GCPs, but "order 1" does not accurately
    #   capture the footprint of higher tilt images.
    # - tps seems to work well with the evenly spaced grid of virtual GCPs.
    cmd = ('gdalwarp -co "COMPRESS=LZW" -co "tiled=yes"  -co "predictor=2"'
               + ' -dstalpha -overwrite -tps -multi -r cubic -t_srs "'
           + OUTPUT_PROJECTION +'" ' + tempPath +' '+ outputPath)
    print cmd
    os.system(cmd)

    # Check output and cleanup
    os.remove(tempPath)
    if not os.path.exists(outputPath):
        raise Exception('Failed to create warped geotiff file: ' + outputPath)

    return transformName
          ],
          [
              -13045724.330780469, 3825669.8715011734, 68.50000000000003,
              289.4999999999986
          ],
          [
              -10824770.036926387, 2994035.003758455, 335.50000000000034,
              424.50000000000097
          ]]

TO_PTS, FROM_PTS = transform.splitPoints(POINTS)
N = len(POINTS)


def testTransformClass(cls):
    tform = cls.fit(TO_PTS, FROM_PTS)
    toPtsApprox = transform.forwardPts(tform, FROM_PTS)
    #print toPtsApprox
    print('%s: %e' %
          (cls.__name__, numpy.linalg.norm(toPtsApprox - TO_PTS) / N))


testTransformClass(transform.TranslateTransform)
testTransformClass(transform.RotateScaleTranslateTransform)
testTransformClass(transform.AffineTransform)
testTransformClass(transform.ProjectiveTransform)
testTransformClass(transform.QuadraticTransform)
testTransformClass(transform.QuadraticTransform2)

print transform.getTransform(TO_PTS, FROM_PTS)