Skip to content

Commit

Permalink
'init'
Browse files Browse the repository at this point in the history
  • Loading branch information
HpWang-whu committed Sep 16, 2022
0 parents commit b6a161b
Show file tree
Hide file tree
Showing 293 changed files with 594,294 additions and 0 deletions.
7 changes: 7 additions & 0 deletions .gitignore
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
367 changes: 367 additions & 0 deletions README.md

Large diffs are not rendered by default.

23 changes: 23 additions & 0 deletions Test.py
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()
30 changes: 30 additions & 0 deletions backbone/fcgf/__init__.py
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
9 changes: 9 additions & 0 deletions backbone/fcgf/common.py
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')
100 changes: 100 additions & 0 deletions backbone/fcgf/misc.py
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
77 changes: 77 additions & 0 deletions backbone/fcgf/residual_block.py
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')
Loading

0 comments on commit b6a161b

Please sign in to comment.