def main():
    usage  = "usage: %prog [options] in_homogs out_homogs\n\n"
    usage += "  Transform a homography file by translating then scaling\n"
    usage += "  in_homog is input homography sequence\n"
    usage += "  out_homog is output homography sequence\n"
    parser = OptionParser(usage=usage)

    parser.add_option("-x", "--x-trans", type='float', default=0.0,
                      action="store", dest="x_trans",
                      help="X translation, or image width if used with -a")
    parser.add_option("-y", "--y-trans", type='float', default=0.0,
                      action="store", dest="y_trans",
                      help="Y translation, or image height if used with -a")
    parser.add_option("-s", "--scale", type='float', default=1.0,
                      action="store", dest="scale",
                      help="scale factor")
    parser.add_option("-a", "--auto-translate", default=False,
                      action="store_true", dest="auto_trans",
                      help="compute the translation from image bounds")

    (options, args) = parser.parse_args()

    in_homog_file = args[0]
    out_homog_file = args[1]

    homogs = homography_io.load_homography_file(in_homog_file)

    x, y = options.x_trans, options.y_trans
    s = options.scale
    if options.auto_trans:
        x_rng, y_rng = compute_extents([H for _, H in homogs], (y,x))
        x = -x_rng[0]
        y = -y_rng[0]
        print "output image size:", s * (x_rng[1] - x_rng[0]), \
                                    s * (y_rng[1] - y_rng[0])

    print "translating output by (%g, %g)" % (x,y)
    print "scaling output by ", s

    trans_homogs = []
    for md, H in homogs:
        H = translate_homog(H, x, y)
        H = scale_homog(H, s)
        trans_homogs.append((md,H))

    homography_io.write_homography_file(trans_homogs, out_homog_file)
Exemple #2
0
def main():
    usage = "usage: %prog [options] image_list_file homography_file mosaic_file"
    description = "warp all of the images by homography and overlay into a mosaic"
    parser = OptionParser(usage=usage, description=description)

    parser.add_option("-e", "--expand", default=False,
                      action="store_true", dest="expand",
                      help="expand the output image to fit entire mosaic")

    parser.add_option("-b", "--blend", default=False,
                      action="store_true", dest="blend",
                      help="blend the pixels when creating the mosaic")

    parser.add_option("-m", "--match-resolution", default=False,
                      action="store_true", dest="match_resolution",
                      help="automatically estimate the output image scale "
                           "to match the input resolution on average")

    parser.add_option("-f", "--frame-width", default=0,
                      type="int", dest="frame",
                      help="draw a frame around each image")

    parser.add_option("-s", "--scale", default=1.0,
                      type="float", dest="scale",
                      help="scale of the output mosaic size")

    parser.add_option("-a", "--all-frame", default=False,
                      action="store_true", dest="all_frame",
                      help="draw all parts of the frames, even when obscured")

    (options, args) = parser.parse_args()

    image_filename = args[0]
    homog_filename = args[1]
    mosaic_filename = args[2]

    with open(image_filename, 'r') as f:
        image_files = [line.rstrip() for line in f]

    homogs = homography_io.load_homography_file(homog_filename)

    if len(homogs) != len(image_files):
        sys.exit("Number of homographies ("+str(len(homogs))+
                 ") does not match number of images ("+
                 str(len(image_files))+")")

    shapes = [image_file_dims(fn) for fn in image_files]
    img = cv2.imread(image_files[0])
    img_dtype = img.dtype

    scale = options.scale
    if options.match_resolution:
        scale = 1.0 / compute_average_scale([H for _, H in homogs], shapes)

    sH = np.diag([scale, scale, 1.0])
    homogs = [(f, sH * H) for f, H in homogs]


    if options.expand:
        x_rng, y_rng = compute_extents([H for _, H in homogs], shapes)
        H_offset = np.matrix([[1, 0, -x_rng[0]], [0, 1, -y_rng[0]], [0, 0, 1]])
        mosaic_shape = (int(math.ceil(x_rng[1] - x_rng[0])),
                        int(math.ceil(y_rng[1] - y_rng[0])))
    else:
        H_offset = np.eye(3)
        mosaic_shape = img.shape[1::-1]

    if options.blend:
        out_type = np.int32
    else:
        out_type = img_dtype

    print "creating mosaic of size", mosaic_shape
    mosaic = np.zeros(mosaic_shape[::-1] + (4,), out_type)
    edges = np.zeros(mosaic.shape[:2], np.bool)
    for fname, (_, H) in zip(image_files, homogs):
        print "processing", fname
        H = H_offset * H
        img = cv2.imread(fname)
        imgt = cv2.cvtColor(img, cv2.COLOR_BGR2BGRA)
        warped = cv2.warpPerspective(imgt, H, mosaic_shape)
        if options.frame > 0:
            edge_map = warped[:,:,3] == 255
            structure = np.ones((2*options.frame+1,)*2)
            edge_map = np.logical_xor(edge_map, morph.binary_erosion(edge_map, structure))
            if options.all_frame:
                edges = np.logical_or(edges, edge_map)
            else:
                warped[edge_map] = (0,0,255,255)
        mask = np.nonzero(warped[:,:,3] == 255)
        if options.blend:
            mosaic[mask] += warped[mask]
        else:
            mosaic[mask] = warped[mask]
    if options.blend:
        mask = np.nonzero(mosaic[:,:,3] > 255)
        for i in range(4):
            mosaic[:,:,i][mask] /= mosaic[:,:,3][mask] / 255
        mosaic.astype(img_dtype)
    if options.frame > 0 and options.all_frame:
        mosaic[edges] = (0,0,255,255)
    cv2.imwrite(mosaic_filename, mosaic)
def main():
    usage = "usage: %prog [options] image_list_file homography_file mosaic_file"
    description = "warp all of the images by homography and overlay into a mosaic"
    parser = OptionParser(usage=usage, description=description)

    parser.add_option("-e",
                      "--expand",
                      default=False,
                      action="store_true",
                      dest="expand",
                      help="expand the output image to fit entire mosaic")

    parser.add_option("-b",
                      "--blend",
                      default=False,
                      action="store_true",
                      dest="blend",
                      help="blend the pixels when creating the mosaic")

    parser.add_option("-f",
                      "--frame-width",
                      default=0,
                      type="int",
                      dest="frame",
                      help="draw a frame around each image")

    parser.add_option("-a",
                      "--all-frame",
                      default=False,
                      action="store_true",
                      dest="all_frame",
                      help="draw all parts of the frames, even when obscured")

    (options, args) = parser.parse_args()

    image_filename = args[0]
    homog_filename = args[1]
    mosaic_filename = args[2]

    with open(image_filename, 'r') as f:
        image_files = [line.rstrip() for line in f]

    homogs = homography_io.load_homography_file(homog_filename)

    if len(homogs) != len(image_files):
        sys.exit("Number of homographies (" + str(len(homogs)) +
                 ") does not match number of images (" +
                 str(len(image_files)) + ")")

    images = [cv2.imread(fn) for fn in image_files]
    shapes = [img.shape[:2] for img in images]

    if options.expand:
        x_rng, y_rng = compute_extents([H for _, H in homogs], shapes)
        H_offset = np.matrix([[1, 0, -x_rng[0]], [0, 1, -y_rng[0]], [0, 0, 1]])
        mosaic_shape = (int(math.ceil(x_rng[1] - x_rng[0])),
                        int(math.ceil(y_rng[1] - y_rng[0])))
    else:
        H_offset = np.eye(3)
        mosaic_shape = images[0].shape[1::-1]

    if options.blend:
        out_type = np.int32
    else:
        out_type = images[0].dtype

    mosaic = np.zeros(mosaic_shape[::-1] + (4, ), out_type)
    edges = np.zeros(mosaic.shape[:2], np.bool)
    for fname, img, (_, H) in zip(image_files, images, homogs):
        H = H_offset * H
        imgt = cv2.cvtColor(img, cv2.COLOR_BGR2BGRA)
        warped = cv2.warpPerspective(imgt, H, mosaic_shape)
        if options.frame > 0:
            edge_map = warped[:, :, 3] == 255
            structure = np.ones((2 * options.frame + 1, ) * 2)
            edge_map = np.logical_xor(
                edge_map, morph.binary_erosion(edge_map, structure))
            if options.all_frame:
                edges = np.logical_or(edges, edge_map)
            else:
                warped[edge_map] = (0, 0, 255, 255)
        mask = np.nonzero(warped[:, :, 3] == 255)
        if options.blend:
            mosaic[mask] += warped[mask]
        else:
            mosaic[mask] = warped[mask]
    if options.blend:
        mask = np.nonzero(mosaic[:, :, 3] > 255)
        for i in range(4):
            mosaic[:, :, i][mask] /= mosaic[:, :, 3][mask] / 255
        mosaic.astype(images[0].dtype)
    if options.frame > 0 and options.all_frame:
        mosaic[edges] = (0, 0, 255, 255)
    cv2.imwrite(mosaic_filename, mosaic)
Exemple #4
0
def main():
    usage = "usage: %prog [options] in_homogs out_homogs\n\n"
    usage += "  Transform a homography file by translating then scaling\n"
    usage += "  in_homog is input homography sequence\n"
    usage += "  out_homog is output homography sequence\n"
    parser = OptionParser(usage=usage)

    parser.add_option("-x",
                      "--x-trans",
                      type='float',
                      default=0.0,
                      action="store",
                      dest="x_trans",
                      help="X translation, or image width if used with -a")
    parser.add_option("-y",
                      "--y-trans",
                      type='float',
                      default=0.0,
                      action="store",
                      dest="y_trans",
                      help="Y translation, or image height if used with -a")
    parser.add_option("-s",
                      "--scale",
                      type='float',
                      default=1.0,
                      action="store",
                      dest="scale",
                      help="scale factor")
    parser.add_option("-a",
                      "--auto-translate",
                      default=False,
                      action="store_true",
                      dest="auto_trans",
                      help="compute the translation from image bounds")

    (options, args) = parser.parse_args()

    in_homog_file = args[0]
    out_homog_file = args[1]

    homogs = homography_io.load_homography_file(in_homog_file)

    x, y = options.x_trans, options.y_trans
    s = options.scale
    if options.auto_trans:
        x_rng, y_rng = compute_extents([H for _, H in homogs], (y, x))
        x = -x_rng[0]
        y = -y_rng[0]
        print "output image size:", s * (x_rng[1] - x_rng[0]), \
                                    s * (y_rng[1] - y_rng[0])

    print "translating output by (%g, %g)" % (x, y)
    print "scaling output by ", s

    trans_homogs = []
    for md, H in homogs:
        H = translate_homog(H, x, y)
        H = scale_homog(H, s)
        trans_homogs.append((md, H))

    homography_io.write_homography_file(trans_homogs, out_homog_file)