Source code for autocnet.io.keypoints

import os

import numpy as np
import pandas as pd
from plio.io import io_hdf

from autocnet.utils import utils

[docs]def from_hdf(in_path, index=None, keypoints=True, descriptors=True): """ For a given node, load the keypoints and descriptors from a hdf5 file. The keypoints and descriptors kwargs support returning only keypoints or descriptors. The index kwarg supports returning a subset of the data. Parameters ---------- in_path : str handle to the file key : str An optional path into the HDF5. For example key='image_name', will search /image_name/descriptors for the descriptors. index : iterable an h5py accepted indexer to pull only a subset of the keypoints off disk. Default is None to pull all keypoints. keypoints : bool if True (default) return the keypoints descriptors : bool if True (default) return the descriptors Returns ------- keypoints : DataFrame A pandas dataframe of keypoints. descriptors : ndarray A numpy array of descriptors """ if isinstance(in_path, str): hdf = io_hdf.HDFDataset(in_path, mode='r') else: hdf = in_path outd = '/descriptors' outk = '/keypoints' if index is not None: index=np.asarray(index) # The indices into HDF have to be sorted lists. When indices get passed in # they are frequently ordered, so this pulls the data using the sorted # index and then reorders the data. i = np.argsort(index) ii = np.argsort(i) # Is is important to use sorted() so that an in-place sort is NOT used. if descriptors: desc = hdf[outd][index[i].tolist()] desc = desc[ii] if keypoints: raw_kps = hdf[outk][index[i].tolist()] raw_kps = raw_kps[ii] else: # Unlike numpy hdf does not handle NoneType as a proxy for `:` if descriptors: desc = hdf[outd][:] if keypoints: raw_kps = hdf[outk][:] if keypoints: index = raw_kps['index'] clean_kps = utils.remove_field_name(raw_kps, 'index') columns = clean_kps.dtype.names allkps = pd.DataFrame(data=clean_kps, columns=columns, index=index) if isinstance(in_path, str): hdf = None if keypoints and descriptors: return allkps, desc elif keypoints: return allkps else: return desc
[docs]def to_hdf(out_path, keypoints=None, descriptors=None, key=None): """ Save keypoints and descriptors to HDF at a given out_path at either the root or at some arbitrary path given by a key. Parameters ---------- keypoints : DataFrame Pandas dataframe of keypoints descriptors : ndarray of feature descriptors out_path : str to the HDF5 file key : str path within the HDF5 file. If given, the keypoints and descriptors are save at <key>/keypoints and <key>/descriptors respectively. """ # If the out_path is a string, access the HDF5 file if isinstance(out_path, str): hdf = io_hdf.HDFDataset(out_path, mode='a') else: hdf = out_path grps = list(hdf.keys()) outd = '/descriptors' outk = '/keypoints' if descriptors is not None: # Strip the leading slash if outd[1:] in grps: del hdf[outd] # pragma: no cover hdf.create_dataset(outd, data=descriptors, compression=io_hdf.DEFAULT_COMPRESSION, compression_opts=io_hdf.DEFAULT_COMPRESSION_VALUE) if keypoints is not None: if outk[1:] in grps: del hdf[outk] # pragma: no cover hdf.create_dataset(outk, data=hdf.df_to_sarray(keypoints.reset_index()), compression=io_hdf.DEFAULT_COMPRESSION, compression_opts=io_hdf.DEFAULT_COMPRESSION_VALUE) #except: #warnings.warn('Descriptors for the node {} are already stored'.format(self['image_name'])) # If the out_path is a string, assume this method is being called as a singleton # and close the hdf file gracefully. If an object, let the instantiator of the # object close the file if isinstance(out_path, str): del hdf
[docs]def from_npy(in_path): """ Load keypoints and descriptors from a .npz file. Parameters ---------- in_path : str PATH to the npz file Returns ------- keypoints : DataFrame of keypoints descriptors : ndarray of feature descriptors """ nzf = np.load(in_path, allow_pickle=True) descriptors = nzf['descriptors'] keypoints = pd.DataFrame(nzf['keypoints'], index=nzf['keypoints_idx'], columns=nzf['keypoints_columns']) return keypoints, descriptors
[docs]def to_npy(keypoints, descriptors, out_path): """ Save keypoints and descriptors to a .npz file at some out_path Parameters ---------- keypoints : DataFrame of keypoints descriptors : ndarray of feature descriptors out_path : str PATH and filename to save the features """ np.savez(out_path, descriptors=descriptors, keypoints=keypoints, keypoints_idx=keypoints.index, keypoints_columns=keypoints.columns)
[docs]def create_output_path(filename, outdir=None): """ Given a filename for keypoints and descriptors, create an output directory with _kps.h5 appended. Parameters ---------- filename : str The filename or full path outdir : str An optional output path Returns ------- outh5 : str Path of the output h5 file """ image_name = os.path.basename(filename) image_path = os.path.dirname(filename) if outdir is None: outh5 = os.path.join(image_path, image_name + '_kps.h5') else: outh5 = os.path.join(outdir, image_name + '_kps.h5') return outh5