项目解析-affnet项目
https://github.com/ducha-aiki/affnet
数据生成:
python -utt gen_ds.py
http://matthewalunbrown.com/patchdata/patchdata.html
http://phototour.cs.washington.edu/patches/default.htm
原始下载后
其中一个解压:
生成后的样子:
生成流程:
affnet/gen_ds.py
affnet/dataset.py- class TripletPhotoTour(dset.PhotoTour):
python2.7/site-packages/torchvision/datasets/phototour.py-
class PhotoTour(data.Dataset):
def __init__(self, root, name, train=True, transform=None, download=False):
if download:
self.download()
def download(self):
# process and save as torch files
print('# Caching data {}'.format(self.data_file))
dataset = (
read_image_file(self.data_dir, self.image_ext, self.lens[self.name]),
read_info_file(self.data_dir, self.info_file),
read_matches_files(self.data_dir, self.matches_files)
)
with open(self.data_file, 'wb') as f:
torch.save(dataset, f)
mean = {'notredame': 0.4854, 'yosemite': 0.4844, 'liberty': 0.4437,
'notredame_harris': 0.4854, 'yosemite_harris': 0.4844, 'liberty_harris': 0.4437}
std = {'notredame': 0.1864, 'yosemite': 0.1818, 'liberty': 0.2019,
'notredame_harris': 0.1864, 'yosemite_harris': 0.1818, 'liberty_harris': 0.2019}
lens = {'notredame': 468159, 'yosemite': 633587, 'liberty': 450092,
'liberty_harris': 379587, 'yosemite_harris': 450912, 'notredame_harris': 325295}
image_ext = 'bmp'
info_file = 'info.txt'
matches_files = 'm50_100000_100000_0.txt'
def read_image_file(data_dir, image_ext, n):
"""Return a Tensor containing the patches
"""
def PIL2array(_img):
"""Convert PIL image type to numpy 2D array
"""
return np.array(_img.getdata(), dtype=np.uint8).reshape(64, 64)
def find_files(_data_dir, _image_ext):
"""Return a list with the file names of the images containing the patches
"""
files = []
# find those files with the specified extension
for file_dir in os.listdir(_data_dir):
if file_dir.endswith(_image_ext):
files.append(os.path.join(_data_dir, file_dir))
return sorted(files) # sort files in ascend order to keep relations
patches = []
list_files = find_files(data_dir, image_ext)
for fpath in list_files:
img = Image.open(fpath)
for y in range(0, 1024, 64):
for x in range(0, 1024, 64):
patch = img.crop((x, y, x + 64, y + 64))
patches.append(PIL2array(patch))
return torch.ByteTensor(np.array(patches[:n]))
def read_info_file(data_dir, info_file):
"""Return a Tensor containing the list of labels
Read the file and keep only the ID of the 3D point.
"""
labels = []
with open(os.path.join(data_dir, info_file), 'r') as f:
labels = [int(line.split()[0]) for line in f]
return torch.LongTensor(labels)
def read_matches_files(data_dir, matches_file):
"""Return a Tensor containing the ground truth matches
Read the file and keep only 3D point ID.
Matches are represented with a 1, non matches with a 0.
"""
matches = []
with open(os.path.join(data_dir, matches_file), 'r') as f:
for line in f:
l = line.split()
matches.append([int(l[0]), int(l[3]), int(l[1] == l[4])])
return torch.LongTensor(matches)
先重建出点云,点云中某个三维点可能对应多个2D点
这个点云是来自项目:
http://phototour.cs.washington.edu/
info.txt 这个文件对应所有patchID的label
matches.append([int(l[0]), int(l[3]), int(l[1] == l[4])])
These are name "m50_n1_n2.txt" where n1 and n2 are the number of matches and non-matches present in the file.
n1:100000 n2:100000 是指这个txt中匹配和不匹配的数目,该文件共有100000条
patchID1 3DpointID1 unused1 patchID2 3DpointID2 unused2
(patchID1, patchID2, (3DpointID1==3DpointID2))
"matches" have the same 3DpointID, and correspond to interest points that were detected with 5 pixels in position, and agreeing to 0.25 octaves of scale and pi/8 radians in angle. "non-matches" have different 3DpointID's, and correspond to interest points lying outside a range of 10 pixels in position, 0.5 octaves of scale and pi/4 radians in angle.
patchID从0开始计
66!= 129
162 66 0 313 129 0 0
patch162 patch313
173088 67671 104 173089 67671 104 0
interest.txt
The first number is the ID of the reference image in which the interest point was found.
The other information in interest.txt is: x, y, orientation, scale (log2 units) x,y,方向,尺度