Пример #1
0
def filter_reconstruct(src, thd=0.3):
    src = os.path.abspath(src)
    res = {}
    if os.path.isdir(src + '/opensfm'):  # for odm
        cam = src + '/cameras.json'
        src += '/opensfm'
        rec = src + '/reconstruction.topocentric.json'
    elif os.path.isfile(src + '/../cameras.json'):
        cam = src + '/../cameras.json'  # for odm
        rec = src + '/reconstruction.topocentric.json'
    elif os.path.isfile(src + '/camera_models.json'):
        cam = src + '/camera_models.json'  # for sfm
        rec = src + '/reconstruction.json'
    cam = Camera(cam)
    bak = rec[:-4] + 'bak'
    if os.path.isfile(bak):
        if os.path.isfile(rec): os.remove(rec)
        os.rename(bak, rec)  # for win
    with open(rec) as f:
        data = json.load(f)[0]
    os.rename(rec, bak)
    INFO(f'Filter: {rec}')

    from opensfm.dataset import DataSet
    T = DataSet(src).load_tracks_manager()
    for im in T.get_shot_ids():
        v = data['shots'][im]
        rotation = np.array(v['rotation'])
        translation = np.array(v['translation'])
        O, X, Y, Z = calc_axis_cam(translation, rotation)
        feat = load_feature(f'{src}/features/{im}', cam, 1)
        for tid, x in T.get_shot_observations(im).items():
            if not tid in data['points']: continue
            dp = data['points'][tid]['coordinates'] - O
            ddp = np.linalg.norm(dp)
            u, v = feat[x.id][:2]  # fid
            qt = u * X + v * Y + Z
            qt /= np.linalg.norm(qt)
            delta = np.dot(dp, qt)
            dis = np.sqrt(ddp**2 - delta**2)
            if tid not in res: res[tid] = dis
            elif dis > res[tid]: res[tid] = dis  # meters
            #print(f'{im} %6s %6s %.3f'%(tid,x.id,dis))
    dis = [*res.values()]
    md = np.mean(dis)
    thd = min(thd, md)
    out = {k: v
           for k, v in res.items() if v > thd}
    #print(out)
    #plt.hist(dis, [0.01,0.05,0.1,0.5,1,2]); plt.show()
    for tid in out:
        data['points'].pop(tid)
    with open(rec, 'w') as f:
        json.dump([data], f, indent=4)
    INFO('Out=%d/%d, Thd=%.3f, Max=%.3f' % (len(out), len(res), thd, max(dis)))
Пример #2
0
def SfM_parse_track(src):
    from opensfm.dataset import DataSet
    #from opensfm.pymap import Observation
    TM = DataSet(src).load_tracks_manager()
    T = {}
    for im in TM.get_shot_ids():
        T.setdefault(im, [[], [], [], []])  # tid=str
        for tid, v in TM.get_shot_observations(im).items():
            T[im][0] += [tid]
            T[im][1] += [v.id]  # xys
            T[im][2] += [np.hstack([v.point, v.scale])]
            T[im][3] += [v.color]  # RGB
    return T  # {im: [tid,fid,xys,RGB]}