[1]王杰英. 侧扫声呐图像的三维重构[D].浙江大学,2018.
\qquad 这里先向学长表示感谢!
\qquad 有关侧扫声呐三维重构的全流程可以参考以下文章,它以南海沉船为例,详细地阐述了侧扫声呐SFS三维重构的全过程
[1]刘小菊,施祺,杨红强,周胜男.基于侧扫声呐影像的南海珊瑚礁沉船及周边地形重建[J].热带地理,2020,40(02):278-288.DOI:10.13284/j.cnki.rddl.003221.
\qquad 本文是在已经解析出XTF文件的基础之上进行的图像处理,关于XTF文件的解析可以参考文章
https://blog.csdn.net/SuperiorEE/article/details/123012392
\qquad 首先我们来回顾一下侧扫声呐(SSS)成像原理,由此引出我们的问题:为什么要对侧扫声图进行图像处理?
\qquad 侧扫声呐是通过向一个扇区发射声波并在遇到障碍物时发生反射的原理来识别地形。这其实就是一个简单的测距原理。侧扫声呐的接收器根据声波传回的早晚和强度,依次在侧扫声图上留下痕迹,如下图顶部。反射愈早的声波越先被接收到,因此会在靠左(但不是最左的位置),相应地,反射发生愈晚的声波就会在声图右侧留下痕迹。痕迹的强度(即明暗)与声音的回波强度有关,回波强度越强,声图该点就越亮。
\qquad 简单介绍之后我们就发现存在着这么几个问题:1.为什么声图的最左侧会一片漆黑(如下图所示)?
\qquad 事实上,我们把这部分区域叫做水柱区。因为侧扫声图上横向表示了声波返回时间的长短,几乎没有声波能在极短的时间内回来(除了微弱的水体反射),因此左侧接近一篇漆黑。而左侧漆黑与右侧有一个交界线,我们称之为海底线,海底线就是最早被接收器接收的强回波,应该是距离侧扫声呐最近的地方——垂直向下的海底(这里假设侧扫角可以覆盖到垂直方向),因此这条线就称为海底线。根据海底线我们就可以算出侧扫声呐距离海底的高度H(声波返回时间*声速),其实这也可以直接在xtf文件中解析出来(一般是联测的单波束声呐测算出来的),相关解析也见本人文章
https://blog.csdn.net/SuperiorEE/article/details/123012392
\qquad 我们知道,声波在水中会产生较为明显的水体吸收,这种吸收显然和距离有关。声波传输得距离越长,损失的能量就越大。我们通过对声图的分析,明显可以看到声图左侧(平距靠近声呐侧)偏亮,而右侧偏暗。因此为了消除这样的干扰,我们需要进行增益补偿。
\qquad 这里采用的是滑窗灰度增益补偿方法。主要内容可以见王杰英论文,核心公式如下,重叠的滑窗按照距离进行加权
\qquad 得到结果如下,增益补偿曲线和补偿之后的图片
\qquad 除此之外,我们发现,侧扫声图上从左到右是按照声波返回时间长短来计算的,因此侧扫声图横向的指标实际上是和斜距成正比的。这里斜距就定义为从侧扫声呐头到地形某处的直线距离(一般忽略微观地形起伏)。因此我们就会发现,要使横向反映的是横距而非斜距,就要进行斜距校正。一般来说,可以使用以下公式实现 X = L 2 − H 2 X=\sqrt{L^2-H^2} X=L2−H2
\qquad 其中,L就是斜距,H是侧扫声呐到海底的高度,其获取方法见本章前文。
\qquad 我们发现斜距校正后还存在着一些问题,因为像素是离散的整数点,我们如果对其进行根号运算,由于非线性的关系,初步斜距校正后就会出现缝隙。根据王杰英的方法,我们对其进行3*3像素矩阵中周围8个点的均值作为中心黑点的亮度值,对其进行插值,可以得到以下结果。
\qquad 得到这样的结果已经可以初步满足我们的处理要求了,可以直接放入我们选择的SFS模型中取,进行高度反演了。
%功能描述:通过滑窗平均的方法对图像进行均值明度统一,从而抵消水体吸收的干扰。
%输入:E0,XTF原始归一化强度方阵
%输出:滑窗行向量(代表着E0在横坐标上的增益)
%使用示例:
% A=Amplify_get1(E);
% A2=repmat(A,range,1);
% E=E.*A2;
%公式推导:浙江大学王杰英论文
%验证时间:2022年4月2日15:44:56
function Amplify_C=Amplify_get1(E0) %E0 is selected aera with smooth surface
n=3;%滑窗数,不要修改
[length,width]=size(E0);%要求E0宽度是4倍数像素
window_length=fix(width./(n-1));
seperate_length=fix(window_length./2);
Amplify_C=0.*ones(1,width);%初始化
threshold=0.05; %明度低于此不计入
M_acc=[0 0 0 0];
M_dark=[0 0 0 0];
point_num_origin=window_length*length;%每块窗口点的个数
for k=1:4
acc_count=0;
dark_count=0;%黑色点计数
%求M1,M2,M3和M
for i=(k-1)*seperate_length+1:k*seperate_length
for j=1:length
if(E0(j,i)>threshold)
acc_count=acc_count+E0(j,i);
else
dark_count=dark_count+1;
end
end
end
M_acc(k)=acc_count;
M_dark(k)=dark_count;
end
point_num_perwindow=[point_num_origin-M_dark(1)-M_dark(2) ...
point_num_origin-M_dark(2)-M_dark(3) ...
point_num_origin-M_dark(3)-M_dark(4)];%每个窗口可用点的个数
acc_count_perwindow=[M_acc(1)+M_acc(2) M_acc(2)+M_acc(3) M_acc(3)+M_acc(4)];
M_ave=acc_count_perwindow./point_num_perwindow;
M_total=sum(acc_count_perwindow)/sum(point_num_perwindow);
%整图求和得到C,公式见论文
for i=1:width
%求和
if(i<=1*seperate_length)
Amplify_C(i)=M_total./M_ave(1);
elseif(i<=2*seperate_length)
Amplify_C(i)=(M_total./M_ave(2))*(i/seperate_length-1)+...
(2-i/seperate_length)*(M_total./M_ave(1));
elseif(i<=3*seperate_length)
Amplify_C(i)=(M_total./M_ave(3))*(i/seperate_length-2)+...
(3-i/seperate_length)*(M_total./M_ave(2));
else
Amplify_C(i)=M_total./M_ave(3);
end
end
end
%功能描述:对图像进行斜距校正和插值
%输入:E1,增益补偿后的E,和H,海底线对象的像素数目,也即像素高度
%输出:斜距校正后的E
%使用示例:见test_slant
% H=277-5;防止溢出,需要减去5
% E_slant_correct=Slant_correct(E,H);
% figure('name','斜距校正的图像');
% imshow(E_slant_correct);
%公式推导:浙江大学王杰英论文
%验证时间:2022年4月3日15:36:09
function E_slant_correct=Slant_correct(E1,H)%E1是增益补偿之后的矩阵,H单位是像素,是海底线对应的像素高度
[length,width]=size(E1);
lst=H:width;%初始化
for i=H:width
lst(i-H+1)=sqrt(i.^2-H.^2)+1;
end
disp(lst);
[p_,lst_len]=size(lst);
E2_width=fix(lst(lst_len));
E2=0.*ones(length,E2_width);
for i=1:length
for j=1: lst_len
E2(i,fix(lst(j)))=E1(i,j-1+H);
end
end
figure('name','初步补偿图像')
imshow(E2);
%缝隙消除
[E2_length,E2_width]=size(E2);
for i=2:E2_length-1
for j=2:E2_width-1
if(E2(i,j)==0)
acc=0;
count=0;
if(E2(i-1,j-1)~=0)
acc=acc+E2(i-1,j-1);
count=count+1;
end
if(E2(i-1,j)~=0)
acc=acc+E2(i-1,j);
count=count+1;
end
if(E2(i-1,j+1)~=0)
acc=acc+E2(i-1,j+1);
count=count+1;
end
if(E2(i,j-1)~=0)
acc=acc+E2(i,j-1);
count=count+1;
end
if(E2(i+1,j+1)~=0)
acc=acc+E2(i+1,j+1);
count=count+1;
end
if(E2(i,j+1)~=0)
acc=acc+E2(i,j+1);
count=count+1;
end
if(E2(i+1,j-1)~=0)
acc=acc+E2(i+1,j-1);
count=count+1;
end
if(E2(i+1,j)~=0)
acc=acc+E2(i+1,j);
count=count+1;
end
%临近点计算
%赋值
if(count~=0)
E2(i,j)=acc/count;
end
end
end
end
E_slant_correct=E2;
%%
figure('name','斜距校正的图像');
imshow(E_slant_correct);
end