最近在搞eCognition(易康)的面向对象分类,最磨人的环节不是调分割参数,也不是选分类器,而是样本选择。几千个多边形,一个一个点过去,点到后面眼睛都花了,还容易点错。更要命的是,样本选完了,导出shp给同事或者下一步流程用,又是一堆坑等着。
这篇文章就是把我这段时间折腾出来的经验整理一下,重点解决两件事:怎么在易康里批量选择样本,以及怎么把样本和分割结果批量导出成shp。里面涉及的操作都是在eCognition Developer 9.x版本下实测的,8.x和10.x的界面差异不大,逻辑是通用的。
先说清楚一个概念,很多人把样本选择理解成“在影像上画点”,这个思路在易康里其实不太对。易康是面向对象分类软件,它的基本处理单元是分割出来的多边形对象,不是像素,也不是你手动画的矢量。所以你在易康里选样本,本质上是在多边形对象集合中标注类别,而不是重新创建样本几何。搞清楚这一点,批量操作的路子就打开了一大半。
1. 批量样本选择:核心思路与方案取舍
1.1 为什么要放弃手动点选
我最早做训练样本,就是老老实实把分割图层加载进来,然后在Viewer里用鼠标一个一个点。这个流程的问题很明显:
- 效率太低:一个中型项目动辄几万个对象,哪怕只选其中1%做样本也要几百个,手动点选一个下午就没了。
- 误操作率高:多边形边界叠在一起的时候,很容易点偏,选到隔壁地类去。样本错了,后面分类精度全完蛋,而且你还不容易发现。
- 可复现性差:手动选的样本没法记录“为什么选这个不选那个”,换了人来做,结果又不一样。批量选择用规则驱动,逻辑是固化的,谁跑都一样。
所以我的建议是:能用规则批量选的就绝不用手点。易康里最核心的批量选择方式就是通过“样本多边形对象”的属性(光谱均值、几何特征、以及与已有矢量的空间关系)来筛选。听起来抽象,实际操作其实就是写几条简单的规则条件,让软件自动把所有满足条件的对象一次性标记成样本。
1.2 两种批量选择路径的对比
在实际项目中,我总结下来有两条路可以走,各有适用的场景:
| 方案 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| A. 基于已有矢量文件导入样本 | 手头已有野外调查点、历史地类图斑、高精度目视解译成果 | 样本位置精准、类别可控,不需要看影像猜 | 矢量与分割对象边界往往不完全重合,需要做空间连接或“标签覆盖”处理 |
| B. 基于对象属性规则筛选 | 没有现成矢量,靠影像特征(光谱、形状、纹理)区分地类 | 完全自动化,适合大范围快速选样本 | 规则写得好不好直接决定样本质量,需要反复调阈值 |
方案A我在后面的实操章节会展开讲,因为它的坑最多,尤其是“导入的shp和分割对象对不上”的问题。方案B相对简单,核心就是写条件表达式,比如“红光波段均值大于某个阈值,同时面积大于某个值,就归为水体样本”,这类规则用易康内置的特征(Feature)面板拖拽就行,不需要代码。
1.3 批量选择的底层原理:样本本质是“类别标注”
我还是要强调一遍,在易康里,当你执行“创建样本”操作时,软件做的事情是把当前选中的对象集合的类别(Class)属性改成目标类别,同时把这些对象加入训练样本列表。所以批量选择样本的本质,就是批量修改对象类别属性。明白了这一点,你就会发现批量选择的所有方法,最终都归结为三种操作:
- 直接给某个条件下筛出来的对象集合赋予类别(Assign Class)。
- 将外部矢量通过空间叠加映射到对象上,再赋予类别。
- 在导入已有分类结果或样本时,通过分类器重新映射类别。
后面所有的实操步骤,都是这三种操作的排列组合。
2. 关键实操:基于已有shp批量生成样本
2.1 前期准备:shp数据与分割对象的对齐
先说我遇到的最典型场景:甲方给了一版野外调查点的shp,每个点带一个“地类代码”字段,我要用这些点作为训练样本去跑易康的分类。很多新手直接“File → Import Layer”就把点导入进去了,然后发现样本根本没法用——点落在了一个巨大的分割对象里,而这个对象里除了这个点对应的地类,还可能包含了其他地类的区域。
这里就涉及易康里一个非常重要的概念:样本的最小单元是分割对象,不是矢量点。一个点落在哪个对象里,这个对象整体就被标记为该点的类别。所以如果你的分割尺度太大,一个对象跨了两个地类,这个样本就是脏的。
我的做法是分三步预处理:
- 检查shp的坐标系与分割影像是否一致。不一致的话,易康导入时虽然会自动投影,但偶尔会出现偏移。我习惯在ArcGIS或QGIS里先把shp投影到与影像相同的坐标系再导入。
- 检查shp的字段编码。易康对中文字段名的支持不算好,最好在导入前把字段名改成英文或拼音,避免后面写规则时出现乱码。
- 检查shp中是否有重复要素、自相交等几何错误。有一个小工具非常值得推荐——ShapeChecker,专门用来检查和修复shp的几何问题。或者你在ArcGIS里用Repair Geometry工具跑一遍也行。
2.2 导入shp的三种方式与选择
在易康里导入shp有三种入口,别搞混了:
- File → Import Layer:把shp作为独立的矢量图层加载到项目中,参与后续的分割或作为分析数据。它不会直接变成样本。
- Classification → Samples → Import Samples from Thematic Layer:把shp图层当作专题层(Thematic Layer),按字段值给对象赋类别,这是生成样本最快的方式,但前提是分割对象已经存在。
- Process Tree中通过Add New Layer的方式导入:适合在规则集(Rule Set)中自动化地导入shp,好处是可复现。
我最常用的是第二种。操作路径是:先在Process Tree中创建分割(Multiresolution Segmentation),分割完成后,在Toolbar里找到Classification标签页,点击“Samples”下拉菜单,选择“Import Samples from Thematic Layer”,然后在弹出的对话框里选导入的shp图层,指定类别字段,软件就会自动把shp中的地物信息映射到与它相交的分割对象上,并批量标记为样本。
注意:这个操作的前提是,shp的类别字段值必须与易康类层次(Class Hierarchy)中已经定义好的类别名称完全一致,否则会提示类别不匹配。我建议在类层次里先建好水、田、林、建筑等类别,再导入,不要指望软件自动建类。
2.3 用空间关系规则解决“点落在对象边缘”问题
导入shp后最常见的问题就是很多对象没有被标记上。原因通常是shp要素和分割对象只是部分相交,或者点状shp落在细长对象的边缘,Intersection计算时不够精确。
针对点状shp,我推荐用一个更稳的方法:基于“Contains”关系写规则。在Process Tree里新建一个规则:
- 算法选择:Assign Class
- 参数设置里,勾选“Use Exported Object Features”,把点shp的类别字段引入特征(Relation to imported point layer → Contains)
- 表达逻辑:对象包含导入的点要素,则把该对象的类别设为对应地类
这样每个点只影响它所在的唯一对象(如果不跨边界),避免了批量导入时的“部分相交”歧义。对于面状shp(比如历史图斑),则反过来用“Intersects”或者“Rel. Border > 0.5”(相对边界占比大于50%)来控制标定程度,防止一个大图斑把周围完全不相干的对象卷进来。
这一步是最容易被忽略的。很多人导入shp后发现样本数量不对,第一反应是抱怨软件,其实十有八九是空间关系没设对。
2.4 导出样本shp的标准流程
样本标记完成后,把样本导出成shp也是高频需求。导出的场景有两种,一种是导出训练样本本身,另一种是导出分类结果。很多人都会在这块卡一下,因为易康默认导出的是全部对象,不是你选中的样本。
导出样本的标准操作:
- 在Process Tree中先执行一次“Select Samples”操作(Classification → Samples → Select Samples),选中所有已标记为某一类的样本对象。
- 然后右键点击Project图层树中的分割图层,选择“Export → Export Vector Layer”。
- 在导出设置里有两个关键选项,第一个是“Export Only Selected Objects”(只导出选中对象)一定要勾上,第二个是输出格式选“Shapefile”。
这个流程走下来,导出的shp就是干净的训练样本,字段里会带上类别名称和各类特征值。如果你不勾选“只导出选中对象”,导出的就是整幅分割结果,文件巨大且没意义。
3. 批量导出shp:从分割结果到成果交付
3.1 导出全部分割对象:属性表完整性的坑
导出全部分割对象这件事,使用频率也很高。比如你做完了多尺度分割,想把分割结果交给同事查看;或者做完了规则集分类,想输出一张矢量成果图。操作上还是“Export → Export Vector Layer”,格式选Shapefile。
但我必须吐槽一个易康的经典坑:导出的shp属性表经常是空的,或者只有FID和Class两个字段,对象的光谱均值、面积、周长等特征全没了。
出现这个问题的原因,是易康默认导出的属性字段列表为空。你必须在导出对话框里点击“Feature Selection”按钮,把需要的特征(Layer Values里的各波段均值、Geometry里的面积、Shape里的形状指数等)手动添加进去。很多教程不会提这一步,导致小白导出的shp在ArcGIS里什么都做不了。
我自己的习惯是,每次导出前都整理一份固定的特征导出模板,包含:面积(Area)、长宽比(Length/Width)、各波段均值(Mean Layer n)、亮度(Brightness)、NDVI(如果自定义了指数)、类别名(Class Name)。这样导出的shp直接就能用,不用二次挂接。
3.2 批量、多类别、分幅导出
如果只是导出一个shp,那用菜单操作就够了。但实际项目里往往要求“每个类别单独导出一个shp”,或者“每块图幅单独导出一个shp”。这种批量导出需求,靠菜单点会点疯掉,必须写规则集(Rule Set)自动化。
这里分享一个通用的批量导出脚本逻辑,在Process Tree里用循环实现:
- 使用Java Script或易康自带的循环控制(For Each Element)遍历类层次中的所有类别。
- 在循环体内,先执行Select Samples,选定当前类别。
- 然后执行Export Vector Layer,导出文件名动态拼接类别名。
- 循环结束后,所有类别的shp就分别导出到指定文件夹。
举个具体写法:在Process Tree中新建一个Process,算法选择“Export Vector Layer”,然后在“File Location”里填写模板路径,比如“D:\export\{Class_Name}.shp”,易康会用当前对象的类别名去替换{Class_Name}占位符。加上循环条件“For each class”,就能一键导出全部类别的shp。
这个技巧我是在一次需要给甲方交付20个地类分类成果时摸索出来的,直接省掉了大半天的重复劳动。关键是易康里这个占位符机制知道的人很少,所以特地写出来。
3.3 导出shp后的收尾处理:坐标系与编码
导出完成后别急着交差。我用易康导出shp后,常规操作是在ArcGIS里再过一遍,做三件事:
- 检查坐标系:易康导出shp时默认使用项目的全局坐标系(Map Coordinate System),一般不会丢。但如果你的项目里同时加载了多个不同坐标系的图层,偶尔会导出成未知坐标系。稳妥做法是在易康里给项目显式设置输出坐标系:Edit → Preferences → Map Coordinate System。
- 检查字段编码:易康导出的shp属性表中的中文字段值,在ArcGIS里偶尔显示乱码。这是因为shp的.dbf文件默认编码是ANSI,如果你的类别名是中文,建议在导出时把类名改成英文,或者后期在ArcGIS里用“Add Field + Calculate Field”重新赋值,避免乱码纠缠。
- 修复几何:易康导出的shp虽然一般几何没问题,但在跨平台传递时,偶尔会出现自相交或空几何。我在交付前习惯用ShapeChecker批量检查一遍,这个工具很小,绿色版,双击打开,选择shp文件,点Check,几秒钟就能把所有有问题的拓扑错误列出来,修复也是一键完成。
这些都是血泪教训。有一回我导出的shp在ArcGIS里打开完全正常,结果同事用QGIS打开后地物全飞了,最后查下来就是坐标系被易康写成了Local投影,没有坐标系定义文件。所以交付前的坐标系检查,必须做。
3.4 shp转其他格式:实用衍生场景
在实际项目里,shp往往不是终点,很多下游工具只认别的格式。在这里顺便聊几个和shp有关的衍生转换需求,都是我踩过坑后总结的捷径:
- shp转txt:易康导出的shp有时候我只是用来提取经纬度坐标,跑批量出图脚本用。常见的做法是用一个小工具或者ArcGIS的“Table To Excel”先导出成表,再另存为txt。如果你只是想快速提取坐标点,直接在ArcGIS的属性表里右键“Create Points”也行,但更快的还是用Python的pyshp库,二三十行代码就能搞定批量转txt。
- shp有没有办法只保留外边界线?这个需求其实用ArcGIS的“Dissolve”工具就能完成,把所有图斑合并后转面转线即可;在易康里则可以通过“Vector Layer → Spatial Operations → Polygon to Line”一步完成。如果你的shp是分类结果,想在易康里直接提取各类别的外边界线做制图,用这个操作效果很好。
- 环境配置里经常遇到的shp转gdb:因为gdb(地理数据库)在字段名长度、拓扑关系上比shp更宽容,很多流程从shp转到gdb后健壮性会好很多。ArcGIS里用“Feature Class to Feature Class”批量转即可,没有坑。
- ArcGIS把CAD转成shp:这个是老生常谈了,用ArcMap里的“CAD to Geodatabase”工具,或者QGIS里直接用“导入矢量”功能,选DWG/DXF文件即可。有一点要注意,CAD里的闭合多段线转过来默认是面,但有时候会变成折线,看图层类型选择就好。
这些衍生场景看着杂,但都是从“易康导出的shp怎么用”延伸出来的真实需求。很多时候不是功能不会用,而是不知道有这些衔接手段。
4. 实战案例:从shp样本到分类成果全流程复盘
4.1 案例背景与数据准备
我拿最近一个实际项目来复盘。任务是对某片区的高分辨率遥感影像做土地利用分类,类别就四类:水体、植被、建筑、裸地。甲方给了一份野外调查点的shp,约300个点,字段里有类型代码。影像分辨率0.5米,坐标系是CGCS2000。
我把整个流程拆成了八步:
- 在ArcGIS里对调查点shp做几何修复和字段预处理:代码字段重命名为land_type,值改成w、v、b、n四个英文代码,对应四个类别。
- 在易康里新建项目,加载影像和分割参数,执行多尺度分割。这里我用了尺度50、形状0.3、紧致度0.7,算是比较常规的参数。
- 在类层次里建立W、V、B、N四个类别,颜色分别设为蓝、绿、红、黄。
- 导入调查点shp作为专题层。
- 执行Import Samples from Thematic Layer,按land_type字段映射类别。
- 检查样本数量与空间分布,发现部分点没有成功标记,原因是点落在对象边界上。
- 写一条补充规则:对未标记对象,检测其与点shp的距离(Distance to imported point layer < 5像素),按最近点的类别补标记。
- 用KNN分类器训练并分类,导出分类结果shp。
4.2 样本检查与异常处理
第六步的“部分点没有成功标记”是最典型的问题。我统计了一下,300个点,成功标记了268个,剩下32个没标记上。这32个点,大部分落在线状地物(比如小路边的单棵树木)分割出来的细长对象上,或者落在两个对象的公共边上。
遇到这种情况,不要急着手动补点,先看看能不能用规则解决。我补充的规则是:
- 算法:Assign Class
- 条件:未分类(Unclassified)且 Distance to imported point layer < 5
- 类别:对应最近点的类别
这个“距离阈值”是关键,设得太小补不上,设得太大把远处无关对象卷进来。我一般用影像分辨率的5到10倍作为初始值,然后结合目视检查调整。实测下来,32个点补上了28个,剩下4个是因为点所在位置本身就是地类过渡带,影相上看着就不明确,这种样本即便补上也会成为分类噪声,删掉不要了。
这里插一句和样本数量相关的经验:很多人以为样本越多越好,其实不是。样本重叠、样本位于过渡地带,都会拉低分类精度。宁可样本少而精(当然每类至少30个),也不要把模糊样本硬塞进去。
4.3 分类器选择与参数配置
易康里常用的分类器有KNN(最近邻)、Bayes、SVM、Random Forest、Decision Tree等。我在这个项目里用的是KNN,因为它对训练样本数量要求低,而且参数简单。
KNN的关键参数是k值(邻居数)和Sample Distance(采样距离)。我用的k=3,Sample Distance选“Variable from Sample”模式,这样软件会根据样本分布自动调整判断阈值。如果是新手,我建议不要手动去调Distance的绝对值,直接用默认的Variable模式,否则很容易出现“所有对象都被分到同一个类”这种极端情况。
分类完成后,在Viewer里叠加底图看效果,重点关注地类边界和容易混淆的区域(比如建筑阴影下的裸地,和水体),必要时回到“样本编辑”状态手动增删几个关键样本,重新训练。这个迭代过程,往往比调分类器本身更有效。
4.4 批量导出分类成果并交付
分类结果检查满意后,就是导出环节。这个项目要求交付两种成果:一是全部分类结果的shp,二是每个类别单独导出一个shp,方便甲方做制图。
我直接写了上面提到的那个循环导出规则集,一次跑完,在D:\export文件夹下生成了四个文件:w.shp、v.shp、b.shp、n.shp,外加一个全部分类结果all.shp。然后按照前面说的流程,在ArcGIS里逐个检查坐标系、字段编码,用ShapeChecker修复一遍拓扑问题,最后打包交付。
整个流程走下来,从分割到交付,总共花了一个半小时左右,其中真正人工干预的时间不到二十分钟,其余全是规则集在跑。这个效率,是传统手动选样本加单次导出的流程没法比的。
这里的经验是:易康最强大的地方不在于某个单一功能,而在于你能把整条流水线串成自动化规则集。一次建好,以后换影像、换项目都能复用。
5. 常见问题与排查技巧实录
5.1 样本导出后shp在ArcGIS里打开是空的
这个问题的原因有两个:一是导出时勾选了“Export Only Selected Objects”,但当前并没有选中任何对象;二是在对象属性抽取时选错了特征。排查思路如下:
- 在易康里先确认对象是否真的选中了:用Viewer里选中几个对象,看Class Hierarchy窗口下方是否有对象计数显示。
- 导出设置里检查“Feature Selection”是否为空,为空就导出只有几何没有属性的shp,在ArcGIS里显示不出内容。
- 确认导出路径不能包含中文。易康的shp导出路径如果包含中文,偶尔会生成0字节的.dbf文件,这个坑我遇到好几次了。
5.2 导入shp时提示“Layer has no valid attributes”
这个问题多半是因为shp的属性表里全是空值,或者字段类型不被易康支持。解决方法是在导入前用ArcGIS检查属性表,把不需要的字段删掉,只保留类别字段,并且把这个字段的类型改成文本型(Text)。整数型字段在易康里也可以映射,但文本型最稳妥。
还有一种情况是shp中包含了多部件(Multi-part)要素,导入易康时会被拆分,然后属性关联不上。这个在ArcGIS里用Multipart To Singlepart工具先处理一下,或者在ShapeChecker里勾选“Split multi-part features”。
5.3 分类结果导出后地物位置偏移
这个问题基本都是坐标系惹的祸。解决方案不再赘述,核心就是三条:
- 在易康项目里统一坐标系,所有图层都设为同一坐标系。
- 导出时检查Map Coordinate System设置,确认不是Local。
- 导出后在ArcGIS里用“Define Projection”工具检查并修正坐标系。
另外还要强调一点,易康的坐标偏移和影像自带的坐标信息直接相关。如果你的源影像坐标系本身定义错误(比如影像标签写的是WGS84,实际却是CGCS2000),那导出shp偏移再远都正常。这种情况第一步就是修复源影像的坐标信息。
5.4 批量导出shp后每个类的文件大小差别巨大
这也是正常现象,因为各地物类别的空间分布和对象数量本来就不一样。但如果你发现某个类别的shp文件极端小(比如只有几KB),那大概率是这个类别的样本没有成功映射,导出内容基本是空的,需要回去检查样本标记情况。
5.5 易康卡死或者运行缓慢怎么办
处理大范围高分辨率影像时,易康卡顿很常见。我的几个实用技巧:
- 分割前对影像做金字塔重采样,易康里用“Image Pyramid”功能,先在低分辨率下跑几次分割测试,确定参数后再用原始分辨率跑正式分割。
- 规则集跑批量导出时,关闭Viewer的自动刷新,改为手动刷新,可以省下大量渲染时间。
- 导出shp时不要一口气把所有特征都选上,只导出真正需要的字段,减少I/O压力。
这些“软优化”虽然解决不了硬件瓶颈,但在相同配置下实测能提升30%到50%的处理速度。
5.6 易康和ArcGIS之间的shp衔接规范
最后整理一份我自己制定的衔接规范,算是给团队的约定,现在分享出来:
- 类别字段一律用英文名,避免中文乱码。
- 导出的shp统一做一次“Repair Geometry”和“Define Projection”。
- 坐标系统一用影像原始坐标系,如果没有明确坐标系,一律在交付说明里写明“未知坐标系,请勿直接用于空间分析”。
- 大批量导出优先用规则集,避免手动操作导致的文件名混乱。
- 每个交付目录下附一个readme.txt,写清楚坐标系、字段含义、数据版本和日期。
这些规范看起来琐碎,但实际项目中,团队协作时80%的沟通成本都耗在这些小问题上。
6. 实际操作中的一点经验心得
做eCognition项目这些年,最深的体会是:这个软件的学习曲线确实陡,但一旦你迈过了“对象思维”这道坎,后面的路就顺了。面向对象分类的精髓,就是放弃对单个像素的执念,把影像信息聚焦在一个个有实际意义的地理实体上。而样本选择作为分类质量的“天花板”,值得你花心思去优化流程。
我自己现在做新项目,第一步不是急着去分割,而是把样本来源理清楚——有没有现成的矢量数据?能不能从历史成果里挖?如果没有,我该怎么用规则把“目视解释经验”转化为可执行的条件?这些问题想清楚了,后面90%的工作都是流程化的。
再说回批量导出shp这件事。很多人觉得导出不就是点一下鼠标的事吗?但在实际生产中,数据清洗、格式转换、质量检查这些环节消耗的精力远超“点一下鼠标”。这篇文章里讲的很多步骤,本质上都不是什么高深算法,而是对生产流程的梳理。把这些细节做好,交付成果的质量才能稳定,返工率才能降下来。
最后再分享一个小技巧:如果你经常在易康、ArcGIS、QGIS三个软件之间倒腾数据,建议在电脑里装一个ShapeChecker之外,再装一个Notepad++,专门用来查看和修复shp属性表对应的.dbf文件乱码问题。这个办法虽然土,但在很多紧急情况下真的能救命。