Exemplo n.º 1
0
def colorize(crop_panchro, im_color, x, y, zoom, out_colorized, rmin,rmax):
    """
    Colorizes a Pleiades gray crop using low-resolution color information.

    Args:
        crop_panchro: path to the panchro (ie gray) crop
        im_color: path to the full color image (tiff or jp2)
        x, y: coordinates of the top-left corner of crop_panchro, in the full
            Pleiade image frame.
        zoom: subsampling zoom-factor that was used to generate crop_panchro
        out_colorized: path to the output file
    """
    # get a translated and zoomed crop from the color image. It has to be
    # sampled on exactly the same grid as the panchro crop.
    # To do that we compose the translation + zoom transformation with a 4x
    # zoom (because color pleiades images have 4x lower resolution).  There is
    # also a small horizontal translation (4 pixels at the panchro resolution)
    # The resulting transformation is the composition of:
    #   translation (-1 - x/4, -y/4)
    #   zoom 4/z
    w, h = common.image_size_tiffinfo(crop_panchro)
    xx = np.floor(x / 4.0) 
    yy = np.floor(y / 4.0)
    ww = np.ceil((x + w * zoom) / 4.0) - xx 
    hh = np.ceil((y + h * zoom) / 4.0) - yy
    crop_ms = common.image_crop_TIFF(im_color, xx, yy, ww, hh)
    crop_ms = common.image_zoom_gdal(crop_ms, zoom/4.0)
    # crop_ms = common.image_safe_zoom_fft(crop_ms, zoom/4.0)

    # crop the crop_ms image to remove the extra-pixels due to the integer crop
    # followed by zoom
    x0 = max(0,x - 4*xx)
    y0 = max(0,y - 4*yy)
    crop_ms = common.image_crop_TIFF(crop_ms, x0, y0, w, h)
    assert(common.image_size_tiffinfo(crop_panchro) ==
           common.image_size_tiffinfo(crop_ms))

    # convert rgbi to rgb
    rgb = common.rgbi_to_rgb(crop_ms, out=None, tilewise=True)

    # blend intensity and color to obtain the result
    # each channel value r, g or b is multiplied by 3*y / (r+g+b), where y
    # denotes the panchro intensity
    tmp = common.tmpfile('.tif')
    pcmd = "dup split + + / * 3 *"
    os.environ['TMPDIR'] = os.path.join(cfg['temporary_dir'], 'meta/')
    cmd = 'tiffu meta \"plambda ^ ^1 \\\"%s\\\" -o @\" %s %s -- %s' % (pcmd,
                                                                      crop_panchro,
                                                                      rgb, tmp)
    common.run(cmd)
    if w * h > 25e6:  # image larger than 5000 x 5000 pixels
        common.image_qauto_otb(out_colorized, tmp)
    else:
        #common.image_qauto(tmp, out_colorized)
        common.image_rescaleintensities(tmp, out_colorized, rmin, rmax)
    return
Exemplo n.º 2
0
def colorize(crop_panchro, im_color, x, y, zoom, out_colorized, rmin, rmax):
    """
    Colorizes a Pleiades gray crop using low-resolution color information.

    Args:
        crop_panchro: path to the panchro (ie gray) crop
        im_color: path to the full color image (tiff or jp2)
        x, y: coordinates of the top-left corner of crop_panchro, in the full
            Pleiade image frame.
        zoom: subsampling zoom-factor that was used to generate crop_panchro
        out_colorized: path to the output file
    """
    # get a translated and zoomed crop from the color image. It has to be
    # sampled on exactly the same grid as the panchro crop.
    # To do that we compose the translation + zoom transformation with a 4x
    # zoom (because color pleiades images have 4x lower resolution).  There is
    # also a small horizontal translation (4 pixels at the panchro resolution)
    # The resulting transformation is the composition of:
    #   translation (-1 - x/4, -y/4)
    #   zoom 4/z
    w, h = common.image_size_tiffinfo(crop_panchro)
    xx = np.floor(x / 4.0)
    yy = np.floor(y / 4.0)
    ww = np.ceil((x + w * zoom) / 4.0) - xx
    hh = np.ceil((y + h * zoom) / 4.0) - yy
    crop_ms = common.image_crop_TIFF(im_color, xx, yy, ww, hh)
    crop_ms = common.image_zoom_gdal(crop_ms, zoom / 4.0)
    # crop_ms = common.image_safe_zoom_fft(crop_ms, zoom/4.0)

    # crop the crop_ms image to remove the extra-pixels due to the integer crop
    # followed by zoom
    x0 = max(0, x - 4 * xx)
    y0 = max(0, y - 4 * yy)
    crop_ms = common.image_crop_TIFF(crop_ms, x0, y0, w, h)
    assert (common.image_size_tiffinfo(crop_panchro) ==
            common.image_size_tiffinfo(crop_ms))

    # convert rgbi to rgb
    rgb = common.rgbi_to_rgb(crop_ms, out=None, tilewise=True)

    # blend intensity and color to obtain the result
    # each channel value r, g or b is multiplied by 3*y / (r+g+b), where y
    # denotes the panchro intensity
    tmp = common.tmpfile('.tif')
    pcmd = "dup split + + / * 3 *"
    os.environ['TMPDIR'] = os.path.join(cfg['temporary_dir'], 'meta/')
    cmd = 'tiffu meta \"plambda ^ ^1 \\\"%s\\\" -o @\" %s %s -- %s' % (
        pcmd, crop_panchro, rgb, tmp)
    common.run(cmd)
    if w * h > 25e6:  # image larger than 5000 x 5000 pixels
        common.image_qauto_otb(out_colorized, tmp)
    else:
        #common.image_qauto(tmp, out_colorized)
        common.image_rescaleintensities(tmp, out_colorized, rmin, rmax)
    return
Exemplo n.º 3
0
def plot_matches_pleiades(im1, im2, rpc1, rpc2, matches, x=None, y=None,
        w=None, h=None, outfile=None):
    """
    Plot matches on Pleiades images

    Args:
        im1, im2: paths to full Pleiades images
        rpc1, rpc2: paths to xml files containing the rpc coefficients
        matches: 2D numpy array of size 4xN containing a list of matches (a
            list of pairs of points, each pair being represented by x1, y1, x2,
            y2). The coordinates are given in the frame of the full images.
        x, y, w, h (optional, default is None): ROI in the reference image
        outfile (optional, default is None): path to the output file. If None,
            the file image is displayed using the pvflip viewer

    Returns:
        path to the displayed output
    """
    # if no matches, no plot
    if not matches.size:
        print "visualisation.plot_matches_pleiades: nothing to plot"
        return

    # read rpcs
    r1 = rpc_model.RPCModel(rpc1)
    r2 = rpc_model.RPCModel(rpc2)

    # determine regions to crop in im1 and im2
    if x is not None:
        x1 = x
    else:
        x1 = np.min(matches[:, 0])

    if y is not None:
        y1 = y
    else:
        y1 = np.min(matches[:, 1])

    if w is not None:
        w1 = w
    else:
        w1 = np.max(matches[:, 0]) - x1

    if h is not None:
        h1 = h
    else:
        h1 = np.max(matches[:, 1]) - y1

    x2, y2, w2, h2 = rpc_utils.corresponding_roi(r1, r2, x1, y1, w1, h1)
    # x2 = np.min(matches[:, 2])
    # w2 = np.max(matches[:, 2]) - x2
    # y2 = np.min(matches[:, 3])
    # h2 = np.max(matches[:, 3]) - y2

    # # add 20 pixels offset and round. The image_crop_TIFF function will round
    # # off the coordinates before it does the crops.
    # x1 -= 20; x1 = np.round(x1)
    # y1 -= 20; y1 = np.round(y1)
    # x2 -= 20; x2 = np.round(x2)
    # y2 -= 20; y2 = np.round(y2)
    # w1 += 40; w1 = np.round(w1)
    # h1 += 40; h1 = np.round(h1)
    # w2 += 40; w2 = np.round(w2)
    # h2 += 40; h2 = np.round(h2)

    # do the crops
    crop1 = common.image_qauto(common.image_crop_TIFF(im1, x1, y1, w1, h1))
    crop2 = common.image_qauto(common.image_crop_TIFF(im2, x2, y2, w2, h2))

    # compute matches coordinates in the cropped images
    pts1 = matches[:, 0:2] - [x1, y1]
    pts2 = matches[:, 2:4] - [x2, y2]

    # plot the matches on the two crops
    to_display = plot_matches(crop1, crop2, np.hstack((pts1, pts2)))
    if outfile is None:
        os.system('v %s &' % (to_display))
    else:
        common.run('cp %s %s' % (to_display, outfile))

    return
Exemplo n.º 4
0
def crop_and_apply_homography(im_out, im_in, H, w, h, subsampling_factor=1,
        convert_to_gray=False):
    """
    Warps a piece of a Pleiades (panchro or ms) image with a homography.

    Args:
        im_out: path to the output image
        im_in: path to the input (tif) full Pleiades image
        H: numpy array containing the 3x3 homography matrix
        w, h: size of the output image
        subsampling_factor (optional, default=1): when set to z>1,
            will result in the application of the homography Z*H where Z =
            diag(1/z, 1/z, 1), so the output will be zoomed out by a factor z.
            The output image will be (w/z, h/z)
        convert_to_gray (optional, default False): it set to True, and if the
            input image has 4 channels, it is converted to gray before applying
            zoom and homographies.

    Returns:
        nothing

    The homography has to be used as: coord_out = H coord_in. The produced
    output image corresponds to coord_out in [0, w] x [0, h]. The warp is made
    by Pascal Monasse's binary named 'homography'.
    """

    # crop a piece of the big input image, to which the homography will be
    # applied
    # warning: as the crop uses integer coordinates, be careful to round off
    # (x0, y0) before modifying the homograpy. You want the crop and the
    # translation representing it do exactly the same thing.
    pts = [[0, 0], [w, 0], [w, h], [0, h]]
    inv_H_pts = common.points_apply_homography(np.linalg.inv(H), pts)
    x0, y0, w0, h0 = common.bounding_box2D(inv_H_pts)
    x0, y0 = np.floor([x0, y0])
    w0, h0 = np.ceil([w0, h0])
    crop_fullres = common.image_crop_LARGE(im_in, x0, y0, w0, h0)

    # This filter is needed (for panchro images) because the original PLEAIDES
    # SENSOR PERFECT images are aliased
    if (common.image_pix_dim(crop_fullres) == 1 and subsampling_factor == 1 and
            cfg['use_pleiades_unsharpening']):
        tmp = image_apply_pleiades_unsharpening_filter(crop_fullres)
        common.run('rm -f %s' % crop_fullres)
        crop_fullres = tmp

    # convert to gray
    if common.image_pix_dim(crop_fullres) == 4:
        if convert_to_gray:
            crop_fullres = common.pansharpened_to_panchro(crop_fullres)

    # compensate the homography with the translation induced by the preliminary
    # crop, then apply the homography and crop.
    H = np.dot(H, common.matrix_translation(x0, y0))

    # Since the objective is to compute a zoomed out homographic transformation
    # of the input image, to save computations we zoom out the image before
    # applying the homography. If Z is the matrix representing the zoom out and
    # H the homography matrix, this trick consists in applying Z*H*Z^{-1} to
    # the zoomed image Z*Im instead of applying Z*H to the original image Im.
    if subsampling_factor == 1:
        common.image_apply_homography(im_out, crop_fullres, H, w, h)
        return

    else:
        assert(subsampling_factor >= 1)

        # H becomes Z*H*Z^{-1}
        Z = np.eye(3);
        Z[0,0] = Z[1,1] = 1 / float(subsampling_factor)
        H = np.dot(Z, H)
        H = np.dot(H, np.linalg.inv(Z))

        # w, and h are updated accordingly
        w = int(w / subsampling_factor)
        h = int(h / subsampling_factor)

        # the DCT zoom is NOT SAFE when the input image size is not a multiple
        # of the zoom factor
        tmpw, tmph = common.image_size(crop_fullres)
        tmpw, tmph = int(tmpw / subsampling_factor), int(tmph / subsampling_factor)
        crop_fullres_safe = common.image_crop_TIFF(crop_fullres, 0, 0, tmpw *
                subsampling_factor, tmph * subsampling_factor)
        common.run('rm -f %s' % crop_fullres)

        # zoom out the input image (crop_fullres)
        crop_zoom_out = common.image_safe_zoom_fft(crop_fullres_safe,
                subsampling_factor)
        common.run('rm -f %s' % crop_fullres_safe)

        # apply the homography to the zoomed out crop
        common.image_apply_homography(im_out, crop_zoom_out, H, w, h)
        return
Exemplo n.º 5
0
def crop_and_apply_homography(im_out,
                              im_in,
                              H,
                              w,
                              h,
                              subsampling_factor=1,
                              convert_to_gray=False):
    """
    Warps a piece of a Pleiades (panchro or ms) image with a homography.

    Args:
        im_out: path to the output image
        im_in: path to the input (tif) full Pleiades image
        H: numpy array containing the 3x3 homography matrix
        w, h: size of the output image
        subsampling_factor (optional, default=1): when set to z>1,
            will result in the application of the homography Z*H where Z =
            diag(1/z, 1/z, 1), so the output will be zoomed out by a factor z.
            The output image will be (w/z, h/z)
        convert_to_gray (optional, default False): it set to True, and if the
            input image has 4 channels, it is converted to gray before applying
            zoom and homographies.

    Returns:
        nothing

    The homography has to be used as: coord_out = H coord_in. The produced
    output image corresponds to coord_out in [0, w] x [0, h]. The warp is made
    by Pascal Monasse's binary named 'homography'.
    """

    # crop a piece of the big input image, to which the homography will be
    # applied
    # warning: as the crop uses integer coordinates, be careful to round off
    # (x0, y0) before modifying the homograpy. You want the crop and the
    # translation representing it do exactly the same thing.
    pts = [[0, 0], [w, 0], [w, h], [0, h]]
    inv_H_pts = common.points_apply_homography(np.linalg.inv(H), pts)
    x0, y0, w0, h0 = common.bounding_box2D(inv_H_pts)
    x0, y0 = np.floor([x0, y0])
    w0, h0 = np.ceil([w0, h0])
    crop_fullres = common.image_crop_LARGE(im_in, x0, y0, w0, h0)

    # This filter is needed (for panchro images) because the original PLEAIDES
    # SENSOR PERFECT images are aliased
    if (common.image_pix_dim(crop_fullres) == 1 and subsampling_factor == 1
            and cfg['use_pleiades_unsharpening']):
        tmp = image_apply_pleiades_unsharpening_filter(crop_fullres)
        common.run('rm -f %s' % crop_fullres)
        crop_fullres = tmp

    # convert to gray
    if common.image_pix_dim(crop_fullres) == 4:
        if convert_to_gray:
            crop_fullres = common.pansharpened_to_panchro(crop_fullres)

    # compensate the homography with the translation induced by the preliminary
    # crop, then apply the homography and crop.
    H = np.dot(H, common.matrix_translation(x0, y0))

    # Since the objective is to compute a zoomed out homographic transformation
    # of the input image, to save computations we zoom out the image before
    # applying the homography. If Z is the matrix representing the zoom out and
    # H the homography matrix, this trick consists in applying Z*H*Z^{-1} to
    # the zoomed image Z*Im instead of applying Z*H to the original image Im.
    if subsampling_factor == 1:
        common.image_apply_homography(im_out, crop_fullres, H, w, h)
        return

    else:
        assert (subsampling_factor >= 1)

        # H becomes Z*H*Z^{-1}
        Z = np.eye(3)
        Z[0, 0] = Z[1, 1] = 1 / float(subsampling_factor)
        H = np.dot(Z, H)
        H = np.dot(H, np.linalg.inv(Z))

        # w, and h are updated accordingly
        w = int(w / subsampling_factor)
        h = int(h / subsampling_factor)

        # the DCT zoom is NOT SAFE when the input image size is not a multiple
        # of the zoom factor
        tmpw, tmph = common.image_size(crop_fullres)
        tmpw, tmph = int(tmpw / subsampling_factor), int(tmph /
                                                         subsampling_factor)
        crop_fullres_safe = common.image_crop_TIFF(crop_fullres, 0, 0,
                                                   tmpw * subsampling_factor,
                                                   tmph * subsampling_factor)
        common.run('rm -f %s' % crop_fullres)

        # zoom out the input image (crop_fullres)
        crop_zoom_out = common.image_safe_zoom_fft(crop_fullres_safe,
                                                   subsampling_factor)
        common.run('rm -f %s' % crop_fullres_safe)

        # apply the homography to the zoomed out crop
        common.image_apply_homography(im_out, crop_zoom_out, H, w, h)
        return