下列链接中图一为“枕形畸变”和“桶形畸变”。
http://www.cpanet.cn/cms/html/laozhanshuju/zixunzhongxin/zhongguosheyingbaodaodu/20070914/17250.html
桶形畸变和枕形畸变的软件校正
周 彧
通常情况下,广角镜头都有或多或少的桶形畸变,而远摄镜头则有一定的枕形畸变(图一),尤其是在变焦镜头的两端,这个问题更是十分严重,很多大变焦比便携式相机出于成本考虑,在这个方面更是有先天不足。不过现在这个问题简单了,因为最近一个名为“全景工具”(Panorama Tools)的软件在因特网上越来越流行,摄影者们通过这个软件可以轻而易举地校正桶形畸变和枕形畸变。
“全景工具”这个软件既有PC版(下载地址为http://home.no.net/dmaurer/%7Edersch/PanoTools.zip),也有Mac版(下载地址为http://home.no.net/dmaurer/%7Edersch/PanoTools2.2.sit.hqx),大多数摄影者手头的家用PC机上安装的Windows 95/98/Me/2000/XP都可以很方便地安装。通常,它是作为Adobe Photoshop Elements 1.0(含更高版本)或Photoshop 5.0(含更高版本)的插件来使用的,通过几个参数的设置即可实现自行校正畸变。需要注意的是,安装是应该将该软件中的pano12.dll文件拷贝到Photoshop的相应目录下,同时将adjust.8bf、correct.8bf、perspect.8bf、remap.8bf等几个文件拷贝到Photoshop下的Plug-ins文件夹下的Filters目录内,另外不要管PanoTools.zip这个压缩文件。遗憾的是,该软件目前只有英文版,不然,该软件的Readme文件中有很多技巧可供您参考。
一切安装就绪,您需要重新启动Photoshop,然后就可以在滤镜菜单中找到“全景工具”(Panorama Tools)。
在校正桶形畸变和枕形畸变时,您可以调用Filter->Panorama Tools->Correct(图二),然后有“Radial Shift”(光线偏移)会以高亮显示,点击“Options”(选项)设定“a”和“c”,选择所有色彩归零,然后设定“b”选项的值,使得“b”+“d”=1。在校正桶形畸变时,“b”表现为负数,反之,在校正枕形畸变时“b”则需要为正数。通常b的值应从-0.015或0.015(1.5%)开始试着设定(图三),直到照片中的线条变直为止。至于a和c两个值的用处,Readme文件中有详细介绍,但因此处并不涉及,因此您也无需了解。
具体操作方法如下:
桶形畸变校正。处理图四时参照垂直线的变形,参数设定如下:a=0,b=-0.016,c=0,d=1.016,结果,该软件成功地将垂直线条和建筑物的变形校正为直线(图五)。处理图六时有关参数设定为a=0,b=-0.018,c=0,d=1.018,结果也成功将窗口的直线校正了(图七)。
枕形畸变的校正。图八为远摄镜头拍摄的一张数码照片,有关参数设定如下:a=0,b=0.013,c=0,d=0.987,也成功地校正了畸变。不过值得一提的是,校正过程中切掉了照片顶部、底部、左右两侧各大约25个像素,但与影像校正的效果相比,这一裁切过程还是值得的(图九)。
从上述图例中可以看出,即使像图八这样使用该软件实际操作的例子,由于使用了Photoshop中的双三次插值,因此放大400%,锐度和像质也没有明显下降。我们可以认为这个软件采用的是无损处理,从其性价比上看,它确实是个很廉价的、不会造成很大像质损失的桶形畸变和枕形畸变校正软件。
2) 枕形失真程序:
clear all;
[filename, pathname] = uigetfile('*.bmp', '选择位图文件');
fn = [pathname,filename];
I=imread(fn);
I=im2double(I);
[m,n,c]=size(I);
hide=100;
for j=1:n
temp1=abs(fix(hide-hide*sin(j*pi/n)));
for i=temp1:m-2*hide+temp1
for k=1:c
temp2=fix(m*(i-temp1)/(m-2*hide));
if(temp2
N(i,j,k)=I(temp2,j,k);
end
end
end
end
subplot(1,2,1),imshow(N);
subplot(1,2,2),imshow(I);
3) 桶形失真程序:
clear all;
[filename, pathname] = uigetfile('*.bmp', '选择位图文件');
fn = [pathname,filename];
I=imread(fn);
I=im2double(I);
[m,n,c]=size(I);
for i=1:m
temp1=abs(fix(50-50*sin(i*pi/(m-1))));
for j=temp1:n-temp1
for k=1:c
temp2=fix(n*(j-temp1)/(n-2*temp1));
if(temp2
N(i,j,k)=I(i,temp2,k);
end
end
end
end
figure;
imshow(N);