MATLAB月球坑識別和降落避障

MATLAB月球坑識別和降落避障

此爲全國大學生數學建模大賽2014年的A題,參加了學校的數模培訓,期間第一輪模擬賽就是這個題,再加上之前有看過CNN的算法,突發奇想魔改了一下CNN的算法,沒想到最後的識別效果還能夠看,特此紀念下

題目

4)粗避障段:粗避障段的範圍是距離月面2.4km到100m區間,其主要是要求避開大的隕石坑,實現在設計着陸點上方100m處懸停,並初步確定落月地點。
嫦娥三號在距離月面2.4km處對正下方月面2300×2300m的範圍進行拍照,獲得數字高程如附圖5所示(相關數據文件見附件3),並嫦娥三號在月面的垂直投影位於預定着陸區域的中心位置。
這裏寫圖片描述
該高程圖的水平分辨率是1m/像素,其數值的單位是1m。例如數字高程圖中第1行第1列的數值是102,則表示着陸區域最左上角的高程是102米。
(5)精避障段:精細避障段的區間是距離月面100m到30m。要求嫦娥三號懸停在距離月面100m處,對着陸點附近區域100m範圍內拍攝圖像,並獲得三維數字高程圖。分析三維數字高程圖,避開較大的隕石坑,確定最佳着陸地點,實現在着陸點上方30m處水平方向速度爲0m/s。附圖6是在距離月面100m處懸停拍攝到的數字高程圖(相關數據文件見附件4)。這裏寫圖片描述
該數字高程的水平分辨率爲0.1m/像素,高度數值的單位是0.1m。

暫且不考慮題目要求用的高程圖,我就要上魔改版CNN硬剛 ╯▽╰

效果

因爲程序還有點小bug,卷積的邊界處僅僅只依靠了題目中相等的邊長長度來補全,導入非正方形的圖親測會將座標標出邊界框外……其次是暫時不支持500x500以下分辨率,多多少少會出奇怪的問題,題目中的2300x2300和100x100剛剛好沒問題;以及高度太高導致坑過於密集也會對識別造成影響。
放了個demo出來,還有bug和需要優化的地方,等後續有空再拐回來修好了。
不多說了,上圖

  • 粗避障
    粗避障

  • 細避障
    細避障

  • 測試圖1
    測試圖1

  • 測試圖2
    測試圖2

圖片的中心點對應實時航天器的位置,紅色線從中心點出發,到結束處爲平緩地帶(沒有坑的可以降落的地方)

處理思路

  1. 讀入圖片
  2. 剛開始加了濾波以除去一些噪點,後邊發現去掉對坑邊緣的識別效果更好,所以並不推薦對圖像進行這些操作
  3. 大津算法對圖像進行二值化處理,我們就可以得到這樣的圖
    OTSU處理
  4. 對每一行的黑色長度進行測量,測量出整個圖片中所有行的黑色的長度並且統計到矩陣中,得到這樣的格式 [X座標,Y座標,黑色長度]
  5. 去除低於80個像素點的長度,因爲沒什麼用,過小的坑最後也會被處理掉,但是前期容易影響直徑均值。去掉這些坑後重新構成一個新的矩陣
  6. 創建矩形構建邊界框,如圖,紅色線即爲原本的按行測量的黑色線,藍色線爲紅色線在中心點旋轉90度後形成,這樣即可構建出一個邊界框(周圍的虛線),判斷這四個點是否在圖像中,留下在圖像中的4個頂點轉移到新的矩陣中
    構建邊界框
  7. 判斷四個點是否都爲白色(旋轉得到的,說明中心點肯定是黑色,四個頂點不一定是黑色,如果是黑色即爲連續的圖,如果爲白色可斷定已經標記到了坑中心),滿足這個條件的再次轉移到一個新的矩陣。同時,對這樣標定的效果圖:標定 可以看到,沒有誤判,只有漏掉的(這樣更好),坑越明顯,其直徑起到的權重越大,對均值直徑影響越大,此處的均值直徑也是後邊用在魔改版卷積的每個單元的邊長
  8. 按照均值直徑的倍數補全二值圖,並且按照均值直徑的長度進行分割,分割成若干個小正方形,並且去除掉所有包含白色像素點的小正方形,此時,我們看下效果圖卷積後 我們看到,對比原圖,所有包含坑的地方已經全部保險去除
  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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章