欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

MATLAB月球坑识别和降落避障

程序员文章站 2022-03-04 20:02:22
...

MATLAB月球坑识别和降落避障

此为全国大学生数学建模大赛2014年的A题,参加了学校的数模培训,期间第一轮模拟赛就是这个题,再加上之前有看过CNN的算法,突发奇想魔改了一下CNN的算法,没想到最后的识别效果还能够看,特此纪念下

题目

4)粗避障段:粗避障段的范围是距离月面2.4km到100m区间,其主要是要求避开大的陨石坑,实现在设计着陆点上方100m处悬停,并初步确定落月地点。
嫦娥三号在距离月面2.4km处对正下方月面2300×2300m的范围进行拍照,获得数字高程如附图5所示(相关数据文件见附件3),并嫦娥三号在月面的垂直投影位于预定着陆区域的中心位置。
MATLAB月球坑识别和降落避障
该高程图的水平分辨率是1m/像素,其数值的单位是1m。例如数字高程图中第1行第1列的数值是102,则表示着陆区域最左上角的高程是102米。
(5)精避障段:精细避障段的区间是距离月面100m到30m。要求嫦娥三号悬停在距离月面100m处,对着陆点附近区域100m范围内拍摄图像,并获得三维数字高程图。分析三维数字高程图,避开较大的陨石坑,确定最佳着陆地点,实现在着陆点上方30m处水平方向速度为0m/s。附图6是在距离月面100m处悬停拍摄到的数字高程图(相关数据文件见附件4)。MATLAB月球坑识别和降落避障
该数字高程的水平分辨率为0.1m/像素,高度数值的单位是0.1m。

暂且不考虑题目要求用的高程图,我就要上魔改版CNN硬刚 ╯▽╰

效果

因为程序还有点小bug,卷积的边界处仅仅只依靠了题目中相等的边长长度来补全,导入非正方形的图亲测会将坐标标出边界框外……其次是暂时不支持500x500以下分辨率,多多少少会出奇怪的问题,题目中的2300x2300和100x100刚刚好没问题;以及高度太高导致坑过于密集也会对识别造成影响。
放了个demo出来,还有bug和需要优化的地方,等后续有空再拐回来修好了。
不多说了,上图

  • 粗避障
    MATLAB月球坑识别和降落避障

  • 细避障
    MATLAB月球坑识别和降落避障

  • 测试图1
    MATLAB月球坑识别和降落避障

  • 测试图2
    MATLAB月球坑识别和降落避障

图片的中心点对应实时航天器的位置,红色线从中心点出发,到结束处为平缓地带(没有坑的可以降落的地方)

处理思路

  1. 读入图片
  2. 刚开始加了滤波以除去一些噪点,后边发现去掉对坑边缘的识别效果更好,所以并不推荐对图像进行这些操作
  3. 大津算法对图像进行二值化处理,我们就可以得到这样的图
    MATLAB月球坑识别和降落避障
  4. 对每一行的黑色长度进行测量,测量出整个图片中所有行的黑色的长度并且统计到矩阵中,得到这样的格式 [X坐标,Y坐标,黑色长度]
  5. 去除低于80个像素点的长度,因为没什么用,过小的坑最后也会被处理掉,但是前期容易影响直径均值。去掉这些坑后重新构成一个新的矩阵
  6. 创建矩形构建边界框,如图,红色线即为原本的按行测量的黑色线,蓝色线为红色线在中心点旋转90度后形成,这样即可构建出一个边界框(周围的虚线),判断这四个点是否在图像中,留下在图像中的4个顶点转移到新的矩阵中
    MATLAB月球坑识别和降落避障
  7. 判断四个点是否都为白色(旋转得到的,说明中心点肯定是黑色,四个顶点不一定是黑色,如果是黑色即为连续的图,如果为白色可断定已经标记到了坑中心),满足这个条件的再次转移到一个新的矩阵。同时,对这样标定的效果图:MATLAB月球坑识别和降落避障 可以看到,没有误判,只有漏掉的(这样更好),坑越明显,其直径起到的权重越大,对均值直径影响越大,此处的均值直径也是后边用在魔改版卷积的每个单元的边长
  8. 按照均值直径的倍数补全二值图,并且按照均值直径的长度进行分割,分割成若干个小正方形,并且去除掉所有包含白色像素点的小正方形,此时,我们看下效果图MATLAB月球坑识别和降落避障 我们看到,对比原图,所有包含坑的地方已经全部保险去除
  9. 以正方形的形式去统计最大面积,并且只取第一个最大面积,计算出该矩阵对应的小正方形的中心位置(分奇偶边长,可能会有1个像素的误差),得到代码中的target_centre,即目标中心
  10. 连接图片中心和目标中心,好了,可以了

T T其实根本就不算是卷积,而是滚动,此处并没有卷积核,没有积,没有叠加层,充其量也就算个残废的CNN…哈哈哈哈

代码

此代码还有bug,有更好建议的朋友欢迎留言我哈哈

clc;clear;close;
pic=imread('test.jpg');
% subplot(1,2,1),imshow(pic);
% J=ordfilt2(pic,5,ones(3,4));
% J=ordfilt2(J,5,ones(3,4)); 
% J=filter2(fspecial('average',16),J)/255;
level=graythresh(pic);
binary_img=im2bw(pic,level);
% subplot(1,2,2),imshow(binary_img);
[length,width]=size(binary_img);
% length <--> y
% width  <--> x
discontinuous_object=[];
for l = 1:length
    w=1;
    while w<(width+1)
        tmp=zeros(1,3);
        if binary_img(l,w) == 1
            w=w+1;
            continue;
        else
            blk_let=blank_length(w,l,binary_img,width);
            tmp=[w,l,blk_let];
            discontinuous_object=[discontinuous_object;tmp];
            w=w+blk_let;
        end
    end
end
[discontinuous_number,tmp_01]=size(discontinuous_object);
reliable_length=[];
for i=1:discontinuous_number
    if discontinuous_object(i,3) > 80
        reliable_length=[reliable_length;discontinuous_object(i,:)];
    else
        continue;
    end
end
[line_num,tmp02]=size(reliable_length);
reliable_matrix=[];
for i=1:line_num
    tmp_matrix=create_matrix(reliable_length(i,:),width,length);
    reliable_matrix=[reliable_matrix;tmp_matrix];
end
[remat_length,tmp03]=size(reliable_matrix);
right_matrix=[];
for i=1:(remat_length/4)
    jud_matr=reliable_matrix(i*4-3:i*4,:);
    if binary_img(jud_matr(1,2),jud_matr(1,1))==1&&binary_img(jud_matr(2,2),jud_matr(2,1))==1&&binary_img(jud_matr(3,2),jud_matr(3,1))==1&&binary_img(jud_matr(4,2),jud_matr(4,1))==1
        right_matrix=[right_matrix;jud_matr];
    else
        continue;
    end
end
[right_matr_length,tmp04]=size(right_matrix);
% imshow(binary_img);
% hold on;
% for i=1:(right_matr_length/4)
%    tmp_matr=right_matrix(i*4-3:i*4,:);
%    line([tmp_matr(1,1),tmp_matr(2,1)],[tmp_matr(1,2),tmp_matr(2,2)],'Color','r','LineWidth',1);
%    line([tmp_matr(2,1),tmp_matr(3,1)],[tmp_matr(2,2),tmp_matr(3,2)],'Color','r','LineWidth',1);
%    line([tmp_matr(3,1),tmp_matr(4,1)],[tmp_matr(3,2),tmp_matr(4,2)],'Color','r','LineWidth',1);
%    line([tmp_matr(4,1),tmp_matr(1,1)],[tmp_matr(4,2),tmp_matr(1,2)],'Color','r','LineWidth',1);
% end
% hold off;
all_len=0;
for i=1:(right_matr_length/4)
    tmp_matr=right_matrix(i*4-3:i*4,:);
    all_len=all_len+(tmp_matr(2,1)-tmp_matr(1,1))/2.0;
end
r=all_len/(right_matr_length/4.0);
r=round(r*2);
if mod(width,r)==0
    matr_num=width/r;
else
    matr_num=ceil(width/(r*1.0));
end
full_matrix=zeros(r*matr_num);
for i=1:length
    for j=1:width
        full_matrix(i,j)=binary_img(i,j);
    end
end
% imshow(full_matrix);
for i=1:matr_num
    for j=1:matr_num
        if ismember(1,full_matrix(((i-1)*r+1):(i*r),((j-1)*r+1):(j*r)) )
            full_matrix(((i-1)*r+1):(i*r),((j-1)*r+1):(j*r))=1;
        end
    end
end
% imshow(full_matrix);
for i=1:length
    for j=1:width
        binary_img(i,j)=full_matrix(i,j);
    end
end
centre=[ceil(length/2.0),ceil(width/2.0)];
matrix_size=[];
for y=1:length
    x=1;
    while x<=width
        if binary_img(y,x) == 1
            x=x+1;
            continue;
        else
            size_tmp=get_black_size(y,x,length,width,r,binary_img);
            matrix_size=[matrix_size;size_tmp];
            x=x+size_tmp(1,3);
        end
    end
end
MAX_SIZE=max(matrix_size(:,4));
[maxm_length,tmp05]=size(matrix_size);
for i=1:maxm_length
    if matrix_size(i,4)==MAX_SIZE
        MAX_MATRIX=matrix_size(i,:);
        break;
    else
        continue;
    end
end
target_centre=[ceil(MAX_MATRIX(1)+(MAX_MATRIX(3)/2.0)),ceil(MAX_MATRIX(2)+(MAX_MATRIX(3)/2.0))];   % x,y
hold on;
imshow(pic);
line([centre(2),target_centre(2)],[centre(1),target_centre(1)],'Color','r','LineWidth',1);
hold off;




function [matrix]=get_black_size(y,x,length,width,r,binary_img)
sm_y=y;sm_x=x;
for len=r:width
    if  (y+len)>0 && (y+len)<=length && (x+len)>0 && (x+len)<=width
        matrix_tmp=binary_img(y:(y+len),x:(x+len));
    else
        sm_length=len-1;
        s=sm_length*sm_length;
        matrix=[sm_y,sm_x,sm_length,s];
        break;
    end
    if ismember(1,matrix_tmp) == 1
        sm_length=len-1;
        s=sm_length*sm_length;
        matrix=[sm_y,sm_x,sm_length,s];
        break;
    else
        continue;
    end
end
end

function [matrix]=create_matrix(s,w,l)
matrix_tmp=[];
if mod(s(1,3),2)==0 %ou shu
    half_l=s(1,3)/2;
    x_centre=s(1,1)+half_l;
    matrix_tmp=[s(1,1),s(1,2)-half_l;
                x_centre+half_l,s(1,2)-half_l;
                x_centre+half_l,s(1,2)+half_l;
                s(1,1),s(1,2)+half_l];
end
if mod(s(1,3),2)==1 %ji shu
    half_l=(s(1,3)-1)/2;
    x_centre=s(1,1)+half_l;
    matrix_tmp=[s(1,1),s(1,2)-half_l;
                x_centre+half_l,s(1,2)-half_l;
                x_centre+half_l,s(1,2)+half_l;
                s(1,1),s(1,2)+half_l];
end
if s(1,1)>0 && s(1,1)<=w && (x_centre+half_l)>0 && (x_centre+half_l)<=w && (s(1,2)-half_l)>0 && (s(1,2)-half_l)<=l && (s(1,2)+half_l)>0 && (s(1,2)+half_l)<=l
   matrix=matrix_tmp;
else
   matrix=[];
end
end

function [le]=blank_length(x,y,bpic,width)
le=0;
for a=x:width
    if bpic(y,a) == 1
        break;
    else
        le=le+1;
        continue;
    end
end
end
相关标签: MATLAB