MATLAB 全景图切割及盒图显示
Posted slandarer
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MATLAB 全景图切割及盒图显示相关的知识,希望对你有一定的参考价值。
part1 全景图切割
原图:
切割效果:
以下是切割部分步骤:
举这张图为例,图片格式hdr,png啥的都行:
1.1 边缘剔除
有些全景图会自带白灰色边缘,若是直接进行切割便会出现如下效果:
这时候我们首先要对原图进行白边剔除,代码如下:
oriPic=imread('test.hdr');
[rows,cols,~]=size(oriPic);
for i=cols:-1:1
tempListR=oriPic(floor(rows/4):ceil(3*rows/4),i,1);
tempListG=oriPic(floor(rows/4):ceil(3*rows/4),i,1);
tempListB=oriPic(floor(rows/4):ceil(3*rows/4),i,1);
if all(round(tempListR-mean(tempListR))==0)&&all(tempListR==tempListG)&&all(tempListR==tempListB)
oriPic(:,i,:)=[];
else
break;
end
end
oriPic=oriPic(:,end:-1:1,:);
for i=size(oriPic,2):-1:1
tempListR=oriPic(floor(rows/4):ceil(3*rows/4),i,1);
tempListG=oriPic(floor(rows/4):ceil(3*rows/4),i,1);
tempListB=oriPic(floor(rows/4):ceil(3*rows/4),i,1);
if all(round(tempListR-mean(tempListR))==0)&&all(tempListR==tempListG)&&all(tempListR==tempListB)
oriPic(:,i,:)=[];
else
break;
end
end
oriPic=oriPic(:,end:-1:1,:);
for i=rows:-1:1
tempListR=oriPic(i,floor(cols/4):ceil(3*cols/4),1);
tempListG=oriPic(i,floor(cols/4):ceil(3*cols/4),1);
tempListB=oriPic(i,floor(cols/4):ceil(3*cols/4),1);
if all(round(tempListR-mean(tempListR))==0)&&all(tempListR==tempListG)&&all(tempListR==tempListB)
oriPic(i,:,:)=[];
else
break;
end
end
oriPic=oriPic(end:-1:1,:,:);
for i=size(oriPic,1):-1:1
tempListR=oriPic(i,floor(cols/4):ceil(3*cols/4),1);
tempListG=oriPic(i,floor(cols/4):ceil(3*cols/4),1);
tempListB=oriPic(i,floor(cols/4):ceil(3*cols/4),1);
if all(round(tempListR-mean(tempListR))==0)&&all(tempListR==tempListG)&&all(tempListR==tempListB)
oriPic(i,:,:)=[];
else
break;
end
end
oriPic=oriPic(end:-1:1,:,:);
1.2 图像裁剪
我们要让完成的就是如下的变换和裁剪:
这部分其实已经有较为成熟的原理和代码:
代码参考:https://stackoverflow.com/questions/29678510/convert-21-equirectangular-panorama-to-cube-map
原理参考:
http://paulbourke.net/panorama/cubemaps/#1
http://paulbourke.net/panorama/cubemaps/
原理参考文章中更加清晰的变化图:
另:
在参考代码的基础上,对映射像素进行了插值处理,可以使图像更加平滑,原理如下:
主要函数代码:
function resultPic=createCubeMapFace(oriPic,id,height,width)
[M,N,~]=size(oriPic);
resultPic=zeros([height,width,3]);
an=sin(pi/4);
ak=cos(pi/4);
faceTransform=[0,0;
pi/2,0;
pi,0;
-pi/2,0;
0,-pi/2;
0,pi];
ftu=faceTransform(id,1);
ftv=faceTransform(id,2);
for y=0:height-1
for x=0:width-1
nx=y/height-0.5;
ny=x/width-0.5;
nx=nx*2*an;
ny=ny*2*an;
if (ftv == 0)
u=atan2(nx, ak);
v=atan2(ny*cos(u),ak);
u=u+ftu;
elseif(ftv>0)
d=sqrt(nx*nx+ny*ny);
v=pi/2-atan2(d,ak);
u=atan2(ny,nx);
else
d=sqrt(nx*nx+ny*ny);
v=-pi/2+atan2(d,ak);
u=atan2(-ny,nx);
end
u=u/(pi);
v=v/(pi/2);
while(v<-1)
v=v+2;
u=u+1;
end
while(v>1)
v=v-2;
u=u+1;
end
while(u<-1)
u=u+2;
end
while(u>1)
u=u-2;
end
u=u/2+0.5;
v=v/2+0.5;
u=u*(N-1)+1;
v=v*(M-1)+1;
fv=floor(v);fv1=floor(v)+1;pv=v-fv;fv1(fv1>M)=M;
fu=floor(u);fu1=floor(u)+1;pu=u-fu;fu1(fu1>N)=N;
resultPic(x+1,y+1,:)=double(oriPic(fv,fu,:)).*(1-pv).*(1-pu)+...
double(oriPic(fv1,fu,:)).*(pv).*(1-pu)+...
double(oriPic(fv,fu1,:)).*(1-pv).*(pu)+...
double(oriPic(fv1,fu1,:)).*(pv).*(pu);
end
end
resultPic=uint8(resultPic);
end
函数调用及图像存储:
这里后面长宽数值可以任意设定,但是要求长宽数值一致,如果按照当前写法,结果被存储至result文件夹:
if ~exist('result','dir')
mkdir('result');
end
for i=1:6
resultPic=createCubeMapFace(oriPic,i,500,500);
figure(i)
imshow(resultPic)
imwrite(resultPic,['result\\',num2str(i),'.png'])
end
另: 如图所示
图片序号[1,2,3,4,5,6]分别对应图片[右,后,左,前,上,下]
1.3 完整代码
function panoramic2box
oriPic=imread('889027-884424860.jpg');
[rows,cols,~]=size(oriPic);
for i=cols:-1:1
tempListR=oriPic(floor(rows/4):ceil(3*rows/4),i,1);
tempListG=oriPic(floor(rows/4):ceil(3*rows/4),i,1);
tempListB=oriPic(floor(rows/4):ceil(3*rows/4),i,1);
if all(round(tempListR-mean(tempListR))==0)&&all(tempListR==tempListG)&&all(tempListR==tempListB)
oriPic(:,i,:)=[];
else
break;
end
end
oriPic=oriPic(:,end:-1:1,:);
for i=size(oriPic,2):-1:1
tempListR=oriPic(floor(rows/4):ceil(3*rows/4),i,1);
tempListG=oriPic(floor(rows/4):ceil(3*rows/4),i,1);
tempListB=oriPic(floor(rows/4):ceil(3*rows/4),i,1);
if all(round(tempListR-mean(tempListR))==0)&&all(tempListR==tempListG)&&all(tempListR==tempListB)
oriPic(:,i,:)=[];
else
break;
end
end
oriPic=oriPic(:,end:-1:1,:);
for i=rows:-1:1
tempListR=oriPic(i,floor(cols/4):ceil(3*cols/4),1);
tempListG=oriPic(i,floor(cols/4):ceil(3*cols/4),1);
tempListB=oriPic(i,floor(cols/4):ceil(3*cols/4),1);
if all(round(tempListR-mean(tempListR))==0)&&all(tempListR==tempListG)&&all(tempListR==tempListB)
oriPic(i,:,:)=[];
else
break;
end
end
oriPic=oriPic(end:-1:1,:,:);
for i=size(oriPic,1):-1:1
tempListR=oriPic(i,floor(cols/4):ceil(3*cols/4),1);
tempListG=oriPic(i,floor(cols/4):ceil(3*cols/4),1);
tempListB=oriPic(i,floor(cols/4):ceil(3*cols/4),1);
if all(round(tempListR-mean(tempListR))==0)&&all(tempListR==tempListG)&&all(tempListR==tempListB)
oriPic(i,:,:)=[];
else
以上是关于MATLAB 全景图切割及盒图显示的主要内容,如果未能解决你的问题,请参考以下文章