-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit b6a161b
Showing
293 changed files
with
594,294 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# hide training files for undering review. | ||
train/* | ||
media/* | ||
parses/parses_train* | ||
dataops/dataloader.py | ||
trainset.py | ||
Train.py |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import sys | ||
import argparse | ||
import parses.parses_test as parses_test | ||
from test.evaluator import yoho_evaluator | ||
|
||
parser = argparse.ArgumentParser() | ||
parser.add_argument('--max_iter',default=1000,type=int,help='ransac iterations') | ||
parser.add_argument('--testset',default='3dmatch',type=str,help='dataset name') | ||
parser.add_argument('--ransac_ird',default=0.1,type=float,help='inliner threshold of ransac') | ||
parser.add_argument('--keynum',default=5000,type=int,help='inliner threshold of ransac') | ||
parser.add_argument('--match_n',default=0.5,type=float,help = 'use how many predicted correspondences, 0.99 for all, >=1 for top-h') | ||
parser.add_argument('--tau_1',default=0.05,type=float,help='tau 1 for FMR') | ||
parser.add_argument('--tau_2',default=0.1,type=float,help='tau 2 for FMR') | ||
parser.add_argument('--tau_3',default=0.2,type=float,help='tau 3 for RR') | ||
parser.add_argument('--RD',action='store_true') | ||
parser.add_argument('--RM',action='store_true') | ||
parser.add_argument('--ET',default='yohoo',type=str,help = 'yohoc/yohoo') | ||
args = parser.parse_args() | ||
|
||
# execuate | ||
config, nouse = parses_test.get_config() | ||
evalor=yoho_evaluator(config) | ||
evalor.run() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import logging | ||
import backbone.fcgf.simpleunet as simpleunets | ||
import backbone.fcgf.resunet as resunets | ||
|
||
MODELS = [] | ||
|
||
|
||
def add_models(module): | ||
MODELS.extend([getattr(module, a) for a in dir(module) if 'Net' in a or 'MLP' in a]) | ||
|
||
|
||
add_models(simpleunets) | ||
add_models(resunets) | ||
|
||
|
||
def load_model(name): | ||
'''Creates and returns an instance of the model given its class name. | ||
''' | ||
# Find the model class from its name | ||
all_models = MODELS | ||
mdict = {model.__name__: model for model in all_models} | ||
if name not in mdict: | ||
logging.info(f'Invalid model index. You put {name}. Options are:') | ||
# Display a list of valid model names | ||
for model in all_models: | ||
logging.info('\t* {}'.format(model.__name__)) | ||
return None | ||
NetClass = mdict[name] | ||
|
||
return NetClass |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import MinkowskiEngine as ME | ||
|
||
def get_norm(norm_type, num_feats, bn_momentum=0.05, D=-1): | ||
if norm_type == 'BN': | ||
return ME.MinkowskiBatchNorm(num_feats, momentum=bn_momentum) | ||
elif norm_type == 'IN': | ||
return ME.MinkowskiInstanceNorm(num_feats, dimension=D) | ||
else: | ||
raise ValueError(f'Type {norm_type}, not defined') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
""" | ||
From https://github.com/chrischoy/FCGF for FCGF feature extraction. | ||
""" | ||
|
||
import torch | ||
import time | ||
import numpy as np | ||
import MinkowskiEngine as ME | ||
|
||
|
||
def _hash(arr, M): | ||
if isinstance(arr, np.ndarray): | ||
N, D = arr.shape | ||
else: | ||
N, D = len(arr[0]), len(arr) | ||
|
||
hash_vec = np.zeros(N, dtype=np.int64) | ||
for d in range(D): | ||
if isinstance(arr, np.ndarray): | ||
hash_vec += arr[:, d] * M**d | ||
else: | ||
hash_vec += arr[d] * M**d | ||
return hash_vec | ||
|
||
|
||
def extract_features(model, | ||
xyz, | ||
rgb=None, | ||
normal=None, | ||
voxel_size=0.05, | ||
device=None, | ||
skip_check=False, | ||
is_eval=True): | ||
''' | ||
xyz is a N x 3 matrix | ||
rgb is a N x 3 matrix and all color must range from [0, 1] or None | ||
normal is a N x 3 matrix and all normal range from [-1, 1] or None | ||
if both rgb and normal are None, we use Nx1 one vector as an input | ||
if device is None, it tries to use gpu by default | ||
if skip_check is True, skip rigorous checks to speed up | ||
model = model.to(device) | ||
xyz, feats = extract_features(model, xyz) | ||
''' | ||
if is_eval: | ||
model.eval() | ||
|
||
if not skip_check: | ||
assert xyz.shape[1] == 3 | ||
|
||
N = xyz.shape[0] | ||
if rgb is not None: | ||
assert N == len(rgb) | ||
assert rgb.shape[1] == 3 | ||
if np.any(rgb > 1): | ||
raise ValueError('Invalid color. Color must range from [0, 1]') | ||
|
||
if normal is not None: | ||
assert N == len(normal) | ||
assert normal.shape[1] == 3 | ||
if np.any(normal > 1): | ||
raise ValueError('Invalid normal. Normal must range from [-1, 1]') | ||
|
||
if device is None: | ||
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") | ||
|
||
feats = [] | ||
if rgb is not None: | ||
# [0, 1] | ||
feats.append(rgb - 0.5) | ||
|
||
if normal is not None: | ||
# [-1, 1] | ||
feats.append(normal / 2) | ||
|
||
if rgb is None and normal is None: | ||
feats.append(np.ones((len(xyz), 1))) | ||
|
||
feats = np.hstack(feats) | ||
|
||
# Voxelize xyz and feats | ||
starttime=time.time() | ||
coords = np.floor(xyz / voxel_size) | ||
coords, inds = ME.utils.sparse_quantize(coords, return_index=True) | ||
# Convert to batched coords compatible with ME | ||
coords = ME.utils.batched_coordinates([coords]) | ||
return_coords = xyz[inds] | ||
#print('ds:',time.time()-starttime) | ||
|
||
feats = feats[inds] | ||
|
||
feats = torch.tensor(feats, dtype=torch.float32) | ||
coords = torch.tensor(coords, dtype=torch.int32) | ||
|
||
stensor = ME.SparseTensor(feats, coordinates=coords, device=device) | ||
|
||
return return_coords, model(stensor).F |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
import torch.nn as nn | ||
|
||
from backbone.fcgf.common import get_norm | ||
|
||
import MinkowskiEngine as ME | ||
import MinkowskiEngine.MinkowskiFunctional as MEF | ||
|
||
|
||
class BasicBlockBase(nn.Module): | ||
expansion = 1 | ||
NORM_TYPE = 'BN' | ||
|
||
def __init__(self, | ||
inplanes, | ||
planes, | ||
stride=1, | ||
dilation=1, | ||
downsample=None, | ||
bn_momentum=0.1, | ||
D=3): | ||
super(BasicBlockBase, self).__init__() | ||
|
||
self.conv1 = ME.MinkowskiConvolution( | ||
inplanes, planes, kernel_size=3, stride=stride, dimension=D) | ||
self.norm1 = get_norm(self.NORM_TYPE, planes, bn_momentum=bn_momentum, D=D) | ||
self.conv2 = ME.MinkowskiConvolution( | ||
planes, | ||
planes, | ||
kernel_size=3, | ||
stride=1, | ||
dilation=dilation, | ||
bias=False, | ||
dimension=D) | ||
self.norm2 = get_norm(self.NORM_TYPE, planes, bn_momentum=bn_momentum, D=D) | ||
self.downsample = downsample | ||
|
||
def forward(self, x): | ||
residual = x | ||
|
||
out = self.conv1(x) | ||
out = self.norm1(out) | ||
out = MEF.relu(out) | ||
|
||
out = self.conv2(out) | ||
out = self.norm2(out) | ||
|
||
if self.downsample is not None: | ||
residual = self.downsample(x) | ||
|
||
out += residual | ||
out = MEF.relu(out) | ||
|
||
return out | ||
|
||
|
||
class BasicBlockBN(BasicBlockBase): | ||
NORM_TYPE = 'BN' | ||
|
||
|
||
class BasicBlockIN(BasicBlockBase): | ||
NORM_TYPE = 'IN' | ||
|
||
|
||
def get_block(norm_type, | ||
inplanes, | ||
planes, | ||
stride=1, | ||
dilation=1, | ||
downsample=None, | ||
bn_momentum=0.1, | ||
D=3): | ||
if norm_type == 'BN': | ||
return BasicBlockBN(inplanes, planes, stride, dilation, downsample, bn_momentum, D) | ||
elif norm_type == 'IN': | ||
return BasicBlockIN(inplanes, planes, stride, dilation, downsample, bn_momentum, D) | ||
else: | ||
raise ValueError(f'Type {norm_type}, not defined') |
Oops, something went wrong.