赵庆鹏. 常见图像退化问题分析及其复原技术研究[D].北京邮电大学,2008.
上图是图像畸变复原的整体框架,本文将对曲面畸变进行描述,并用matlab进行复现。
我所选取的图片无明显的透视变换,所以只需在图片上进行曲面畸变的复原即可。
首先读取图片:
I = imread('001.jpg'); %基准图像
J = imread('002.jpg'); %待配准图像
[m,n] = size(J);
[o,p] = size(I);
其中001.jpg是无畸变的原始图像,002.jpg是几何畸变的图像。分别计算两幅图像的长和高。(J图像的长为n,高为m,同理I图像的长为p,高为o)
在读取的图片I和J中,选取若干个点,我选取了30个点,这30个坐标点的选取应分散在图片的各个角落 。建议在扭曲的区域多选几个点。
cpselect(J,I);&matlab手动取点工具箱
xlswrite('data1.xls',fixedPoints);
xlswrite('data2.xls',movingPoints);
把这些点保存在data1.xls和data2.xls文档中,到时候调取数据的时候可以更加方便。
接下来用matlab中的lsqcurvefit函数进行多项式拟合,在拟合函数中需要计算出a1到a6的数值。
fixedPoints = xlsread('data1.xls');%读取excel文件中的坐标数据
movingPoints = xlsread('data2.xls');
x0 = fixedPoints(:,1);
y0 = fixedPoints(:,2);
x1 = movingPoints(:,1);
y1 = movingPoints(:,2);
data = [x1,y1];
a = [1 1 1 1 1 1];%初始的a1到a6的拟合值
a1 = lsqcurvefit('fun',a,data,x0);%data是精准图像的横纵坐标,x0是畸变图像的横坐标
a2 = lsqcurvefit('fun',a,data,y0);%y0是畸变图像的纵坐标
以下是对lsqcurvefit函数的具体介绍,拟合结果会得到a1和a2两个函数的拟合系数。分别用两个函数,找到畸变图像到复原图像点对点的映射。
接着执行点对点的映射操作:
J2 = uint8(zeros(size(J)));
for rgb = 1:3
for i = 1:m
for j = 1:n
if round(fun(a1,[i,j]))>=1 && round(fun(a1,[i,j]))<=c && round(fun(a2,[i,j]))>=1 && round(fun(a2,[i,j]))<=d
J2(i,j,rgb) = J1(round(fun(a1,[i,j])),round(fun(a2,[i,j])),rgb);
end
% J2(round(fun(a1,[i,j])),round(fun(a2,[i,j]))) = J(i,j);
% end
end
end
end
[x,y] = size(J2);
J2就是变换后的图像,但是这样得到的图像会有像素的重叠,所以还需要进行双线性插值,对这些重叠的像素进行修正:
J3 = imcrop(I,[98 180 60*o/x 60*p/y]);
J4 = imcrop(J2,[41 80 60 60]);
[k,y,z] = size(J3);
[h,t,e] = size(J4);
%%重采样
%双线性内插法
u = h/k;
v = t/y;
itp = uint8(zeros(k,y,3));
for rgb = 1:3
for i = ceil(1/u):k-1
iu = floor(i*u);
for j = ceil(1/v):y-1
jv = floor(j*v);
itp(i,j,rgb) = (1-(i*u-iu))*(1-(j*v-jv))*J4(iu,jv,rgb)...
+(1-(i*u-iu))*(j*v-jv)*J4(iu,jv+1,rgb)...
+(i*u-iu)*(1-(j*v-jv))*J4(iu+1,jv,rgb)...
+(i*u-iu)*(j*v-jv)*J4(iu+1,jv+1,rgb);
end
end
end
双线性插值的具体知识可以在百度百科中查阅。
最后显示图片:
subplot(231),imshow(J),title('待配准图像');
subplot(232),imshow(I),title('基准图像');
subplot(233),imshow(J2),title('多项式几何校正后');
效果不太好,原因是我在选点的时候没有分散的选点,使得拟合的结果不太好,如果能在右上角多选取一些点,效果会更好。