获得人生第一桶金对遥感的一些思考

写blog的原因

前几天,一位同僚接了一个处理遥感灯光数据的单子,80块钱,就2个要求,一个是做一个最大值滤波,一个是把小于0的值改成0。要求是用MATLAB做,我其实一开始并没有学过MATLAB导入遥感影像的知识,我一开始也明白遥感影像有两个魂,一个是它背后的矩阵,一个是它的地理参考。而如果仅仅用imread的BIF导入的话会把第二个灵魂给丢掉。所以我想用ENVI进行滤波并用band math写一个逻辑语句赋值,但是同僚给我的影像我用envi打开的时候傻眼了,对方给的是一个灰度图像,两个灵魂同时缺失了。
在这里插入图片描述
这很明显是个珠三角的图,和我做一个小项目的山东省图叠一起,竟然会有重叠,那么地理参考就完全没意义了,就变成了计算机显示坐标系里的一张图了。后来同僚和我说,只要负责把MATLAB代码写出来,后续就不管它了。

第一个插曲

其实因为做一些遥感方面的东西的时间长把也不算长,说短也不短,而且如何获取数据是一个难题,所以我就想研究研究,我去NOAA(美国国家海洋大气局)搜了搜,但是有些复杂而且时间比较紧我就没有继续尝试找数据了(之前批量下载MODIS数据和批量重投影给了点经验和动力所以想试试)。

第二个插曲

与其说是同僚接任务不如说我接下了单子,由于是头天晚上10:30他才和我说这个单子,我其实算法自己早就写过了于是第二天写这个代码其实花了10分钟就写完了。

%交互式的获取文件名与路径获取图像
[filename,path] = uigetfile    %选择文件获取路径和文件名
str = [path,filename];         %合成路径名与文件名
[A,R]  = geotiffread(str);    %读取图像矩阵与地理坐标系
[m.n] = size(A);
%滤波部分
for i = 2:m-1
    for j=2:n-1
        near = [A(i-1,j-1),A(i-1,j),A(i-1,j+1),A(i,j-1),A(i,j+1), A(i+1,j-1),A(i+1,j),A(i+1,j+1)];
        near_max = max(near);
        if A(i,j) > 199.89 
            A(i,j) = near_max;               %把大于阈值的变为邻域内的最大值
        end
    end
end
%小于0的部分用0替代
for i = 2:m-1
    for j=2:n-1
        if A(i,j)<0
            A(i,j) = 0;              
        end
    end
end
%输出图像
geotiffwrite('dengguang.tif',A,R);

用uigetfile实在是逼不得已,因为从对面给数据以及一些问题来看就知道连绝对路径和相对路径都不知道,于是我就想直接让甲方点文件自动来拿这个路径和文件名吧,也算给甲方一点方便吧。否则MATLAB图像如果不在当前文件夹下就需要绝对路径来读取。这个最大值滤波其实就是以前数字图像处理写的一个很简单很低效的代码,而且当时我没有意识到我忽略了图像边缘。
plus:这个geotiffread和geotiffwrite可以把图像及地理参考给拿出来,也是这次学到的。

第三个插曲

在某节课的上课的时候我突然发现我做这个遍历的时候忘记把第一行第一列最后一行最后一列进行操作了,比如这里面确实有小于0的值,甲方也反应了这个问题,于是我改了改遍历的范围。而最大值滤波部分,在边缘无法处理的部分我则人为的填充,又写了4个循环处理。

%第一行
for j = 2:n-1
    near = [A1(1,j-1),A1(1,j+1),A1(m,j-1),A1(m,j),A(m,j+1),A1(2,j-1),A1(2,j),A1(2,j+1)];
    if A(1,j) > 119.89 
        A(1,j) = max(near);
    end
end
%最后一行
for j = 2:n-1
    near = [A1(m,j-1),A1(m,j+1),A1(m-1,j-1),A1(m-1,j),A1(m-1,j+1),A1(1,j-1),A1(1,j),A1(1,j+1)];
    if A(m,j) > 119.89 
        A(m,j) = max(near);
    end
end
%第一列
for i = 2:m-1
    near = [A1(i-1,n),A1(i-1,1),A1(i-1,2),A1(i,n),A1(i,2),A1(i+1,n),A1(i+1,1),A1(i+1,2)];
    if A(i,1) > 119.89
        A(i,1) = max(near);
    end
end
%最后一列
for i = 2:m-1
        near = [A1(i-1,n-1),A1(i-1,n),A1(i-1,1),A1(i,n-1),A1(i,1),A1(i+1,n-1),A1(i+1,n),A1(i+1,1)];
        if A(i,n) > 119.89
            A(i,n) = max(near);
        end
end

这种方法其实和后面要讲的冈萨雷斯教授在图像处理讲的padarray method里的replicate差不多,是一种反镜像的处理,只不过人为的处理,加入了更多循环,而且9邻域选取比较反麻烦。
在这里插入图片描述
就比如第一行第二个元素开始,需要这样取邻域,把最后一行补上来,同理,处理第一列补最后一列,最后一列补第一列到最后,最后一行补第一行到下一行组成9邻域,而四个角同样的理论单独处理。那么我滤波就需要3大块方面了,时间成本一下上去了。于是我思索更简单的方法。

第一步改进

首先是补充的方面,如果需要补充可以利用冈萨雷斯图像处理中的padarray函数进行填充。在这里插入图片描述
至于method的选择,就可以自己选了。反正都会引入误差,我后来采用了’replicate’复制边界填充,然后这样就把边缘都填完了。用我这种全部遍历的方法做,最后提取图像矩阵的(2:end-1,2:end-1)就可以得到滤波完的图像。但是时间成本依旧很高。因为MATLAB的for循环的代价实在是太高了。

第二步改进

我想起来了MATLAB有一种东西叫向量化,能用向量表示的就用向量表示,于是用起了最熟悉的find函数,在原始的矩阵找那些大于119.89的阈值部分然后利用下标+1即在扩展的矩阵中找邻域进行滤波。

%处理扩展的矩阵,但是输出扩展矩阵的2:end-1,2:end-1部分
A = double(A);   %A为图像的矩阵转换为double型
A1 = padarray(A,[1,1],'replicate','both');
A2 = A1;     %存储改变的矩阵,滤波过程中滤波的矩阵不能改变
[m,n] = find(A>119,89);    %m,n返回的是在未扩展的矩阵中的下标
k = size(m);
m1 = m+1;                  %为滤波的邻域准备,而扩展后的矩阵相对原始矩阵下标+1,
n1 = n+1;                  %否则会若出现1-1=0的情况超出MATLAB索引范围
for i = 1:1:k
    near = [A2(m1(i)-1,n1(i-1)),A2(m1(i)-1,n1(i)),A2(m1(i)-1,n1(i)+1),A2(m1(i),n1(i)),A2(m1(i),n1(i)+1),A2(m1(i)+1,n1(i)-1),A2(m1(i)+1,n1(i)),A2(m1(i)+1,n1(i)+1)];
    near_max = max(near);
    if A1(m(i),n(i)) > 119.89
        A1(m(i),n(i)) = near_max;
    end
end
%取出要的那部分矩阵
A3 = A1(2:end-1,2:end-1);
   %直方图的对比
figure;
subplot(1,2,1);
imhist(A);
title('原始图像的直方图');
subplot(1,2,2);
imhist(A3);
title('处理后图像的直方图');
%输出图像
geotiffwrite('m2.tif', A3, R,'GeoKeyDirectoryTag',info.GeoTIFFTags.GeoKeyDirectoryTag);

这种方法少了二次循环而且循环次数也大量的降低,免去了许多没必要的循环。不过这几个矩阵的关系需要好好厘清楚。其实还有一种是移动窗口样的,由于甲方给的要求是找到大于阈值的进行滤波所以这种方法比窗口移动又少了许多。但是窗口移动式的方法对整副影像进行滤波相对较好,后期还会学习搞清楚之后写blog。

对专业的认识的进程

大一时

大一时,老师总问我们你们认为遥感是什么,我心中总会根据我高中刷天利刷名校卷子的经验不假思索地在心里说道,遥感就是用来看的,只要注意下台风中心的移动也是用遥感监测就行了。

大二时

大二时,总在进行测绘,让我不禁怀疑遥感和测绘并没有什么区别。
在这里插入图片描述
大二那个暑假开始搞建模,要做数据分析,要敲代码。

大三时

刚开始时,因为小项目的原因利用ENVI做一点很简单的处理,我开始研究遥感影像那时候感觉遥感影像就是许多马赛克构成的大马赛克,在我的眼里遥感影像就是加上地理参考系的一幅图像(我记得当时有人让我做过一个土壤分类图,我也问过对方是否只要那花花绿绿的颜色而不顾参考系,对方也给了我肯定的答复),外行人看的是那颜色和结论,我们看的是密度分割后的成果和地理参考系。其实最后要看的是加上各种整饰要素的图。随着项目的深入,我不在把ENVI当成一种傻瓜式的点击就行的东西,而是利用自己的方法来计算这种图像矩阵,遥感影像背后是存储DN值的数字矩阵,利用band math来写语句就是来对矩阵进行处理。在这里插入图片描述
而直到这次单子之后,遥感影像在我心中成了一个数字矩阵+结构体,那数字矩阵是背后的DN值矩阵,而那结构体就是地理参考系。
在这里插入图片描述
这个是当时甲方给我的同僚的图,缺失了地理参考系的图就是一幅灰度图,缺少了重要的灵魂。
真正的遥感影像应该是:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
矩阵+参考系的结合体。在处理的时候它是一个大型的矩阵,而在真正需要的时候,那里的山川地貌,大江大河能够直接印在脑海里。
利用MATLAB处理数字矩阵其实在很大程度上会比ENVI band math快,我也在思索ENVI band math也是对栅格图像处理的机制是否也是向量化处理。

后续希望的改进

其实本来我希望通过同僚拿到甲方的数据,利用MATLAB tic toc计时器功能计算代码运行的时间来进行比较效率问题,但是没有能够成功。希望能拿到吧。
虽然第一桶金只赚来50多块钱,这第一桶金背后的锻炼以及思想上的转变是无法形容的的。
在我看来,从获得影像数据到出图这一整个生产链是都需要付出努力的。有时候影像不好获得,有时候天气数据不好获得,倘若会爬虫获取数据,那是一大进步。而倘若会数据分析,则能够很大程度上解决你只能生产影像却不能评价以及应用决策的问题。

结语

我记得某一位同僚说过很戏谑的话,计算机的人懂得编程,却不懂得地学影像处理,而遥感的很多人懂得影像处理却不懂得编程。其实这话没什么错,这也就造成了很有意思的现象,那就是想要实现实时地图及坐标显示及分析时,编程的人找不到逻辑,而做地学的人懂逻辑却不会写代码。真正做地学的人应该是一种计算机编程+影像处理+数据后期分析的结合体,最终为相应的部门进行决策。

发布了14 篇原创文章 · 获赞 2 · 访问量 848

猜你喜欢

转载自blog.csdn.net/weixin_43342986/article/details/102936380
今日推荐