获取Matterport数据集
申请
详细访问Matterport3D官方仓库,下载申请表MP_TOS.pdf,填写说明:
然后用英文简单介绍使用该数据集用途,发送给matterport3d@googlegroups.com
,我当天晚上就收到回复,一般没什么问题,Matterport那边就会回复你。使用其提供的下载脚本进行下载。
下载
我这里提供批量下载脚本:
import os
import argparse
import zipfile
import subprocess
def sh(command, show=False):
"""
real time output
:param show:
:param command:
:return:
"""
p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
print(type(p))
lines = []
for line in iter(p.stdout.readline, b''):
line = line.strip().decode("UTF-8")
if show:
print(">>>", line)
lines.append(line)
return lines
def unzip_file(zip_src, dst_dir):
r = zipfile.is_zipfile(zip_src)
if r:
fz = zipfile.ZipFile(zip_src, 'r')
for file in fz.namelist():
fz.extract(file, dst_dir)
else:
print('This is not zip')
if __name__ == "__main__":
parser = argparse.ArgumentParser()
# e.g.
# --out_dir
# /Volumes/dataset/matterport3d
# --data_list_path
# /Code/Matterport3DLayoutAnnotation/data_list/mp3d_val.txt
parser.add_argument('-o', '--out_dir', required=True, help='directory in which to download')
parser.add_argument('-p', '--data_list_path', required=True, help='path of the data_list file')
parser.add_argument('--python', default='python2', help='path of the python interpreter ')
parser.add_argument('--download_mp_path', default='Matterport/download_mp.py', help='the download_mp.py script')
args = parser.parse_args()
args.type = 'matterport_skybox_images'
with open(args.data_list_path, 'r') as f:
lines = f.readlines()
ids = [line.strip('\n').split(" ")[0] for line in lines]
ids = set(ids)
for id in ids:
# download_mp.py only support python2, or modify the script to support python3
command = "{} {} --out_dir {} --id {} --type {}".format(args.python, args.download_mp_path, args.out_dir, id, args.type)
print(command)
sh(command, show=True)
zip_path = os.path.join(args.out_dir, "v1/scans/", id, "{}.zip".format(args.type))
assert os.path.exists(zip_path)
dst_dir = os.path.join(args.out_dir, "v1/scans/")
unzip_file(zip_src=zip_path, dst_dir=dst_dir)
其中data_list_path
指train/test/val分割文件,可以在Matterport3DLayoutAnnotation仓库找到。
另外一个重要文件download_mp_path
,就是Matterport回复给你的python下载脚本。
下载好后的格式:
可以看到图片是6面图,需要后续进行拼接。
拼接全景图
使用Matterport3DLayoutAnnotation指定的拼接程序:PanoBasic,它是Matlab代码。
同样地,我这里提供批处理matlab代码:
add_path;
vx = [-pi/2 -pi/2 0 pi/2 pi -pi/2];
vy = [pi/2 0 0 0 0 -pi/2];
listPath='/Code/Matterport3DLayoutAnnotation/data_list/mp3d_val.txt';
dataPath='/Volumes/dataset/matterport3d/v1/scans';
listText=fileread(listPath);
list=strsplit(listText, '\n');
list=list(1, :);
for a=list(1:end)
b=deblank(a{1});
raw=strsplit(b);
house_id=raw{1};
image_id=raw{2};
disp(sprintf('house_id:%s image_id:%s',house_id, image_id));
panorama_iamges_dir=fullfile(dataPath, house_id, 'panorama_iamges');
panorama_iamge_path=fullfile(panorama_iamges_dir, sprintf('%s.png',image_id));
if exist(panorama_iamge_path,'file')~=0
disp('pass')
continue;
end
folderonpath=fullfile(dataPath, house_id, 'matterport_skybox_images', image_id);
sepImg = [];
for b = 1:6
sepImg(b).img = im2double(imread(sprintf('%s_skybox%d_sami.jpg',folderonpath, b-1)));
sepImg(b).vx = vx(b);
sepImg(b).vy = vy(b);
sepImg(b).fov = pi/2+0.001;
sepImg(b).sz = size(sepImg(b).img);
end
panoskybox = combineViews( sepImg, 2048, 1024 );
% figure;
% imshow(panoskybox);
if exist(panorama_iamges_dir,'dir')==0
mkdir(panorama_iamges_dir);
end
imwrite(panoskybox, panorama_iamge_path);
end
disp('end')
将上面代码添加到如下位置,然后执行。
需要额外注意:输出文件名一定要为png后缀,无损保存,否则在消失点对齐步骤将可能发生和label不匹配情况:
猜测是保存jpg格式有损压缩导致消失点对齐步骤中线段搜索发生变化。
消失点对齐(Manhattan-aligned)
使用Matterport3DLayoutAnnotation指定消失点对齐(Manhattan-aligned)程序:PanoAnnotator/pre-process,下载preprocess.zip解压后,可以看到下图Matlab代码。
请注意Matlab是否安装了Image Processing Toolbox,否则无法使用。
此外在mac上,你需要手动编译lsd代码,也很简单,cd到lsd_1.6
目录,执行make
命令,将可执行文件lsd
移动到外层VpEstimation
目录下。windows和linux作者已经提供了可执行文件。
如果还有问题你可以使用Matlab在线版本,但是它非常的慢,而且不操作时间久了会想colab一样提示超时,毕竟白嫖7_7。
上面环境设置好了你可以执行preprocess('/Volumes/dataset/matterport3d/v1/scans/7y3sRwLe3Va/panorama_iamges/0e9fdd85e24a4a35b3dc1e8cb76ebb09.png', '/Volumes/dataset/matterport3d/v1/scans/7y3sRwLe3Va/panorama_iamges/0e9fdd85e24a4a35b3dc1e8cb76ebb09_aligned.png')
进行测试。同样的,我也提供了批处理matlab代码:
listPath='/Volumes/dataset/matterport3d/mp3d/split/mp3d_train.txt';
dataPath='/Volumes/dataset/matterport3d/v1/scans';
out_dir='/Volumes/dataset/matterport3d/matlab_preprocessed';
listText=fileread(listPath);
list=strsplit(listText, '\n');
list=list(1, :);
if exist(out_dir,'dir')==0
mkdir(out_dir);
end
i=0;
for a=list(1:end)
i=i+1;
b=deblank(a{1});
raw=strsplit(b);
house_id=raw{1};
image_id=raw{2};
fprintf('house_id:%s image_id:%s\n',house_id, image_id);
panorama_iamges_dir=fullfile(dataPath, house_id, 'panorama_iamges');
panorama_iamge_path=fullfile(panorama_iamges_dir, sprintf('%s.png',image_id));
output_iamge_path=fullfile(out_dir, sprintf('%s_%s.png', house_id, image_id));
if exist(panorama_iamge_path,'file')==0
fprintf('%s not exist\n',panorama_iamge_path);
continue;
end
if exist(output_iamge_path, 'file')==0
batch_preprocess(panorama_iamge_path, output_iamge_path);
else
disp('pass!');
continue;
end
fprintf("----%d\n", i);
end
如果不想输出OM和Manhattan Line,可以修改process.m
为:
function [ panoImg_rot, panoEdge_rot, panoOmap_rot] = preprocess( inputFile, outputPath)
add_path;
%%
panoImg = imread(inputFile);
panoImg = imresize(panoImg, [1024, 2048]);
panoImg = im2double(panoImg);
%figure; imshow(panoImg)
%%
panoSep = getPanoSeperate(panoImg, 320);
%%
[ olines, vp, views, score, angle] = getPanoEdges(panoImg, panoSep, 0.7);
%figure; imshow(panoEdge);
%%
vp = vp(3:-1:1,:);
[ panoImg_rot, R ] = rotatePanorama( panoImg, vp);
%%
imwrite(panoImg_rot,outputPath);
end
batch_getPanoEdges.m
function [ olines, vp, views, score, angle] = getPanoEdges(img, sepScene, qError )
numScene = length(sepScene);
edge(numScene) = struct('img',[],'edgeLst',[],'vx',[],'vy',[],'fov',[]);
for i = 1:numScene
cmdline = sprintf('-q %f ', qError);
[ edgeMap, edgeList ] = lsdWrap( sepScene(i).img, cmdline);
% [edgeList, edgeMap] = getLargeConnectedEdges(sepScene(i).img, thresh);
edge(i).img = edgeMap;
edge(i).edgeLst = edgeList;
edge(i).fov = sepScene(i).fov;
edge(i).vx = sepScene(i).vx;
edge(i).vy = sepScene(i).vy;
edge(i).panoLst = edgeFromImg2Pano( edge(i) );
end
[lines,olines] = combineEdgesN( edge);
%% compute vanishing point and refine line segments
clines = lines;
for iter = 1:3
fprintf('*************%d-th iteration:****************\n', iter);
[mainDirect, score, angle] = findMainDirectionEMA( clines );
[ type, typeCost ] = assignVanishingType( lines, mainDirect(1:3,:), 0.1, 10 );
lines1 = lines(type==1,:);
lines2 = lines(type==2,:);
lines3 = lines(type==3,:);
lines1rB = refitLineSegmentB(lines1, mainDirect(1,:), 0);
lines2rB = refitLineSegmentB(lines2, mainDirect(2,:), 0);
lines3rB = refitLineSegmentB(lines3, mainDirect(3,:), 0);
clines = [lines1rB;lines2rB;lines3rB];
end
%% output
olines = clines;
vp = mainDirect;
views = sepScene;
end
另外一个可选方案是使用python版本的preprocess,它的大部分代码是翻译matlab版本,所以理论上结果是一致的。但是为了防止意外,我使用batch_preprocess数据集推荐的Matlab处理程序。
结果
使用提供的对齐
我们发现使用Matlab和python版本的预处理会有差异,而且处理过程中如果保存为jpg(比如6面图拼接完全景图时)也会得到不同的输出,为了避免这些差异,建议使用我们计算好的消失点进行预处理:
[‘sT4fr6TAbpF’, ‘00f205a65f374c5299b67176c0852e91’],
[‘S9hNv5qa7GM’, ‘625eb179629b45f280c01d3f6ec74b4f’],
[‘uNb9QFRL6hY’, ‘4d422e01951e4c4a9fa3c2d10666a004’],
[‘ac26ZMwG7aT’, ‘8dc2bb01c486457b9a0348c413d62f67’],
[‘ac26ZMwG7aT’, ‘331098855d30477582b2ad4d3fcdda62’],
[‘TbHJrupSAjP’, ‘d142b55fe4fb4e1cb26608085d729ac2’],
[‘vyrNrziPKCB’, ‘468dc41d313746d0a4bcda690794d9bb’],
[‘VzqfbhrpDEA’, ‘cb6d7cb920924379a292ac93e655fcfb’],
[‘uNb9QFRL6hY’, ‘5fc8f0e230eb49eca81fdfb0398d824b’],
[‘jh4fc5c5qoQ’, ‘755d110c2ed84d76be11ad56ae00b53f’]