您的位置:首页 > 其它

《基于双经度模型的鱼眼图像畸变校正方法》code

2016-05-16 21:33 666 查看
网友说现在用得多的是双经度法来校正鱼眼图像,理论部分来自题目说的这个期刊论文。

主要分5步:

1,和期刊论文《一种鱼眼图象到透视投影图象的变换模型》中一样求光学中心和真实半径。。。循环三次求平均值得到鱼眼图像的中心和半径

2,目标图像坐标转为双经度坐标

3,双经度坐标转为球面坐标

4,球面坐标转鱼眼图像坐标

5,双线性插值

其中第4步,有两种投影方式:正交投影和等距投影

第1步:

%《一种鱼眼图象到透视投影图象的变换模型》

% 对于齐次线性方程 A*X =0;当A的秩大于列数时,就需要求解最小二乘解 使用SVD分解矩阵A,[U S V] = svd(A); U 由 A*A'的特征向量组成,V 由

%A'*A的特征向量组成,因此,奇异值矩阵S中最小的奇异值对应的V中的奇异向量即为最小二乘解。

function result=doublejingdu(A)

A=imread('F:\fisheye\14.JPG');

[A,R]=kuaisusaomiao(A,40);

[width,height,kk]=size(A);

%xo=R;

%yo=R;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

imshow(A)

hold on;

[x1 y1]=ginput(1);

plot(x1,y1,'g.');

drawnow;

[x2 y2]=ginput(1);

plot(x2,y2,'g.');

drawnow;

[x3 y3]=ginput(1);

plot(x3,y3,'g.');

drawnow;

[x4 y4]=ginput(1);

plot(x4,y4,'g.');

drawnow;

[x5 y5]=ginput(1);

plot(x5,y5,'g.');

drawnow;

[x6 y6]=ginput(1);

plot(x6,y6,'g.');

drawnow;

[x7 y7]=ginput(1);

plot(x7,y7,'g.');

drawnow;

hold off;

%[x8 y8]=ginput(1);

%plot(x8,y8,'g.');

%drawnow;

%[x9 y9]=ginput(1);

%plot(x9,y9,'g.');

%drawnow;

%[x10 y10]=ginput(1);

%plot(x10,y10,'g.');

%drawnow;

%hold off;

M0=[x1,y1;x2,y2;x3,y3;x4,y4;x5,y5;x6,y6;x7,y7];

M=zeros(7,6);

j=M0(:,2);

i=M0(:,1);

M(:,1)=j.^2;

M(:,2)=2*i.*j;

M(:,3)=i.^2;

M(:,4)=j;

M(:,5)=i;

M(:,6)=1;

[U,S,V]=svd(M);

%选S里最小对应的V即为所求的六个参数A B C D E F

S =

1.0e+007 *

2.9628 0 0 0 0 0

0 0.6137 0 0 0 0

0 0 0.0733 0 0 0

0 0 0 0.0000 0 0

0 0 0 0 0.0000 0

0 0 0 0 0 0.0000

0 0 0 0 0 0

V =

-0.5589 -0.7725 0.3016 0.0002 -0.0004 0.0000

-0.7728 0.3533 -0.5272 -0.0002 -0.0000 0.0000

-0.3007 0.5277 0.7944 -0.0000 -0.0002 0.0000

-0.0002 -0.0003 0.0003 -0.6256 0.7802 -0.0008

-0.0002 0.0001 0.0000 0.7802 0.6256 -0.0001

-0.0000 -0.0000 0.0000 -0.0004 0.0007 1.0000

A=0.0002;

B=-A;

C=0;

D=-0.6256;

E=0.7802;

F=-0.0004;

u1=(C*D-B*E)/2/(B^2-A*C);

v1=(A*E-B*D)/2/(B^2-A*C);

a1=sqrt(((C*D^2-2*B*D*E+A*E^2)/4/(B^2-A*C)+F)*((A+C+sqrt((A-C)^2+4*B^2))/2/(B^2-A*C)));

u1 =

1.9505e+003

v1 =

386.5000

a1 =

0 +1.9277e+003i

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

u2=(C*D-B*E)/2/(B^2-A*C);

v2=(A*E-B*D)/2/(B^2-A*C);

a2=sqrt(((C*D^2-2*B*D*E+A*E^2)/4/(B^2-A*C)+F)*((A+C+sqrt((A-C)^2+4*B^2))/2/(B^2-A*C)));

u2 =

2.4340e+003

v2 =

646.8333

a2 =

1.4902e+003

u3=(C*D-B*E)/2/(B^2-A*C);

v3=(A*E-B*D)/2/(B^2-A*C);

a3=sqrt(((C*D^2-2*B*D*E+A*E^2)/4/(B^2-A*C)+F)*((A+C+sqrt((A-C)^2+4*B^2))/2/(B^2-A*C)));

u3 =

337

v3 =

649.8333

a3 =

634.9031

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%




选择的是这三条弧线 第一条是最右边这条 第二条是金字塔那条 第三条是柱子那条 我在想是不是不能选第一条这样横着的 或者说我这个图不适合双经度校正? 第一个算出来的u1 v1和a1那么奇怪 只有u3 v3 a3算出来是看起来比较正常的 还有SVD分解那里 最小S对应的V就是参数A B C D E F 可是比如第一次算出的S有三个都是0那我选哪个呢?? 奇怪 然后我主要想看后面的效果
我就暂且把第三次算的变化一两个像素作为平均值好了

%final center and R

u0=338;

v0=648;

R=635;

后面的几步:

function resultimg=calibration(fisheyeimg,Rtrue,u0,v0,flag)

%《基于双经度模型的鱼眼图像畸变校正方法》

% Detailed explanation goes here

R=Rtrue+10;

for i=1:2*R

for j=1:2*R

arfa=(pi/2/R)*i;

beta=(pi/2/R)*j;

sita=pi-arfa;

fi=pi-beta;

fenmu1=sqrt((tan(fi))^2+1+((tan(fi))^2/(tan(sita))^2));

x=R/fenmu1;

fenmu2=sqrt((tan(sita))^2+1+((tan(sita))^2/(tan(fi))^2));

y=R/fenmu2;

fenmu3=sqrt(1/((tan(fi))^2)+1+(1/(tan(sita))^2));

z=R/fenmu3;

if(flag==1)

u=x+u0;

v=y+v0;

else

r=R*arccos(z/R);

u=r*x/sqrt(x^2+y^2)+u0;

v=r*y/sqrt(x^2+y^2)+v0;

end

[ER,EG,EB]=doublelinechazhi(fisheyeimg,v,u);

resultimg(i,j,1)=ER;

resultimg(i,j,2)=EG;

resultimg(i,j,3)=EB;

end

end

end

双线性插值自己写的感觉很慢啊:

function [ER,EG,EB]=doublelinechazhi(fisheyeimg,u,v)

%《基于双经度模型的鱼眼图像畸变校正方法》双线性插值

% Detailed explanation goes here

fisheyeimgR=fisheyeimg(:,:,1);

fisheyeimgG=fisheyeimg(:,:,2);

fisheyeimgB=fisheyeimg(:,:,3);

%R channel

FR=(u-floor(u))*(fisheyeimgR(floor(u),ceil(v))-fisheyeimgR(floor(u),floor(v)))+fisheyeimgR(floor(u),floor(v));

GR=(u-floor(u))*(fisheyeimgR(ceil(u),ceil(v))-fisheyeimgR(ceil(u),floor(v)))+fisheyeimgR(ceil(u),floor(v));

ER=(v-floor(v))*(GR-FR)+FR;

%G channel

FG=(u-floor(u))*(fisheyeimgG(floor(u),ceil(v))-fisheyeimgG(floor(u),floor(v)))+fisheyeimgG(floor(u),floor(v));

GG=(u-floor(u))*(fisheyeimgG(ceil(u),ceil(v))-fisheyeimgG(ceil(u),floor(v)))+fisheyeimgG(ceil(u),floor(v));

EG=(v-floor(v))*(GG-FG)+FG;

%B channel

FB=(u-floor(u))*(fisheyeimgB(floor(u),ceil(v))-fisheyeimgB(floor(u),floor(v)))+fisheyeimgB(floor(u),floor(v));

GB=(u-floor(u))*(fisheyeimgB(ceil(u),ceil(v))-fisheyeimgB(ceil(u),floor(v)))+fisheyeimgB(ceil(u),floor(v));

EB=(v-floor(v))*(GB-FB)+FB;

end

太慢了 就不用双线性插值 用最近邻的像素代替不是整数的点 看下效果 结果:


我只能呵呵了 看来我错了

重新看论文 看到一个地方错了 空间直线投影成球面大圆 球面大圆投影成鱼眼图像的椭圆 算出的长轴a只是直径 应该再除以2 才是半径Rtrue 可是光学中心和鱼眼图像中心是一个意思吗 即使改了 出来也不对啊

我重新选一幅图 试试这次出来的S:


这次的S出来分别是3.9489、1.1605、0.2224、0.0003、0.0001、0那么最小的就是最后一个0 它对应的V向量 A=0 、B=0、C=0.0001、D=-0.0093、E=-0.0174、F=0.9998可是这样一来 那个光学中心u0、v0分母都是0了啊 长轴的分母也是0啊???为什么 难道选弧线还有什么特别要求?

然后看到http://blog.csdn.net/qq_15947787/article/details/51441128这位兄台也写了双经度法 果然论文里还是有笔误的 只是这个兄台的中心和半径是直接给出的。 所以我也不知道他会不会遇到我这种问题 可是我按照他的改了

先不看左右反了 单纯看校正效果 很差啊 虽然半径和光学中心都有偏差 但也不该这样房子上的柱子还是那么弯 不过可以看出是双极点
四个角拉伸果然严重。哎。。。还是不行。。。话说这个论文是在《电子测量与仪器学报》今年的CSCD核心上发表的 还可以有笔误?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: