Пример #1
0
def gen_pairwise_surf_control_points(proj_file, img_fns, display=False):
    """ Use OpenCV for pairwise image matching
    """
    # get the kps of the first frame
    img1, kp1, ds1 = get_surf_kps(img_fns[0])
    # match the frame t with t+1
    cpoints = []
    for i2 in range(1, len(img_fns)):
        # get the kps of frame t+1
        img2, kp2, ds2 = get_surf_kps(img_fns[i2])
        # get the control points
        cp1, cp2 = get_pairwise_matches(kp1, ds1, kp2, ds2)
        # estimate the homography
        H, mask = cv2.findHomography(cp1, cp2, cv2.RANSAC)
        mask = mask.squeeze() > 0
        # display the matches and homography
        if display:
            homo_warp_image(img1, cp1, img2, cp2, H, mask)
        # filter out the outlier matches
        cp1 = cp1[mask]
        cp2 = cp2[mask]
        # add the control points
        cpoints.extend([
            hsi.ControlPoint(i2 - 1, x1, y1, i2, x2, y2)
            for (x1, y1), (x2, y2) in zip(cp1, cp2)
        ])
        # next -> cur
        img1, kp1, ds1 = img2, kp2, ds2
    # write to pto
    pano = hsi.Panorama()
    pano.readData(hsi.ifstream(proj_file))
    pano.setCtrlPoints(cpoints)
    pano.writeData(hsi.ofstream(proj_file))
Пример #2
0
def standalone():

    import sys  # to look at the argument vector
    import hsi  # to use hugin's scripting interface

    if len(sys.argv) < 2:
        print('usage: %s <pto file>' % sys.argv[0])
        sys.exit(-1)

    panofile = sys.argv[1]  # the only parameter: a pto file
    ifs = hsi.ifstream(panofile)  # create a C++ ifstream from it
    pano = hsi.Panorama()  # and a Panorama object
    success = pano.readData(ifs)  # feed the ifstream to the pano object

    # check if all went well
    if success != hsi.DocumentData.SUCCESSFUL:
        # if it failed, complain
        print('input file %s contains invalid data' % panofile)
        success = -1
    else:
        # if it succeeded, call the workhorse
        entry(pano)
        success = 0

    # and that's it
    return success
Пример #3
0
    def __init__(self):

        self.pto_nev = ""
        self.fajl_path = ""
        self.fajl_l = []

        self.sorok = 0
        self.oszlopok = 0

        self.epsilon = 1.5  # Erre az értékre érzékeny az eredmény. A teljes panorama automatikus forgatás segíthet talán

        self.yawBucket = {}
        self.pitchBucket = {}
        self.yawValues = []
        self.pitchValues = []
        self.x_coord = []
        self.y_coord = []
        self.roll = []
        self.yaw = []
        self.pitch = []
        self.p = hsi.Panorama()
        self.roll_eh = robjects.vectors.FloatVector
        self.yaw_eh = robjects.vectors.FloatVector
        self.pitch_eh = robjects.vectors.FloatVector
Пример #4
0
def main():

    # when called from the command line, we import the argparse module.
    # This may not be part of the standard library on your system.

    import argparse

    # and create an argument parser.

    parser = argparse.ArgumentParser(
        formatter_class=argparse.RawDescriptionHelpFormatter,
        description=gpl + '''
    crop_cp will remove all CPs which are either outside the panorama's ROI
    or inside it's ROI if the inside flag is set
    ''')

    parser.add_argument('-o',
                        '--output',
                        metavar='<output file>',
                        default=None,
                        type=str,
                        help='write output to a different file')

    parser.add_argument('-i',
                        '--inside',
                        action='store_true',
                        default=False,
                        help='remove CPs inside ROI')

    parser.add_argument('input',
                        metavar='<pto file>',
                        type=str,
                        help='pto file to be processed')

    if len(sys.argv) < 2:
        parser.print_help()
        return

    # we parse the arguments into a global variable so we can access
    # them from everywhere without having to pass them around

    global args

    args = parser.parse_args()

    if args.output:
        print('output: ', args.output)
    print('ptofile:', args.input)

    # first we see if we can open the input file

    ifs = hsi.ifstream(args.input)
    if not ifs.good():
        raise CropCpError('cannot open input file %s' % args.input)

    pano = hsi.Panorama()
    success = pano.readData(ifs)
    del ifs
    if success != hsi.DocumentData.SUCCESSFUL:
        raise CropCpError('input file %s contains invalid data' % args.input)

    # if a separate output file was chosen, we open it now to avoid
    # later disappointments

    if args.output:
        ofs = hsi.ofstream(args.output)
        if not ofs.good():
            raise CropCpError('cannot open output file %s' % args.output)

    # we've checked the args, now we call crop_cps()

    crop_cps(pano, args.inside)

    # if no different output file was specified, overwrite the input

    if not args.output:
        ofs = hsi.ofstream(args.input)
        if not ofs.good():
            raise CropCpError('cannot open file %s for output' % args.input)

    success = pano.writeData(ofs)
    del ofs
    if success != hsi.DocumentData.SUCCESSFUL:
        raise CropCpError('error writing pano to %s' % args.input)

    # done.

    return 0
Пример #5
0
    import sys
    import hsi

    # hpi.py has been called standalone rather than having been
    # mported as a module. In this case we want to look at the
    # argument vector:

    if len(sys.argv) < 3:
        print("use: %s panorama.pto plugin.py [plugin args]" % sys.argv[0])
        sys.exit(-12)

    # okay, there are some arguments, let's go ahead and try
    # opening the first one as a panorama.

    p = hsi.Panorama()
    ifs = hsi.ifstream(sys.argv[1])
    if not ifs.good():
        print("failed to open %s" % sys.argv[1])
        sys.exit(-13)

    # next, make the panorama object read the file

    if p.readData(ifs) != hsi.DocumentData.SUCCESSFUL:
        print("failed to read panorama data from %s" % sys.argv[1])
        sys.exit(-14)

    del ifs

    # if we're here, the load succeeded and we can finally call
    # the plugin
Пример #6
0
def pto_gen(img_fns, hfov, out_pto="project.pto"):
    """ Generate a Hugin .pto project file

    Parameters
    ----------
    img_fns: list,
             the (ordered) full paths to the video frames

    hfov: int,
          horizontal field of view in degrees
          (around 50 is ok for most non-fish-eye cameras)

    out_pto: string, optional, default: 'project.pto',
             output path to the generated panotools .pto file

    Notes
    -----
    Suitable as input for further tools such as the cpfind control-point
    generator.

    Inspired from pto_gen
    (http://hugin.sourceforge.net/docs/html/pto__gen_8cpp-source.html)
    but with some hacks to correct the generated m-line in the header.

    Uses the Hugin python scripting interface
    (http://wiki.panotools.org/Hugin_Scripting_Interface).
    """
    # projection type: 0 == rectilinear (2 == equirectangular)
    projection = 0
    assert projection >= 0, "Invalid projection number (%d)" % projection
    assert 1 <= hfov <= 360, "Invalid horizontal field of view (%d)" % hfov
    # hugin Panorama object
    pano = hsi.Panorama()
    # add the images in order
    for img_fn in img_fns:
        src_img = hsi.SrcPanoImage(img_fn)
        src_img.setProjection(projection)
        src_img.setHFOV(hfov)
        src_img.setExifCropFactor(1.0)
        pano.addImage(src_img)
    # check we added all of them
    n_inserted = pano.getNrOfImages()
    assert n_inserted == len(img_fns), "Didn't insert all images (%d < %d)" % \
            (n_inserted, len(img_fns))
    # output the .pto file
    pano.writeData(
        hsi.ofstream(out_pto +
                     '.tmp'))  # same as pano.printPanoramaScript(...)
    # some bug in header: rewrite it manually (TODO through hsi?)
    with open(out_pto + '.tmp', 'r') as tmp_ff:
        with open(out_pto, 'w') as ff:
            # re-write the header
            ff.write(tmp_ff.readline())
            ff.write(tmp_ff.readline())
            # force jpeg for the p-line
            p_line = tmp_ff.readline().strip().split()
            assert p_line[0] == 'p', "BUG: should be a p-line"
            ff.write(' '.join(p_line[:7]) + ' n"JPEG q100"\n')
            # remove extra 'f' param in the m-line (screws everything up if left here...)
            m_line = tmp_ff.readline().strip().split()
            assert m_line[0] == 'm', "BUG: should be a m-line"
            ff.write(' '.join(m_line[:3]) + ' ' + ' '.join(m_line[4:]) + '\n')
            # write all other lines
            for l in tmp_ff.readlines():
                ff.write(l)
    os.remove(out_pto + '.tmp')
Пример #7
0
def optimize_geometry(proj_file, optim_vars, optim_ref_fov=False):
    """ Optimise the geometric parameters

    Parameters
    ----------
    proj_file: string,
               the path to the Hugin project file (.pto)

    optim_vars: string,
                the set of variables to optimize for (separated by '_')
                - v: view point
                - p: pitch
                - y: yaw
                - r: roll
                - Tr{X,Y,Z}: translation

    optim_ref_fov: boolean, optional, default: False,
                   whether to optimize the input's reference horizontal field
                   of view (risky)

    Returns
    -------
    optim_proj_file: string,
                     path of the Hugin project file containing the optimized
                     values for the desired variables.

    Notes
    -----
    This is (by far) the most time consuming operation
    (because of hugin's autooptimiser).

    This is also the most likely function where the compensation process tends
    to fail.
    """
    optim_proj_file = proj_file + '.optim.pto'
    # modify the input pto to specify the optimization variables
    pano = hsi.Panorama()
    pano.readData(hsi.ifstream(proj_file))
    n_imgs = pano.getNrOfImages()
    var_tup = tuple(optim_vars.split('_'))
    for v in var_tup:
        assert v in ('v', 'p', 'y', 'r', 'TrX', 'TrY', 'TrZ'), \
                "Unknown var {0} in {1}".format(v, optim_vars)
    optim_opts = [var_tup] * n_imgs  # fov, pitch, roll, yaw
    if optim_ref_fov:
        # optim only field of view for 1st (reference) frame
        optim_opts[0] = ('v')
        # Note: do not optim. pitch, roll and yaw for this one, weird otherwise
    else:
        # 1st reference frame has the same fov as those of the input images
        optim_opts[0] = ()
    pano.setOptimizeVector(optim_opts)
    pano.writeData(hsi.ofstream(proj_file))
    # perform the optimization (TODO through hsi?)
    cmd = "autooptimiser -n -s -o {opto} {pto}"  # leveling can screw things up
    exec_shell(cmd.format(pto=proj_file, opto=optim_proj_file))
    # check for too large output (e.g. too wide panning or traveling)
    pano = hsi.Panorama()
    pano.readData(hsi.ifstream(optim_proj_file))
    opts = pano.getOptions()
    oh = opts.getHeight()
    ow = opts.getWidth()
    if oh * ow > 1e3 * 5e3:
        raise ValueError(
            "Degenerate case: too big output size ({0}, {1})\n".format(ow, oh) + \
            "May be caused by too large panning or translations\n" + \
            "=> Possible fixes: use a different field of view parameter or " + \
            "optimize only for different variables than {0}\n".format(optim_vars))
    return optim_proj_file