{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# 9.1 面向对象的分类" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "传统的基于像素的遥感影像处理方法都是基于遥感影像光谱信息极其丰富,地物间光谱差异较为明显的基础上进行的。对于只含有较少波段的高分辨率遥感影像,传统的分类方法,就会造成分类精度降低,空间数据的大量冗余,并且其分类结果常常是椒盐图像,不利于进行空间分析。\n", "\n", "\n", "影像中地物类别特征不仅由光谱信息来刻画的,很多情况下(高分辨率或纹理影像数据)通过纹理特征来表示。此外背景信息在影像分析中很重要,举例来说,城市绿地与某些湿地在光谱信息上十分相似,在面向对象的影像分析中只要明确城市绿地的背景为城市地区,就可以轻松地区分绿地与湿地,而在基于像元的分类中这种背景信息几乎不可利用。面向对象的影像分析技术是在空间信息技术长期发展的过程中产生的,在遥感影像分析中具有巨大的潜力,要建立与现实世界真正相匹配的地表模型,面向对象的方法是目前为止较为理想的方法。面向对象的处理方法中最重要的一部分是图像分割。\n", "\n", "\n", "在分类之前,必须根据需要提取的地物类别,选择合适的尺度和合适的特征,然后根据地物类别的性质,设计好分类策略和步骤。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![](SLIC/objectclassF.JPG)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "图像对象 < 地理对象:根据像素间邻接关系创建和使用图像对象\n", "\n", "图像对象 ≈ 地理对象:对象间拓扑关系(相对距离、方位关系、相关等GIS空间分析功能)\n", "\n", "图像对象 > 地理对象: 利用地理对象间聚集(共生)关系" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![](SLIC/objectclass.JPG)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 9.2 实验要求" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "(1)理解基于对象的分类和传统的基于像素的分类在思想上的差异。\n", "\n", "(2)理解面向对象分类的关键在于图像分割,了解一些基本的分割算法。\n", "\n", "(3)掌握SLIC分割算法的原理,能用python实现基于SLIC对影像的分割。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 9.3 思考探索" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "(1)面向对象分类的思想内涵是怎样的?\n", "\n", "(2)SLIC分割算法与Kmean聚类算法的异同?\n", "\n", "(3)在什么情况下适合用面向对象的影像分类?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 9.4 案例展示(SLIC算法分割图像)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 9.4.1 需要的python模块" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "ExecuteTime": { "end_time": "2017-10-01T08:06:42.948034Z", "start_time": "2017-10-01T08:06:41.881324Z" }, "collapsed": true }, "outputs": [], "source": [ "from skimage.segmentation import slic #SCLI算法包\n", "from skimage.segmentation import mark_boundaries #根据SLIC分割结果生成边界\n", "from skimage.util import img_as_float #读取影像数据为float型\n", "from skimage import io,color #颜色库\n", "import matplotlib.pyplot as plt #绘图制图\n", "import argparse\n", "import skimage.io as SKimg #读取多种栅格图" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 9.4.2 SLIC算法原理" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "整个算法的输入只有一个,即超像素的个数K。\n", "\n", "图片原有N个像素,要分割成K个像素,那么每个像素的大小是N/K。超像素之间的距离(即规则情况下超像素的边长)就是S=sqrt(N/K)。\n", "\n", "我们的目标是使代价函数(cost function)最小。具体到本算法中,就是每个像素到所属的中心点的距离之和最小。\n", "\n", "首先,将K个超像素种子(也叫做聚类,即超像素的中心),均匀撒到图像的像素点上。\n", "\n", "一次迭代的第一步,对每个超像素的中心,2S范围内的所有像素点,判断他们是否属于这个超像素。这样之后,就缩短了像素点到超像素中心的距离。\n", "\n", "一次迭代的第二步,对每个超像素,将它的超像素中心移动到这个超像素的中点上。这样也缩短了像素点到超像素中心的距离。\n", "\n", "一般来说,迭代10是聚类效果和计算成本折中的次数。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 9.4.3 SLIC具体实现步骤" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "1.初始化种子点(聚类中心):按照设定的超像素个数,在图像内均匀的分配种子点。假设图片总共有 N 个像素点,
\n", "预分割为 K 个相同尺寸的超像素,那么每个超像素的大小为N/ K ,则相邻种子点的距离(步长)近似为S=sqrt(N/K)。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "2.在种子点的n*n邻域内重新选择种子点(一般取n=3)。具体方法为:计算该邻域内所有像素点的梯度值,将种子点移到
\n", "该邻域内梯度最小的地方。这样做的目的是为了避免种子点落在梯度较大的轮廓边界上,以免影响后续聚类效果。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "3.在每个种子点周围的邻域内为每个像素点分配类标签(即属于哪个聚类中心)。和标准的k-means在整张图中搜索不同,
\n", "SLIC的搜索范围限制为2S x 2S,可以加速算法收敛,如下图。在此注意一点:期望的超像素尺寸为S x S,但是搜索的范围是2S x 2S。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![](SLIC/Searchrange.JPG)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "4.距离度量。包括颜色距离和空间距离。对于每个搜索到的像素点,分别计算它和该种子点的距离。距离计算方法如下:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![](SLIC/DistanceMeasure.JPG)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "其中,dc代表颜色距离,ds代表空间距离,Ns是类内最大空间距离,定义为Ns=S=sqrt(N/K),适用于每个聚类。
\n", "最大的颜色距离Nc既随图片不同而不同,也随聚类不同而不同,所以我们取一个固定常数m(取值范围[1,40],一般取10)代替。
\n", "最终的距离度量D'如下:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![](SLIC/FinalDistanceMetric.JPG)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "由于每个像素点都会被多个种子点搜索到,所以每个像素点都会有一个与周围种子点的距离,取最小值对应的种子点作为该像素点的聚类中心。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "5.迭代优化。理论上上述步骤不断迭代直到误差收敛(可以理解为每个像素点聚类中心不再发生变化为止),实践发现10次迭代对绝大部分
\n", "图片都可以得到较理想效果,所以一般迭代次数取10。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "6.增强连通性。经过上述迭代优化可能出现以下瑕疵:出现多连通情况、超像素尺寸过小,单个超像素被切割成多个不连续超像素等,
\n", "这些情况可以通过增强连通性解决。主要思路是:新建一张标记表,表内元素均为-1,按照“Z”型走向(从左到右,从上到下顺序)
\n", "将不连续的超像素、尺寸过小超像素重新分配给邻近的超像素,遍历过的像素点分配给相应的标签,直到所有点遍历完毕为止。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 9.4.4 python关键代码" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Tpan =SKimg.imread(\"F:/pythontestdata/MyTiff/tianhui1200pan.tif\"); 读取全色影像数据(格式为TIFF)
\n", "\n", "TpanRGB=img_as_float(color.gray2rgb(Tpan)); 将灰度图像转为RGB图像" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "segments = slic(TpanRGB, n_segments =100, sigma = 5); 设置分割数量为100\n", "\n", "plt.imshow(mark_boundaries(TpanRGB, segments,color=(1, 1, 0), mode='outer', background_label=0)); 显示分割后的边界线条\n", "\n", "plt.savefig('name',dpi=2000); 分割效果保存出去" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 9.4.5 分割效果展示" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "分别设置分割体的数量为 100,200,500,1000,比较分割效果的差异。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![](SLIC/SLIC.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "从上图可以看出,分割体数量越大,对图像分割得越细致,同类地物分割得也就越破碎。在实际运用,可根据不同的需求,设置不同的分割体数量,
\n", "从而达到比较理想的分割效果。" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.0" }, "toc": { "colors": { "hover_highlight": "#DAA520", "navigate_num": "#000000", "navigate_text": "#333333", "running_highlight": "#FF0000", "selected_highlight": "#FFD700", "sidebar_border": "#EEEEEE", "wrapper_background": "#FFFFFF" }, "moveMenuLeft": true, "nav_menu": { "height": "138px", "width": "252px" }, "navigate_menu": true, "number_sections": true, "sideBar": true, "threshold": 4, "toc_cell": false, "toc_section_display": "block", "toc_window_display": true, "widenNotebook": false } }, "nbformat": 4, "nbformat_minor": 2 }