commit
749538acf1
58 changed files with 1470 additions and 744 deletions
@ -1,3 +1 @@ |
|||||||
# 开发规范 |
# PaddleRS文档 |
||||||
请注意,paddlers/models/ppxxx系列除了修改import路径和支持多通道模型外,不要增删改任何代码。 |
|
||||||
新增的模型需放在paddlers/models/下的seg、det、clas、cd目录下。 |
|
||||||
|
@ -0,0 +1,182 @@ |
|||||||
|
# 数据相关API说明 |
||||||
|
|
||||||
|
## 数据集 |
||||||
|
|
||||||
|
在PaddleRS中,所有数据集均继承自父类[`BaseDataset`](https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/datasets/base.py)。 |
||||||
|
|
||||||
|
### 变化检测数据集`CDDataset` |
||||||
|
|
||||||
|
`CDDataset`定义在:https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/datasets/cd_dataset.py |
||||||
|
|
||||||
|
其初始化参数列表如下: |
||||||
|
|
||||||
|
|参数名称|类型|参数说明|默认值| |
||||||
|
|-------|----|--------|-----| |
||||||
|
|`data_dir`|`str`|数据集存放目录。|| |
||||||
|
|`file_list`|`str`|file list路径。file list是一个文本文件,其中每一行包含一个样本的路径信息。`CDDataset`对file list的具体要求请参见下文。|| |
||||||
|
|`transforms`|`paddlers.transforms.Compose`|对输入数据应用的数据变换算子。|| |
||||||
|
|`label_list`|`str` \| `None`|label list文件。label list是一个文本文件,其中每一行包含一个类别的名称。|`None`| |
||||||
|
|`num_workers`|`int` \| `str`|加载数据时使用的辅助进程数。若设置为`'auto'`,则按照如下规则确定使用进程数:当CPU核心数大于16时,使用8个数据读取辅助进程;否则,使用CPU核心数一半数量的辅助进程。|`'auto'`| |
||||||
|
|`shuffle`|`bool`|是否随机打乱数据集中的样本。|`False`| |
||||||
|
|`with_seg_labels`|`bool`|当数据集中包含每个时相的分割标签时,请指定此选项为`True`。|`False`| |
||||||
|
|`binarize_labels`|`bool`|若为`True`,则在除`Arrange`以外的所有数据变换算子处理完毕后对变化标签(和分割标签)进行二值化操作。例如,将取值为{0, 255}的标签二值化到{0, 1}。|`False`| |
||||||
|
|
||||||
|
`CDDataset`对file list的要求如下: |
||||||
|
|
||||||
|
- 当`with_seg_labels`为`False`时,file list中的每一行应该包含3个以空格分隔的项,依次表示第一时相影像相对`data_dir`的路径、第二时相影像相对`data_dir`的路径以及变化标签相对`data_dir`的路径。 |
||||||
|
- 当`with_seg_labels`为`True`时,file list中的每一行应该包含5个以空格分隔的项,其中前3项的表示含义与`with_seg_labels`为`False`时相同,后2项依次表示第一时相和第二时相影像对应的分割标签相对`data_dir`的路径。 |
||||||
|
|
||||||
|
### 场景分类数据集`ClasDataset` |
||||||
|
|
||||||
|
`ClasDataset`定义在:https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/datasets/clas_dataset.py |
||||||
|
|
||||||
|
其初始化参数列表如下: |
||||||
|
|
||||||
|
|参数名称|类型|参数说明|默认值| |
||||||
|
|-------|----|--------|-----| |
||||||
|
|`data_dir`|`str`|数据集存放目录。|| |
||||||
|
|`file_list`|`str`|file list路径。file list是一个文本文件,其中每一行包含一个样本的路径信息。`ClasDataset`对file list的具体要求请参见下文。|| |
||||||
|
|`transforms`|`paddlers.transforms.Compose`|对输入数据应用的数据变换算子。|| |
||||||
|
|`label_list`|`str` \| `None`|label list文件。label list是一个文本文件,其中每一行包含一个类别的名称。|`None`| |
||||||
|
|`num_workers`|`int` \| `str`|加载数据时使用的辅助进程数。若设置为`'auto'`,则按照如下规则确定使用进程数:当CPU核心数大于16时,使用8个数据读取辅助进程;否则,使用CPU核心数一半数量的辅助进程。|`'auto'`| |
||||||
|
|`shuffle`|`bool`|是否随机打乱数据集中的样本。|`False`| |
||||||
|
|
||||||
|
`ClasDataset`对file list的要求如下: |
||||||
|
|
||||||
|
- file list中的每一行应该包含2个以空格分隔的项,依次表示输入影像相对`data_dir`的路径以及影像的类别ID(可解析为整型值)。 |
||||||
|
|
||||||
|
### COCO格式目标检测数据集`COCODetDataset` |
||||||
|
|
||||||
|
`COCODetDataset`定义在:https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/datasets/coco.py |
||||||
|
|
||||||
|
其初始化参数列表如下: |
||||||
|
|
||||||
|
|参数名称|类型|参数说明|默认值| |
||||||
|
|-------|----|--------|-----| |
||||||
|
|`data_dir`|`str`|数据集存放目录。|| |
||||||
|
|`image_dir`|`str`|输入图像存放目录。|| |
||||||
|
|`ann_path`|`str`|[COCO格式](https://cocodataset.org/#home)标注文件路径。|| |
||||||
|
|`transforms`|`paddlers.transforms.Compose`|对输入数据应用的数据变换算子。|| |
||||||
|
|`label_list`|`str` \| `None`|label list文件。label list是一个文本文件,其中每一行包含一个类别的名称。|`None`| |
||||||
|
|`num_workers`|`int` \| `str`|加载数据时使用的辅助进程数。若设置为`'auto'`,则按照如下规则确定使用进程数:当CPU核心数大于16时,使用8个数据读取辅助进程;否则,使用CPU核心数一半数量的辅助进程。|`'auto'`| |
||||||
|
|`shuffle`|`bool`|是否随机打乱数据集中的样本。|`False`| |
||||||
|
|`allow_empty`|`bool`|是否向数据集中添加负样本。|`False`| |
||||||
|
|`empty_ratio`|`float`|负样本占比,仅当`allow_empty`为`True`时生效。若`empty_ratio`为负值或大于等于1,则保留所有生成的负样本。|`1.0`| |
||||||
|
|
||||||
|
### VOC格式目标检测数据集`VOCDetDataset` |
||||||
|
|
||||||
|
`VOCDetDataset`定义在:https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/datasets/voc.py |
||||||
|
|
||||||
|
其初始化参数列表如下: |
||||||
|
|
||||||
|
|参数名称|类型|参数说明|默认值| |
||||||
|
|-------|----|--------|-----| |
||||||
|
|`data_dir`|`str`|数据集存放目录。|| |
||||||
|
|`file_list`|`str`|file list路径。file list是一个文本文件,其中每一行包含一个样本的路径信息。`VOCDetDataset`对file list的具体要求请参见下文。|| |
||||||
|
|`transforms`|`paddlers.transforms.Compose`|对输入数据应用的数据变换算子。|| |
||||||
|
|`label_list`|`str` \| `None`|label list文件。label list是一个文本文件,其中每一行包含一个类别的名称。|`None`| |
||||||
|
|`num_workers`|`int` \| `str`|加载数据时使用的辅助进程数。若设置为`'auto'`,则按照如下规则确定使用进程数:当CPU核心数大于16时,使用8个数据读取辅助进程;否则,使用CPU核心数一半数量的辅助进程。|`'auto'`| |
||||||
|
|`shuffle`|`bool`|是否随机打乱数据集中的样本。|`False`| |
||||||
|
|`allow_empty`|`bool`|是否向数据集中添加负样本。|`False`| |
||||||
|
|`empty_ratio`|`float`|负样本占比,仅当`allow_empty`为`True`时生效。若`empty_ratio`为负值或大于等于1,则保留所有生成的负样本。|`1.0`| |
||||||
|
|
||||||
|
`VOCDetDataset`对file list的要求如下: |
||||||
|
|
||||||
|
- file list中的每一行应该包含2个以空格分隔的项,依次表示输入影像相对`data_dir`的路径以及[Pascal VOC格式](http://host.robots.ox.ac.uk/pascal/VOC/)标注文件相对`data_dir`的路径。 |
||||||
|
|
||||||
|
### 图像分割数据集`SegDataset` |
||||||
|
|
||||||
|
`SegDataset`定义在:https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/datasets/seg_dataset.py |
||||||
|
|
||||||
|
其初始化参数列表如下: |
||||||
|
|
||||||
|
|参数名称|类型|参数说明|默认值| |
||||||
|
|-------|----|--------|-----| |
||||||
|
|`data_dir`|`str`|数据集存放目录。|| |
||||||
|
|`file_list`|`str`|file list路径。file list是一个文本文件,其中每一行包含一个样本的路径信息。`SegDataset`对file list的具体要求请参见下文。|| |
||||||
|
|`transforms`|`paddlers.transforms.Compose`|对输入数据应用的数据变换算子。|| |
||||||
|
|`label_list`|`str` \| `None`|label list文件。label list是一个文本文件,其中每一行包含一个类别的名称。|`None`| |
||||||
|
|`num_workers`|`int` \| `str`|加载数据时使用的辅助进程数。若设置为`'auto'`,则按照如下规则确定使用进程数:当CPU核心数大于16时,使用8个数据读取辅助进程;否则,使用CPU核心数一半数量的辅助进程。|`'auto'`| |
||||||
|
|`shuffle`|`bool`|是否随机打乱数据集中的样本。|`False`| |
||||||
|
|
||||||
|
`SegDataset`对file list的要求如下: |
||||||
|
|
||||||
|
- file list中的每一行应该包含2个以空格分隔的项,依次表示输入影像相对`data_dir`的路径以及分割标签相对`data_dir`的路径。 |
||||||
|
|
||||||
|
## 数据读取API |
||||||
|
|
||||||
|
遥感影像的来源多样,数据格式十分繁杂。PaddleRS为不同类型、不同格式的遥感影像提供了统一的读取接口。目前,PaddleRS支持.png、.jpg、.bmp、.npy等常见文件格式的读取,也支持处理遥感领域常用的GeoTiff、img等影像格式。 |
||||||
|
|
||||||
|
根据实际需要,用户可以选择`paddlers.transforms.decode_image()`或`paddlers.transforms.DecodeImg`进行数据读取。`DecodeImg`是[数据变换算子](#数据变换算子)之一,可以与其它算子组合使用。`decode_image`是对`DecodeImg`算子的封装,方便用户以函数调用的方式使用。 |
||||||
|
|
||||||
|
`decode_image()`函数的参数列表如下: |
||||||
|
|
||||||
|
|参数名称|类型|参数说明|默认值| |
||||||
|
|-------|----|--------|-----| |
||||||
|
|`im_path`|`str`|输入图像路径。|| |
||||||
|
|`to_rgb`|`bool`|若为`True`,则执行BGR到RGB格式的转换。|`True`| |
||||||
|
|`to_uint8`|`bool`|若为`True`,则将读取的图像数据量化并转换为uint8类型。|`True`| |
||||||
|
|`decode_bgr`|`bool`|若为`True`,则自动将非地学格式影像(如jpeg影像)解析为BGR格式。|`True`| |
||||||
|
|`decode_sar`|`bool`|若为`True`,则自动将2通道的地学格式影像(如GeoTiff影像)作为SAR影像解析。|`True`| |
||||||
|
|`read_geo_info`|`bool`|若为`True`,则从影像中读取地理信息。|`False`| |
||||||
|
|
||||||
|
返回格式如下: |
||||||
|
|
||||||
|
- 若`read_geo_info`为`False`,则以np.ndarray形式返回读取的影像数据([h, w, c]排布); |
||||||
|
- 若`read_geo_info`为`True`,则返回一个二元组,其中第一个元素为读取的影像数据,第二个元素为一个字典,其中的键值对为影像的地理信息,如地理变换信息、地理投影信息等。 |
||||||
|
|
||||||
|
## 数据变换算子 |
||||||
|
|
||||||
|
在PaddleRS中定义了一系列类,这些类在实例化之后,可通过调用`__call__`方法执行某种特定的数据预处理或数据增强操作。PaddleRS将这些类称为数据预处理/数据增强算子,并统称为**数据变换算子**。所有数据变换算子均继承自父类[`Transform`](https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/transforms/operators.py)。 |
||||||
|
|
||||||
|
### `Transform` |
||||||
|
|
||||||
|
`Transform`对象的`__call__`方法接受唯一的参数`sample`。`sample`必须为字典或字典构成的序列。当`sample`是序列时,为`sample`中的每个字典执行数据变换操作,并将变换结果依次存储在一个Python built-in list中返回;当`sample`是字典时,`Transform`对象根据其中的一些键值对提取输入(这些键称为“输入键”),执行变换后,将结果以键值对的形式写入`sample`中(这些键称为“输出键”)。需要注意的是,目前PaddleRS中许多`Transform`对象都存在复写行为,即,输入键与输出键之间存在交集。`sample`中常见的键名及其表示的含义如下表: |
||||||
|
|
||||||
|
|键名|说明| |
||||||
|
|----|----| |
||||||
|
|`'image'`|影像路径或数据。对于变化检测任务,指第一时相影像数据。| |
||||||
|
|`'image2'`|变化检测任务中第二时相影像数据。| |
||||||
|
|`'image_t1'`|变化检测任务中第一时相影像路径。| |
||||||
|
|`'image_t2'`|变化检测任务中第二时相影像路径。| |
||||||
|
|`'mask'`|图像分割/变化检测任务中的真值标签路径或数据。| |
||||||
|
|`'aux_masks'`|图像分割/变化检测任务中的辅助标签路径或数据。| |
||||||
|
|`'gt_bbox'`|目标检测任务中的检测框标注数据。| |
||||||
|
|`'gt_poly'`|目标检测任务中的多边形标注数据。| |
||||||
|
|
||||||
|
### 组合数据变换算子 |
||||||
|
|
||||||
|
使用`paddlers.transforms.Compose`对一组数据变换算子进行组合。`Compose`对象在构造时接受一个列表输入。在调用`Compose`对象时,相当于串行执行列表中的每一个数据变换算子。示例如下: |
||||||
|
|
||||||
|
```python |
||||||
|
# 使用Compose组合多种变换方式。Compose中包含的变换将按顺序串行执行 |
||||||
|
train_transforms = T.Compose([ |
||||||
|
# 读取影像 |
||||||
|
T.DecodeImg(), |
||||||
|
# 将影像缩放到512x512大小 |
||||||
|
T.Resize(target_size=512), |
||||||
|
# 以50%的概率实施随机水平翻转 |
||||||
|
T.RandomHorizontalFlip(prob=0.5), |
||||||
|
# 将数据归一化到[-1,1] |
||||||
|
T.Normalize( |
||||||
|
mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]), |
||||||
|
# 挑选并排布后续需要使用的信息 |
||||||
|
T.ArrangeSegmenter('train') |
||||||
|
]) |
||||||
|
``` |
||||||
|
|
||||||
|
一般来说,`Compose`对象接受的数据变换算子列表中,首个元素为`paddlers.transforms.DecodeImg`对象,用于读取影像数据;最后一个元素为[`Arrange`算子](https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/transforms/operators.py),用于从`sample`字典中抽取信息并排列。 |
||||||
|
|
||||||
|
对于图像分割任务和变化检测任务的验证集而言,可在`Arrange`算子之前插入`ReloadMask`算子以重新加载真值标签。示例如下: |
||||||
|
|
||||||
|
```python |
||||||
|
eval_transforms = T.Compose([ |
||||||
|
T.DecodeImg(), |
||||||
|
T.Resize(target_size=512), |
||||||
|
T.Normalize( |
||||||
|
mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]), |
||||||
|
# 重新加载标签 |
||||||
|
T.ReloadMask(), |
||||||
|
T.ArrangeSegmenter('eval') |
||||||
|
]) |
||||||
|
``` |
@ -0,0 +1,195 @@ |
|||||||
|
# PaddleRS推理API说明 |
||||||
|
|
||||||
|
PaddleRS的动态图推理和静态图推理能力分别由训练器([`BaseModel`](https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/tasks/base.py)及其子类)和**预测器**(`paddlers.deploy.Predictor`)提供。 |
||||||
|
|
||||||
|
## 动态图推理API |
||||||
|
|
||||||
|
### 整图推理 |
||||||
|
|
||||||
|
#### `BaseChangeDetector.predict()` |
||||||
|
|
||||||
|
接口形式: |
||||||
|
|
||||||
|
```python |
||||||
|
def predict(self, img_file, transforms=None): |
||||||
|
``` |
||||||
|
|
||||||
|
输入参数: |
||||||
|
|
||||||
|
|参数名称|类型|参数说明|默认值| |
||||||
|
|-------|----|--------|-----| |
||||||
|
|`img_file`|`list[tuple]` \| `tuple[str\|np.ndarray]`|输入影像对数据(NumPy数组形式)或输入影像对路径。若仅预测一个影像对,使用一个元组顺序包含第一时相影像数据/路径以及第二时相影像数据/路径。若需要一次性预测一组影像对,以列表包含这些影像对的数据或路径(每个影像对对应列表中的一个元组)。|| |
||||||
|
|`transforms`|`paddlers.transforms.Compose` \| `None`|对输入数据应用的数据变换算子。若为`None`,则使用训练器在验证阶段使用的数据变换算子。|`None`| |
||||||
|
|
||||||
|
返回格式: |
||||||
|
|
||||||
|
若`img_file`是一个元组,则返回对象为包含下列键值对的字典: |
||||||
|
|
||||||
|
``` |
||||||
|
{"label map": 输出类别标签(以[h, w]格式排布),"score_map": 模型输出的各类别概率(以[h, w, c]格式排布)} |
||||||
|
``` |
||||||
|
|
||||||
|
若`img_file`是一个列表,则返回对象为与`img_file`等长的列表,其中的每一项为一个字典(键值对如上所示),顺序对应`img_file`中的每个元素。 |
||||||
|
|
||||||
|
#### `BaseClassifier.predict()` |
||||||
|
|
||||||
|
接口形式: |
||||||
|
|
||||||
|
```python |
||||||
|
def predict(self, img_file, transforms=None): |
||||||
|
``` |
||||||
|
|
||||||
|
输入参数: |
||||||
|
|
||||||
|
|参数名称|类型|参数说明|默认值| |
||||||
|
|-------|----|--------|-----| |
||||||
|
|`img_file`|`list[str\|np.ndarray]` \| `str` \| `np.ndarray`|输入影像数据(NumPy数组形式)或输入影像路径。若需要一次性预测一组影像,以列表包含这些影像的数据或路径(每幅影像对应列表中的一个元素)。|| |
||||||
|
|`transforms`|`paddlers.transforms.Compose` \| `None`|对输入数据应用的数据变换算子。若为`None`,则使用训练器在验证阶段使用的数据变换算子。|`None`| |
||||||
|
|
||||||
|
返回格式: |
||||||
|
|
||||||
|
若`img_file`是一个字符串或NumPy数组,则返回对象为包含下列键值对的字典: |
||||||
|
|
||||||
|
``` |
||||||
|
{"label map": 输出类别标签, |
||||||
|
"scores_map": 输出类别概率, |
||||||
|
"label_names_map": 输出类别名称} |
||||||
|
``` |
||||||
|
|
||||||
|
若`img_file`是一个列表,则返回对象为与`img_file`等长的列表,其中的每一项为一个字典(键值对如上所示),顺序对应`img_file`中的每个元素。 |
||||||
|
|
||||||
|
#### `BaseDetector.predict()` |
||||||
|
|
||||||
|
接口形式: |
||||||
|
|
||||||
|
```python |
||||||
|
def predict(self, img_file, transforms=None): |
||||||
|
``` |
||||||
|
|
||||||
|
输入参数: |
||||||
|
|
||||||
|
|参数名称|类型|参数说明|默认值| |
||||||
|
|-------|----|--------|-----| |
||||||
|
|`img_file`|`list[str\|np.ndarray]` \| `str` \| `np.ndarray`|输入影像数据(NumPy数组形式)或输入影像路径。若需要一次性预测一组影像,以列表包含这些影像的数据或路径(每幅影像对应列表中的一个元素)。|| |
||||||
|
|`transforms`|`paddlers.transforms.Compose` \| `None`|对输入数据应用的数据变换算子。若为`None`,则使用训练器在验证阶段使用的数据变换算子。|`None`| |
||||||
|
|
||||||
|
返回格式: |
||||||
|
|
||||||
|
若`img_file`是一个字符串或NumPy数组,则返回对象为一个列表,列表中每个元素对应一个预测的目标框。列表中的元素为包含下列键值对的字典: |
||||||
|
|
||||||
|
``` |
||||||
|
{"category_id": 类别ID, |
||||||
|
"category": 类别名称, |
||||||
|
"bbox": 目标框位置信息,依次包含目标框左上角的横、纵坐标以及目标框的宽度和长度, |
||||||
|
"score": 类别置信度, |
||||||
|
"mask": [RLE格式](https://baike.baidu.com/item/rle/366352)的掩模图(mask),仅实例分割模型预测结果包含此键值对} |
||||||
|
``` |
||||||
|
|
||||||
|
若`img_file`是一个列表,则返回对象为与`img_file`等长的列表,其中的每一项为一个由字典(键值对如上所示)构成的列表,顺序对应`img_file`中的每个元素。 |
||||||
|
|
||||||
|
#### `BaseSegmenter.predict()` |
||||||
|
|
||||||
|
接口形式: |
||||||
|
|
||||||
|
```python |
||||||
|
def predict(self, img_file, transforms=None): |
||||||
|
``` |
||||||
|
|
||||||
|
输入参数: |
||||||
|
|
||||||
|
|参数名称|类型|参数说明|默认值| |
||||||
|
|-------|----|--------|-----| |
||||||
|
|`img_file`|`list[str\|np.ndarray]` \| `str` \| `np.ndarray`|输入影像数据(NumPy数组形式)或输入影像路径。若需要一次性预测一组影像,以列表包含这些影像的数据或路径(每幅影像对应列表中的一个元素)。|| |
||||||
|
|`transforms`|`paddlers.transforms.Compose` \| `None`|对输入数据应用的数据变换算子。若为`None`,则使用训练器在验证阶段使用的数据变换算子。|`None`| |
||||||
|
|
||||||
|
返回格式: |
||||||
|
|
||||||
|
若`img_file`是一个字符串或NumPy数组,则返回对象为包含下列键值对的字典: |
||||||
|
|
||||||
|
``` |
||||||
|
{"label map": 输出类别标签(以[h, w]格式排布),"score_map": 模型输出的各类别概率(以[h, w, c]格式排布)} |
||||||
|
``` |
||||||
|
|
||||||
|
若`img_file`是一个列表,则返回对象为与`img_file`等长的列表,其中的每一项为一个字典(键值对如上所示),顺序对应`img_file`中的每个元素。 |
||||||
|
|
||||||
|
### 滑窗推理 |
||||||
|
|
||||||
|
考虑到遥感影像的大幅面性质,PaddleRS为部分任务提供了滑窗推理支持。PaddleRS的滑窗推理功能具有如下特色: |
||||||
|
|
||||||
|
1. 为了解决一次读入整张大图直接导致内存不足的问题,PaddleRS采用延迟载入内存的技术,一次仅读取并处理一个窗口内的影像块。 |
||||||
|
2. 用户可自定义滑窗的大小和步长。支持滑窗重叠,对于窗口之间重叠的部分,PaddleRS将自动对模型预测结果进行融合。 |
||||||
|
3. 支持将推理结果保存为GeoTiff格式,支持对地理变换信息、地理投影信息的读取与写入。 |
||||||
|
|
||||||
|
目前,图像分割训练器([`BaseSegmenter`](https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/tasks/segmenter.py)及其子类)与变化检测训练器([`BaseChangeDetector`](https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/tasks/change_detector.py)及其子类)具有动态图滑窗推理API,以图像分割任务的API为例,说明如下: |
||||||
|
|
||||||
|
接口形式: |
||||||
|
|
||||||
|
```python |
||||||
|
def slider_predict(self, |
||||||
|
img_file, |
||||||
|
save_dir, |
||||||
|
block_size, |
||||||
|
overlap=36, |
||||||
|
transforms=None): |
||||||
|
``` |
||||||
|
|
||||||
|
输入参数列表: |
||||||
|
|
||||||
|
|参数名称|类型|参数说明|默认值| |
||||||
|
|-------|----|--------|-----| |
||||||
|
|`img_file`|`str`|输入影像路径。|| |
||||||
|
|`save_dir`|`str`|预测结果输出路径。|| |
||||||
|
|`block_size`|`list[int]` \| `tuple[int]` \| `int`|滑窗的窗口大小(以列表或元组指定长、宽或以一个整数指定相同的长宽)。|| |
||||||
|
|`overlap`|`list[int]` \| `tuple[int]` \| `int`|滑窗的滑动步长(以列表或元组指定长、宽或以一个整数指定相同的长宽)。|`36`| |
||||||
|
|`transforms`|`paddlers.transforms.Compose` \| `None`|对输入数据应用的数据变换算子。若为`None`,则使用训练器在验证阶段使用的数据变换算子。|`None`| |
||||||
|
|
||||||
|
变化检测任务的滑窗推理API与图像分割任务类似,但需要注意的是输出结果中存储的地理变换、投影等信息以从第一时相影像中读取的信息为准。 |
||||||
|
|
||||||
|
## 静态图推理API |
||||||
|
|
||||||
|
### Python API |
||||||
|
|
||||||
|
[将模型导出为部署格式](https://github.com/PaddlePaddle/PaddleRS/blob/develop/deploy/export/README.md)或执行模型量化后,PaddleRS提供`paddlers.deploy.Predictor`用于加载部署或量化格式模型以及执行基于[Paddle Inference](https://www.paddlepaddle.org.cn/tutorials/projectdetail/3952715)的推理。 |
||||||
|
|
||||||
|
#### 初始化`Predictor`对象 |
||||||
|
|
||||||
|
`Predictor.__init__()`接受如下参数: |
||||||
|
|
||||||
|
|参数名称|类型|参数说明|默认值| |
||||||
|
|-------|----|--------|-----| |
||||||
|
|`model_dir`|`str`|模型路径(必须是导出的部署或量化模型)。|| |
||||||
|
|`use_gpu`|`bool`|是否使用GPU。|`False`| |
||||||
|
|`gpu_id`|`int`|使用GPU的ID。|`0`| |
||||||
|
|`cpu_thread_num`|`int`|使用CPU执行推理时的线程数。|`1`| |
||||||
|
|`use_mkl`|`bool`|是否使用MKL-DNN计算库(此选项仅在使用CPU执行推理时生效)。|`False`| |
||||||
|
|`mkl_thread_num`|`int`|MKL-DNN计算线程数。|`4`| |
||||||
|
|`use_trt`|`bool`|是否使用TensorRT。|`False`| |
||||||
|
|`use_glog`|`bool`|是否启用glog日志。|`False`| |
||||||
|
|`memory_optimize`|`bool`|是否启用内存优化。|`True`| |
||||||
|
|`max_trt_batch_size`|`int`|在使用TensorRT时配置的最大batch size。|`1`| |
||||||
|
|`trt_precision_mode`|`str`|在使用TensorRT时采用的精度,可选值为`'float32'`或`'float16'`。|`'float32'`| |
||||||
|
|
||||||
|
#### `Predictor.predict()` |
||||||
|
|
||||||
|
接口形式: |
||||||
|
|
||||||
|
```python |
||||||
|
def predict(self, |
||||||
|
img_file, |
||||||
|
topk=1, |
||||||
|
transforms=None, |
||||||
|
warmup_iters=0, |
||||||
|
repeats=1): |
||||||
|
``` |
||||||
|
|
||||||
|
输入参数列表: |
||||||
|
|
||||||
|
|参数名称|类型|参数说明|默认值| |
||||||
|
|-------|----|--------|-----| |
||||||
|
|`img_file`|`list[str\|tuple\|np.ndarray]` \| `str` \| `tuple` \| `np.ndarray`|对于场景分类、目标检测和图像分割任务来说,该参数可为单一图像路径,或是解码后的、排列格式为[h, w, c]且具有float32类型的图像数据(表示为NumPy数组形式),或者是一组图像路径或np.ndarray对象构成的列表;对于变化检测任务来说,该参数可以为图像路径二元组(分别表示前后两个时相影像路径),或是解码后的两幅图像组成的二元组,或者是上述两种二元组之一构成的列表。|| |
||||||
|
|`topk`|`int`|场景分类模型预测时使用,表示选取模型输出概率大小排名前`topk`的类别作为最终结果。|`1`| |
||||||
|
|`transforms`|`paddlers.transforms.Compose`\|`None`|对输入数据应用的数据变换算子。若为`None`,则使用从`model.yml`中读取的算子。|`None`| |
||||||
|
|`warmup_iters`|`int`|预热轮数,用于评估模型推理以及前后处理速度。若大于1,将预先重复执行`warmup_iters`次推理,而后才开始正式的预测及其速度评估。|`0`| |
||||||
|
|`repeats`|`int`|重复次数,用于评估模型推理以及前后处理速度。若大于1,将执行`repeats`次预测并取时间平均值。|`1`| |
||||||
|
|
||||||
|
`Predictor.predict()`的返回格式与相应的动态图推理API的返回格式完全相同,详情请参考[动态图推理API](#动态图推理api)。 |
@ -1,33 +0,0 @@ |
|||||||
# 模型库 |
|
||||||
|
|
||||||
PaddleRS的基础模型库来自[PaddleClas](https://github.com/PaddlePaddle/PaddleClas/blob/release/2.3/docs/zh_CN/algorithm_introduction/ImageNet_models.md)、[PaddleSeg](https://github.com/PaddlePaddle/PaddleSeg/blob/release/2.4/docs/model_zoo_overview_cn.md)、[PaddleDetection](https://github.com/PaddlePaddle/PaddleDetection/blob/release/2.3/README_cn.md#模型库)以及[PaddleGAN](https://github.com/PaddlePaddle/PaddleGAN/blob/develop/README_cn.md#模型库),可以通过相关的链接进行查看。而在此之外,PaddleRS也针对遥感任务添加了一些特有的模型库,可用于遥感图像语义分割、遥感变化检测等。 |
|
||||||
|
|
||||||
## 遥感专用模型库 |
|
||||||
|
|
||||||
| 模型名称 | 用途 | |
|
||||||
| --------------- | -------- | |
|
||||||
| FarSeg | 语义分割 | |
|
||||||
| BIT | 变化检测 | |
|
||||||
| CDNet | 变化检测 | |
|
||||||
| DSIFN | 变化检测 | |
|
||||||
| STANet | 变化检测 | |
|
||||||
| SNUNet | 变化检测 | |
|
||||||
| DSAMNet | 变化检测 | |
|
||||||
| FCEarlyFusion | 变化检测 | |
|
||||||
| FCSiamConc | 变化检测 | |
|
||||||
| FCSiamDiff | 变化检测 | |
|
||||||
|
|
||||||
|
|
||||||
## 如何导入 |
|
||||||
|
|
||||||
模型均位于`paddlers/models`和`paddlers/rs_models`中,对于套件中的模型可以通过如下方法进行使用 |
|
||||||
|
|
||||||
```python |
|
||||||
from paddlers.models import xxxx |
|
||||||
``` |
|
||||||
|
|
||||||
而PaddleRS所特有的模型可以通过如下方法调用 |
|
||||||
|
|
||||||
```python |
|
||||||
from paddlers.rs_models import xxxx |
|
||||||
``` |
|
@ -0,0 +1,341 @@ |
|||||||
|
# PaddleRS训练API说明 |
||||||
|
|
||||||
|
**训练器**封装了模型训练、验证、量化以及动态图推理等逻辑,定义在`paddlers/tasks/`目录下的文件中。为了方便用户使用,PaddleRS为所有支持的模型均提供了继承自父类[`BaseModel`](https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/tasks/base.py)的训练器,并对外提供数个API。变化检测、场景分类、图像分割以及目标检测任务对应的训练器类型分别为`BaseChangeDetector`、`BaseClassifier`、`BaseDetector`和`BaseSegmenter`。本文档介绍训练器的初始化函数以及`train()`、`evaluate()` API。 |
||||||
|
|
||||||
|
## 初始化训练器 |
||||||
|
|
||||||
|
所有训练器均支持默认参数构造(即构造对象时不传入任何参数),在这种情况下,构造出的训练器对象适用于三通道RGB数据。 |
||||||
|
|
||||||
|
### 初始化`BaseChangeDetector`子类对象 |
||||||
|
|
||||||
|
- 一般支持设置`num_classes`、`use_mixed_loss`以及`in_channels`参数,分别表示模型输出类别数、是否使用预置的混合损失以及输入通道数。部分子类如`DSIFN`暂不支持对`in_channels`参数的设置。 |
||||||
|
- `use_mixed_loss`参将在未来被弃用,因此不建议使用。 |
||||||
|
- 不同的子类支持与模型相关的输入参数,详情请参考[模型定义](https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/rs_models/cd)和[训练器定义](https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/tasks/change_detector.py)。 |
||||||
|
|
||||||
|
### 初始化`BaseClassifier`子类对象 |
||||||
|
|
||||||
|
- 一般支持设置`num_classes`和`use_mixed_loss`参数,分别表示模型输出类别数以及是否使用预置的混合损失。 |
||||||
|
- `use_mixed_loss`参将在未来被弃用,因此不建议使用。 |
||||||
|
- 不同的子类支持与模型相关的输入参数,详情请参考[模型定义](https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/rs_models/clas)和[训练器定义](https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/tasks/classifier.py)。 |
||||||
|
|
||||||
|
### 初始化`Baseetector`子类对象 |
||||||
|
|
||||||
|
- 一般支持设置`num_classes`和`backbone`参数,分别表示模型输出类别数以及所用的骨干网络类型。相比其它任务,目标检测任务的训练器支持设置的初始化参数较多,囊括网络结构、损失函数、后处理策略等方面。 |
||||||
|
- 不同的子类支持与模型相关的输入参数,详情请参考[模型定义](https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/rs_models/det)和[训练器定义](https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/tasks/object_detector.py)。 |
||||||
|
|
||||||
|
### 初始化`BaseSegmenter`子类对象 |
||||||
|
|
||||||
|
- 一般支持设置`input_channel`、`num_classes`以及`use_mixed_loss`参数,分别表示输入通道数、输出类别数以及是否使用预置的混合损失。部分模型如`FarSeg`暂不支持对`input_channel`参数的设置。 |
||||||
|
- `use_mixed_loss`参将在未来被弃用,因此不建议使用。 |
||||||
|
- 不同的子类支持与模型相关的输入参数,详情请参考[模型定义](https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/rs_models/seg)和[训练器定义](https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/tasks/segmentor.py)。 |
||||||
|
|
||||||
|
## `train()` |
||||||
|
|
||||||
|
### `BaseChangeDetector.train()` |
||||||
|
|
||||||
|
接口形式: |
||||||
|
|
||||||
|
```python |
||||||
|
def train(self, |
||||||
|
num_epochs, |
||||||
|
train_dataset, |
||||||
|
train_batch_size=2, |
||||||
|
eval_dataset=None, |
||||||
|
optimizer=None, |
||||||
|
save_interval_epochs=1, |
||||||
|
log_interval_steps=2, |
||||||
|
save_dir='output', |
||||||
|
pretrain_weights=None, |
||||||
|
learning_rate=0.01, |
||||||
|
lr_decay_power=0.9, |
||||||
|
early_stop=False, |
||||||
|
early_stop_patience=5, |
||||||
|
use_vdl=True, |
||||||
|
resume_checkpoint=None): |
||||||
|
``` |
||||||
|
|
||||||
|
其中各参数的含义如下: |
||||||
|
|
||||||
|
|参数名称|类型|参数说明|默认值| |
||||||
|
|-------|----|--------|-----| |
||||||
|
|`num_epochs`|`int`|训练的epoch数目。|| |
||||||
|
|`train_dataset`|`paddlers.datasets.CDDataset`|训练数据集。|| |
||||||
|
|`train_batch_size`|`int`|训练时使用的batch size。|`2`| |
||||||
|
|`eval_dataset`|`paddlers.datasets.CDDataset` \| `None`|验证数据集。|`None`| |
||||||
|
|`optimizer`|`paddle.optimizer.Optimizer` \| `None`|训练时使用的优化器。若为`None`,则使用默认定义的优化器。|`None`| |
||||||
|
|`save_interval_epochs`|`int`|训练时存储模型的间隔epoch数。|`1`| |
||||||
|
|`log_interval_steps`|`int`|训练时打印日志的间隔step数(即迭代数)。|`2`| |
||||||
|
|`save_dir`|`str`|存储模型的路径。|`'output'`| |
||||||
|
|`pretrain_weights`|`str` \| `None`|预训练权重的名称/路径。若为`None`,则不适用预训练权重。|`None`| |
||||||
|
|`learning_rate`|`float`|训练时使用的学习率大小,适用于默认优化器。|`0.01`| |
||||||
|
|`lr_decay_power`|`float`|学习率衰减系数,适用于默认优化器。|`0.9`| |
||||||
|
|`early_stop`|`bool`|训练过程是否启用早停策略。|`False`| |
||||||
|
|`early_stop_patience`|`int`|启用早停策略时的`patience`参数(参见[`EarlyStop`](https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/utils/utils.py))。|`5`| |
||||||
|
|`use_vdl`|`bool`|是否启用VisualDL日志。|`True`| |
||||||
|
|`resume_checkpoint`|`str` \| `None`|检查点路径。PaddleRS支持从检查点(包含先前训练过程中存储的模型权重和优化器权重)继续训练,但需注意`resume_checkpoint`与`pretrain_weights`不得同时设置为`None`以外的值。|`None`| |
||||||
|
|
||||||
|
### `BaseClassifier.train()` |
||||||
|
|
||||||
|
接口形式: |
||||||
|
|
||||||
|
```python |
||||||
|
def train(self, |
||||||
|
num_epochs, |
||||||
|
train_dataset, |
||||||
|
train_batch_size=2, |
||||||
|
eval_dataset=None, |
||||||
|
optimizer=None, |
||||||
|
save_interval_epochs=1, |
||||||
|
log_interval_steps=2, |
||||||
|
save_dir='output', |
||||||
|
pretrain_weights='IMAGENET', |
||||||
|
learning_rate=0.1, |
||||||
|
lr_decay_power=0.9, |
||||||
|
early_stop=False, |
||||||
|
early_stop_patience=5, |
||||||
|
use_vdl=True, |
||||||
|
resume_checkpoint=None): |
||||||
|
``` |
||||||
|
|
||||||
|
其中各参数的含义如下: |
||||||
|
|
||||||
|
|参数名称|类型|参数说明|默认值| |
||||||
|
|-------|----|--------|-----| |
||||||
|
|`num_epochs`|`int`|训练的epoch数目。|| |
||||||
|
|`train_dataset`|`paddlers.datasets.ClasDataset`|训练数据集。|| |
||||||
|
|`train_batch_size`|`int`|训练时使用的batch size。|`2`| |
||||||
|
|`eval_dataset`|`paddlers.datasets.ClasDataset` \| `None`|验证数据集。|`None`| |
||||||
|
|`optimizer`|`paddle.optimizer.Optimizer` \| `None`|训练时使用的优化器。若为`None`,则使用默认定义的优化器。|`None`| |
||||||
|
|`save_interval_epochs`|`int`|训练时存储模型的间隔epoch数。|`1`| |
||||||
|
|`log_interval_steps`|`int`|训练时打印日志的间隔step数(即迭代数)。|`2`| |
||||||
|
|`save_dir`|`str`|存储模型的路径。|`'output'`| |
||||||
|
|`pretrain_weights`|`str` \| `None`|预训练权重的名称/路径。若为`None`,则不适用预训练权重。|`'IMAGENET'`| |
||||||
|
|`learning_rate`|`float`|训练时使用的学习率大小,适用于默认优化器。|`0.1`| |
||||||
|
|`lr_decay_power`|`float`|学习率衰减系数,适用于默认优化器。|`0.9`| |
||||||
|
|`early_stop`|`bool`|训练过程是否启用早停策略。|`False`| |
||||||
|
|`early_stop_patience`|`int`|启用早停策略时的`patience`参数(参见[`EarlyStop`](https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/utils/utils.py))。|`5`| |
||||||
|
|`use_vdl`|`bool`|是否启用VisualDL日志。|`True`| |
||||||
|
|`resume_checkpoint`|`str` \| `None`|检查点路径。PaddleRS支持从检查点(包含先前训练过程中存储的模型权重和优化器权重)继续训练,但需注意`resume_checkpoint`与`pretrain_weights`不得同时设置为`None`以外的值。|`None`| |
||||||
|
|
||||||
|
### `BaseDetector.train()` |
||||||
|
|
||||||
|
接口形式: |
||||||
|
|
||||||
|
```python |
||||||
|
def train(self, |
||||||
|
num_epochs, |
||||||
|
train_dataset, |
||||||
|
train_batch_size=64, |
||||||
|
eval_dataset=None, |
||||||
|
optimizer=None, |
||||||
|
save_interval_epochs=1, |
||||||
|
log_interval_steps=10, |
||||||
|
save_dir='output', |
||||||
|
pretrain_weights='IMAGENET', |
||||||
|
learning_rate=.001, |
||||||
|
warmup_steps=0, |
||||||
|
warmup_start_lr=0.0, |
||||||
|
lr_decay_epochs=(216, 243), |
||||||
|
lr_decay_gamma=0.1, |
||||||
|
metric=None, |
||||||
|
use_ema=False, |
||||||
|
early_stop=False, |
||||||
|
early_stop_patience=5, |
||||||
|
use_vdl=True, |
||||||
|
resume_checkpoint=None): |
||||||
|
``` |
||||||
|
|
||||||
|
其中各参数的含义如下: |
||||||
|
|
||||||
|
|参数名称|类型|参数说明|默认值| |
||||||
|
|-------|----|--------|-----| |
||||||
|
|`num_epochs`|`int`|训练的epoch数目。|| |
||||||
|
|`train_dataset`|`paddlers.datasets.COCODetDataset` \| `paddlers.datasets.VOCDetDataset` |训练数据集。|| |
||||||
|
|`train_batch_size`|`int`|训练时使用的batch size(多卡训练时,为所有设备合计batch size)。|`64`| |
||||||
|
|`eval_dataset`|`paddlers.datasets.COCODetDataset` \| `paddlers.datasets.VOCDetDataset` \| `None`|验证数据集。|`None`| |
||||||
|
|`optimizer`|`paddle.optimizer.Optimizer` \| `None`|训练时使用的优化器。若为`None`,则使用默认定义的优化器。|`None`| |
||||||
|
|`save_interval_epochs`|`int`|训练时存储模型的间隔epoch数。|`1`| |
||||||
|
|`log_interval_steps`|`int`|训练时打印日志的间隔step数(即迭代数)。|`10`| |
||||||
|
|`save_dir`|`str`|存储模型的路径。|`'output'`| |
||||||
|
|`pretrain_weights`|`str` \| `None`|预训练权重的名称/路径。若为`None`,则不适用预训练权重。|`'IMAGENET'`| |
||||||
|
|`learning_rate`|`float`|训练时使用的学习率大小,适用于默认优化器。|`0.001`| |
||||||
|
|`warmup_steps`|`int`|默认优化器使用[warm-up策略](https://www.mdpi.com/2079-9292/10/16/2029/htm)的预热轮数。|`0`| |
||||||
|
|`warmup_start_lr`|`int`|默认优化器warm-up阶段使用的初始学习率。|`0`| |
||||||
|
|`lr_decay_epochs`|`list` \| `tuple`|默认优化器学习率衰减的milestones,以epoch计。即,在第几个epoch执行学习率的衰减。|`(216, 243)`| |
||||||
|
|`lr_decay_gamma`|`float`|学习率衰减系数,适用于默认优化器。|`0.1`| |
||||||
|
|`metric`|`str` \| `None`|评价指标,可以为`'VOC'`、`COCO`或`None`。若为`Nnoe`,则根据数据集格式自动确定使用的评价指标。|`None`| |
||||||
|
|`use_ema`|`bool`|是否启用[指数滑动平均策略](https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/models/ppdet/optimizer.py)更新模型权重参数。|`False`| |
||||||
|
|`early_stop`|`bool`|训练过程是否启用早停策略。|`False`| |
||||||
|
|`early_stop_patience`|`int`|启用早停策略时的`patience`参数(参见[`EarlyStop`](https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/utils/utils.py))。|`5`| |
||||||
|
|`use_vdl`|`bool`|是否启用VisualDL日志。|`True`| |
||||||
|
|`resume_checkpoint`|`str` \| `None`|检查点路径。PaddleRS支持从检查点(包含先前训练过程中存储的模型权重和优化器权重)继续训练,但需注意`resume_checkpoint`与`pretrain_weights`不得同时设置为`None`以外的值。|`None`| |
||||||
|
|
||||||
|
### `BaseSegmenter.train()` |
||||||
|
|
||||||
|
接口形式: |
||||||
|
|
||||||
|
```python |
||||||
|
def train(self, |
||||||
|
num_epochs, |
||||||
|
train_dataset, |
||||||
|
train_batch_size=2, |
||||||
|
eval_dataset=None, |
||||||
|
optimizer=None, |
||||||
|
save_interval_epochs=1, |
||||||
|
log_interval_steps=2, |
||||||
|
save_dir='output', |
||||||
|
pretrain_weights='CITYSCAPES', |
||||||
|
learning_rate=0.01, |
||||||
|
lr_decay_power=0.9, |
||||||
|
early_stop=False, |
||||||
|
early_stop_patience=5, |
||||||
|
use_vdl=True, |
||||||
|
resume_checkpoint=None): |
||||||
|
``` |
||||||
|
|
||||||
|
其中各参数的含义如下: |
||||||
|
|
||||||
|
|参数名称|类型|参数说明|默认值| |
||||||
|
|-------|----|--------|-----| |
||||||
|
|`num_epochs`|`int`|训练的epoch数目。|| |
||||||
|
|`train_dataset`|`paddlers.datasets.SegDataset`|训练数据集。|| |
||||||
|
|`train_batch_size`|`int`|训练时使用的batch size。|`2`| |
||||||
|
|`eval_dataset`|`paddlers.datasets.SegDataset` \| `None`|验证数据集。|`None`| |
||||||
|
|`optimizer`|`paddle.optimizer.Optimizer` \| `None`|训练时使用的优化器。若为`None`,则使用默认定义的优化器。|`None`| |
||||||
|
|`save_interval_epochs`|`int`|训练时存储模型的间隔epoch数。|`1`| |
||||||
|
|`log_interval_steps`|`int`|训练时打印日志的间隔step数(即迭代数)。|`2`| |
||||||
|
|`save_dir`|`str`|存储模型的路径。|`'output'`| |
||||||
|
|`pretrain_weights`|`str` \| `None`|预训练权重的名称/路径。若为`None`,则不适用预训练权重。|`'CITYSCAPES'`| |
||||||
|
|`learning_rate`|`float`|训练时使用的学习率大小,适用于默认优化器。|`0.01`| |
||||||
|
|`lr_decay_power`|`float`|学习率衰减系数,适用于默认优化器。|`0.9`| |
||||||
|
|`early_stop`|`bool`|训练过程是否启用早停策略。|`False`| |
||||||
|
|`early_stop_patience`|`int`|启用早停策略时的`patience`参数(参见[`EarlyStop`](https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/utils/utils.py))。|`5`| |
||||||
|
|`use_vdl`|`bool`|是否启用VisualDL日志。|`True`| |
||||||
|
|`resume_checkpoint`|`str` \| `None`|检查点路径。PaddleRS支持从检查点(包含先前训练过程中存储的模型权重和优化器权重)继续训练,但需注意`resume_checkpoint`与`pretrain_weights`不得同时设置为`None`以外的值。|`None`| |
||||||
|
|
||||||
|
## `evaluate()` |
||||||
|
|
||||||
|
### `BaseChangeDetector.evaluate()` |
||||||
|
|
||||||
|
接口形式: |
||||||
|
|
||||||
|
```python |
||||||
|
def evaluate(self, eval_dataset, batch_size=1, return_details=False): |
||||||
|
``` |
||||||
|
|
||||||
|
输入参数如下: |
||||||
|
|
||||||
|
|参数名称|类型|参数说明|默认值| |
||||||
|
|-------|----|--------|-----| |
||||||
|
|`eval_dataset`|`paddlers.datasets.CDDataset`|评估数据集。|| |
||||||
|
|`batch_size`|`int`|评估时使用的batch size(多卡训练时,为所有设备合计batch size)。|`1`| |
||||||
|
|`return_details`|`bool`|是否返回详细信息。|`False`| |
||||||
|
|
||||||
|
当`return_details`为`False`(默认行为)时,输出为一个`collections.OrderedDict`对象。对于二类变化检测任务,输出包含如下键值对: |
||||||
|
|
||||||
|
``` |
||||||
|
{"iou": 变化类的IoU指标, |
||||||
|
"f1": 变化类的F1分数, |
||||||
|
"oacc": 总体精度(准确率), |
||||||
|
"kappa": kappa系数} |
||||||
|
``` |
||||||
|
|
||||||
|
对于多类变化检测任务,输出包含如下键值对: |
||||||
|
|
||||||
|
``` |
||||||
|
{"miou": mIoU指标, |
||||||
|
"category_iou": 各类的IoU指标, |
||||||
|
"oacc": 总体精度(准确率), |
||||||
|
"category_acc": 各类精确率, |
||||||
|
"kappa": kappa系数, |
||||||
|
"category_F1score": 各类F1分数} |
||||||
|
``` |
||||||
|
|
||||||
|
当`return_details`为`True`时,返回一个由两个字典构成的二元组,其中第一个元素为上述评价指标,第二个元素为仅包含一个key的字典,其`'confusion_matrix'`键对应值为以Python built-in list存储的混淆矩阵。 |
||||||
|
|
||||||
|
### `BaseClassifier.evaluate()` |
||||||
|
|
||||||
|
接口形式: |
||||||
|
|
||||||
|
```python |
||||||
|
def evaluate(self, eval_dataset, batch_size=1, return_details=False): |
||||||
|
``` |
||||||
|
|
||||||
|
输入参数如下: |
||||||
|
|
||||||
|
|参数名称|类型|参数说明|默认值| |
||||||
|
|-------|----|--------|-----| |
||||||
|
|`eval_dataset`|`paddlers.datasets.ClasDataset`|评估数据集。|| |
||||||
|
|`batch_size`|`int`|评估时使用的batch size(多卡训练时,为所有设备合计batch size)。|`1`| |
||||||
|
|`return_details`|`bool`|*当前版本请勿手动设置此参数。*|`False`| |
||||||
|
|
||||||
|
输出为一个`collections.OrderedDict`对象,包含如下键值对: |
||||||
|
|
||||||
|
``` |
||||||
|
{"top1": top1准确率, |
||||||
|
"top5": `top5准确率} |
||||||
|
``` |
||||||
|
|
||||||
|
### `BaseDetector.evaluate()` |
||||||
|
|
||||||
|
接口形式: |
||||||
|
|
||||||
|
```python |
||||||
|
def evaluate(self, |
||||||
|
eval_dataset, |
||||||
|
batch_size=1, |
||||||
|
metric=None, |
||||||
|
return_details=False): |
||||||
|
``` |
||||||
|
|
||||||
|
输入参数如下: |
||||||
|
|
||||||
|
|参数名称|类型|参数说明|默认值| |
||||||
|
|-------|----|--------|-----| |
||||||
|
|`eval_dataset`|`paddlers.datasets.COCODetDataset` \| `paddlers.datasets.VOCDetDataset`|评估数据集。|| |
||||||
|
|`batch_size`|`int`|评估时使用的batch size(多卡训练时,为所有设备合计batch size)。|`1`| |
||||||
|
|`metric`|`str` \| `None`|评价指标,可以为`'VOC'`、`COCO`或`None`。若为`Nnoe`,则根据数据集格式自动确定使用的评价指标。|`None`| |
||||||
|
|`return_details`|`bool`|是否返回详细信息。|`False`| |
||||||
|
|
||||||
|
当`return_details`为`False`(默认行为)时,输出为一个`collections.OrderedDict`对象,包含如下键值对: |
||||||
|
|
||||||
|
``` |
||||||
|
{"bbox_mmap": 预测结果的mAP值} |
||||||
|
``` |
||||||
|
|
||||||
|
当`return_details`为`True`时,返回一个由两个字典构成的二元组,其中第一个字典为上述评价指标,第二个字典包含如下3个键值对: |
||||||
|
|
||||||
|
``` |
||||||
|
{"gt": 数据集标注信息, |
||||||
|
"bbox": 预测得到的目标框信息, |
||||||
|
"mask": 预测得到的掩模图信息} |
||||||
|
``` |
||||||
|
|
||||||
|
### `BaseSegmenter.evaluate()` |
||||||
|
|
||||||
|
接口形式: |
||||||
|
|
||||||
|
```python |
||||||
|
def evaluate(self, eval_dataset, batch_size=1, return_details=False): |
||||||
|
``` |
||||||
|
|
||||||
|
输入参数如下: |
||||||
|
|
||||||
|
|参数名称|类型|参数说明|默认值| |
||||||
|
|-------|----|--------|-----| |
||||||
|
|`eval_dataset`|`paddlers.datasets.SegDataset`|评估数据集。|| |
||||||
|
|`batch_size`|`int`|评估时使用的batch size(多卡训练时,为所有设备合计batch size)。|`1`| |
||||||
|
|`return_details`|`bool`|是否返回详细信息。|`False`| |
||||||
|
|
||||||
|
当`return_details`为`False`(默认行为)时,输出为一个`collections.OrderedDict`对象,包含如下键值对: |
||||||
|
|
||||||
|
``` |
||||||
|
{"miou": mIoU指标, |
||||||
|
"category_iou": 各类的IoU指标, |
||||||
|
"oacc": 总体精度(准确率), |
||||||
|
"category_acc": 各类精确率, |
||||||
|
"kappa": kappa系数, |
||||||
|
"category_F1score": 各类F1分数} |
||||||
|
``` |
||||||
|
|
||||||
|
当`return_details`为`True`时,返回一个由两个字典构成的二元组,其中第一个元素为上述评价指标,第二个元素为仅包含一个key的字典,其`'confusion_matrix'`键对应值为以Python built-in list存储的混淆矩阵。 |
@ -1,53 +0,0 @@ |
|||||||
# 数据增强 |
|
||||||
|
|
||||||
PaddleRS将多种任务需要的数据增强进行了有机整合,均通过`Compose`进行使用,数据读取方面通过`DecodeImg`可以对不只三通道RGB图像进行读取,还可以对SAR以及多通道图像进行读取,提供有转为`uint8`的选项。此外提供以下数据增强的方法。 |
|
||||||
|
|
||||||
| 数据增强名称 | 用途 | 任务 | ... | |
|
||||||
| -------------------- | ----------------------------------------------- | -------- | ---- | |
|
||||||
| Resize | 调整输入大小 | 所有 | ... | |
|
||||||
| RandomResize | 随机调整输入大小 | 所有 | ... | |
|
||||||
| ResizeByShort | 调整输入大小,保持纵横比不变 | 所有 | ... | |
|
||||||
| RandomResizeByShort | 随机调整输入大小,保持纵横比不变 | 所有 | ... | |
|
||||||
| ResizeByLong | 调整输入大小,保持纵横比不变 | 所有 | ... | |
|
||||||
| RandomHorizontalFlip | 随机水平翻转输入 | 所有 | ... | |
|
||||||
| RandomVerticalFlip | 随机竖直翻转输入 | 所有 | ... | |
|
||||||
| Normalize | 对输入中的图像应用最小-最大标准化 | 所有 | ... | |
|
||||||
| CenterCrop | 对输入进行中心裁剪 | 所有 | ... | |
|
||||||
| RandomCrop | 对输入进行随机中心裁剪 | 所有 | ... | |
|
||||||
| RandomScaleAspect | 裁剪输入并重新调整大小至原始大小 | 所有 | ... | |
|
||||||
| RandomExpand | 通过根据随机偏移填充来随机扩展输入 | 所有 | ... | |
|
||||||
| Pad | 将输入填充到指定的大小 | 所有 | ... | |
|
||||||
| MixupImage | 将两张图片和它们的`gt_bbbox/gt_score`混合在一起 | 目标检测 | ... | |
|
||||||
| RandomDistort | 对输入进行随机色彩变换 | 所有 | ... | |
|
||||||
| RandomBlur | 对输入进行随机模糊 | 所有 | ... | |
|
||||||
| Dehaze | 对输入图像进行去雾 | 所有 | ... | |
|
||||||
| ReduceDim | 对输入图像进行降维 | 所有 | ... | |
|
||||||
| SelectBand | 选择输入图像的波段 | 所有 | ... | |
|
||||||
| RandomSwap | 随机交换两个输入图像 | 变化检测 | ... | |
|
||||||
| ... | ... | | ... | |
|
||||||
|
|
||||||
## 如何使用 |
|
||||||
|
|
||||||
以变化检测任务为例,其余任务的使用方法与此类似。 |
|
||||||
|
|
||||||
```python |
|
||||||
import paddlers.transforms as T |
|
||||||
from paddlers.datasets import CDDataset |
|
||||||
|
|
||||||
|
|
||||||
train_transforms = T.Compose([ |
|
||||||
T.DecodeImg(), |
|
||||||
T.Resize(target_size=512), |
|
||||||
T.RandomHorizontalFlip(), |
|
||||||
T.Normalize( |
|
||||||
mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]), |
|
||||||
T.ArrangeChangeDetector('train') |
|
||||||
]) |
|
||||||
|
|
||||||
train_dataset = CDDataset( |
|
||||||
data_dir='xxx/xxx', |
|
||||||
file_list='xxx/train_list.txt', |
|
||||||
label_list='xxx/labels.txt', |
|
||||||
transforms=train_transforms, |
|
||||||
shuffle=True) |
|
||||||
``` |
|
@ -0,0 +1,19 @@ |
|||||||
|
# 遥感开源数据集 |
||||||
|
|
||||||
|
PaddleRS搜集汇总了遥感领域常用的**开源**深度学习数据集,提供每个数据集的以下信息:数据集说明,影像信息,标注信息,源地址,AI Studio备份链接。这些数据集按任务类型可分为**图像分类、图像分割、变化检测、目标检测、目标跟踪、多标签分类、图像生成**等多种类型。目前已收录的遥感数据集有: |
||||||
|
|
||||||
|
* 图像分类数据集32个; |
||||||
|
* 目标检测数据集40个; |
||||||
|
* 图像分割数据集70个; |
||||||
|
* 变化检测数据集28个; |
||||||
|
* 实例分割数据集7个; |
||||||
|
* 多标签分类数据集3个; |
||||||
|
* 目标跟踪数据集9个; |
||||||
|
* 图像标题数据集3个; |
||||||
|
* 图像生成数据集8个。 |
||||||
|
|
||||||
|
欢迎访问[遥感数据集汇总](./dataset_summary.md),以获取详细信息。 |
||||||
|
|
||||||
|
## 特别贡献数据集 |
||||||
|
|
||||||
|
* 2020年中国典型城市道路样本数据CHN6-CUG,由中国地质大学[朱祺琪](http://grzy.cug.edu.cn/zhuqiqi)教授提供。相关介绍和下载方式请参考[此处](http://grzy.cug.edu.cn/zhuqiqi/zh_CN/yjgk/32368/content/1733.htm)。 |
@ -1,20 +0,0 @@ |
|||||||
## 公开数据集 |
|
||||||
|
|
||||||
PaddleRS搜集汇总了 遥感影像领域 常用的 **开源**深度学习数据集,每个数据集信息包括:数据集说明,影像信息,标注信息,源地址,aistudio备份链接。这些数据集按任务类型可分为 **图像分类、图像分割、变化检测、目标检测、目标跟踪、多标签分类、图像生成** 等多种类型,目前已收录的遥感数据集: |
|
||||||
|
|
||||||
* 图像分类数据集32个; |
|
||||||
* 目标检测数据集40个; |
|
||||||
* 图像分割数据集70个; |
|
||||||
* 变化检测数据集28个; |
|
||||||
* 实例分割数据集7个; |
|
||||||
* 多标签分类数据集3个; |
|
||||||
* 目标跟踪数据集9个; |
|
||||||
* 图像标题数据集3个; |
|
||||||
* 图像生成数据集8个 |
|
||||||
|
|
||||||
|
|
||||||
欢迎访问[遥感数据集汇总](./dataset_summary.md),获取详细数据集内容。 |
|
||||||
|
|
||||||
## 特别贡献数据集 |
|
||||||
|
|
||||||
* 2020年中国典型城市道路样本数据CHN6-CUG,由中国地质大学[朱祺琪](http://grzy.cug.edu.cn/zhuqiqi)教授提供,相关介绍和下载方式请参考[该地址](http://grzy.cug.edu.cn/zhuqiqi/zh_CN/yjgk/32368/content/1733.htm)。 |
|
@ -0,0 +1,111 @@ |
|||||||
|
# 遥感数据介绍 |
||||||
|
|
||||||
|
## 1 遥感与遥感影像的定义 |
||||||
|
|
||||||
|
广义上,遥感指的是"遥远的感知",即在不直接接触的情况下,对目标或自然现象进行远距离探测和感知。狭义上的遥感一般指电磁波遥感技术,即在某种平台(如飞机或卫星)上利用传感器探测电磁波的反射特性、并从中提取信息的过程。这个过程获取的影像数据被称作遥感影像,一般包括卫星和航空影像。遥感数据的用途广泛,在诸如空间分析等GIS任务中、或是包括场景分类、影像分割与目标检测在内的计算机视觉(Computer Vision, CV)领域都可以见到它们的身影。 |
||||||
|
|
||||||
|
相比航空影像,卫星影像的覆盖面积更广,因此得到了更加长足的应用。常见的卫星影像可能由商业卫星摄制,也可能来自NASA、ESA等机构的开放数据库。 |
||||||
|
|
||||||
|
## 2 遥感影像的特点 |
||||||
|
|
||||||
|
遥感技术具有宏观性、多波段性、周期性和经济性的特点。其中,宏观性指的是遥感平台越高,视角就越广,可以同步探测到的地面范围就越广;多波段性指的是传感器可以从紫外、可见光、近红外到微波等各个不同波段进行探测和记录信息;周期性指的是遥感卫星具有以一定周期重复获取图像的特点,可以在短时间内对同一地区进行重复观测;经济性指的是遥感技术可以作为一种获取大面积地表信息的方式,而相对不需要花费太多人力物力。 |
||||||
|
|
||||||
|
遥感技术的特点决定了遥感影像具有如下特性: |
||||||
|
|
||||||
|
1. 大尺度。一幅遥感影像能够覆盖广大的地表面积。 |
||||||
|
2. 多光谱。相比自然图像,遥感影像往往具有较多的波段数。 |
||||||
|
3. 来源丰富。不同传感器、不同卫星可以提供多样的数据源。 |
||||||
|
|
||||||
|
## 3 栅格影像的定义与遥感影像成像原理 |
||||||
|
|
||||||
|
为介绍遥感影像的成像原理,首先需要引入栅格的概念。栅格是一种基于像素的数据格式,可以有效地表示连续表面。栅格中的信息存储在网格结构中,每个信息单元或像素具有相同的大小和形状,但值不同。数码照片、正射影像和卫星影像都可以这种格式存储。 |
||||||
|
|
||||||
|
栅格格式非常适合用于查看空间和时间变化的分析,因为每个数据值都有一个基于网格的可访问位置。这使我们能够访问两个或多个不同栅格中的相同地理位置并比较它们的值。 |
||||||
|
|
||||||
|
当地球观测卫星拍摄照片时,传感器会记录不同波长电磁波在栅格像元中的DN值(Digital Number)。通过DN值,可以反求地物的辐照率和反射率。它们之间的关系如以下公式所示,其中$gain$和$bias$分别指传感器的增益和偏移;$L$是辐射率,也称为辐射亮度值;$\rho$是地物反射率;$d_{s}$、$E_{0}$和$\theta$分别表示日地天文单位距离、太阳辐照度以及太阳天顶角。 |
||||||
|
|
||||||
|
$$ |
||||||
|
L = gain * DN + bias \\ |
||||||
|
\rho = \pi Ld^{2}_{s}/(E_{0}\cos{\theta}) |
||||||
|
$$ |
||||||
|
|
||||||
|
电磁波谱是人类根据电磁波的波长或频率、波数、能量等的大小顺序进行排列的成果。在电磁波谱中人眼只能感受到一个很小的波段范围,这个范围被称为可见光,波长范围在0.38-0.76μm。这是因为我们的视觉进化为在太阳发出最多光的地方最敏感,并且广泛地局限于构成我们所谓的红色、绿色和蓝色的波长。但卫星传感器可以感知范围更广的电磁频谱,这使得我们能够与借助传感器感知更多的频谱范围。 |
||||||
|
|
||||||
|
![band](../images/band.jpg) |
||||||
|
|
||||||
|
电磁波谱范围很广,使用一个传感器同时收集所有波长的信息是不切实际的。在实际中,不同的传感器优先考虑从不同波长的光谱收集信息。由传感器捕获和分类的频谱的每个部分都被归类为一个信息带。信息带的大小各不相同,可以编译成不同类型的合成影像,每幅合成影像都强调不同的物理特性。同时,大多数遥感影像都为16位的图像,与传统的8位图像不同,它能表示更精细的光谱信息。 |
||||||
|
|
||||||
|
## 4 遥感影像的分类 |
||||||
|
|
||||||
|
遥感影像具有覆盖面积广、波段数多、来源丰富等特点,其分类方式也十分多样。例如,根据空间分辨率,可将遥感影像分为低分辨率遥感影像、中分辨率遥感影像、高分辨率遥感影像等;根据波段数,又可分为多光谱影像、高光谱影像、全色影像等类型。本文档旨在为不具备遥感专业背景的开发者提供快速了解的途径,因此仅介绍几种常见的遥感影像类型。 |
||||||
|
|
||||||
|
### 4.1 RGB影像 |
||||||
|
|
||||||
|
RGB影像与生活中常见的自然图像类似,其中显示的地物特征也符合人类的视觉常识(如树是绿色的、水泥是灰色的等),三个通道分别表示红、绿和蓝。下图展示了一幅RGB遥感影像: |
||||||
|
|
||||||
|
![rgb](../images/rgb.jpg) |
||||||
|
|
||||||
|
由于当前大多数CV任务的处理流程都是基于自然图像设计的,因此RGB类型的遥感数据集在CV领域使用较多。 |
||||||
|
|
||||||
|
### 4.2 MSI/HSI影像 |
||||||
|
|
||||||
|
MSI(Multispectral Image,多光谱影像)和HSI(Hyperspectral Image,高光谱影像)通常包括数个到数百个不等的波段,二者以不同的光谱分辨率(*光谱分辨率是指传感器所能记录的电磁波谱中某一特定的波长范围值,波长范围值越宽,则光谱分辨率越低*)进行区分。通常光谱分辨率在波长的1/10数量级范围内称为多光谱。MSI的波段数相对HSI较少,谱带较宽,空间分辨率较高;而HSI的波段数较多,谱带较窄,光谱分辨率较高。 |
||||||
|
|
||||||
|
在实际中常常根据应用需求选取MSI/HSI的一些特定波段:例如中红外波段的透射率在60%-70%,包含地物反射及发射光谱,可以用来探测火灾等高温目标;红边波段(*绿色植物在0.67-0.76μm之间反射率增高最快的点,也是一阶导数光谱在该区间内的拐点*)是指示绿色植物生长状况的敏感性波段,可以有效地监测植被的生长状况,用于研究植物养分、健康状态监测、植被识别和生理生化参数等信息等。 |
||||||
|
|
||||||
|
下面以天宫一号高光谱成像仪拍摄的北京大兴机场为例,简单介绍一下MSI/HSI处理中常见的波段组合、光谱曲线和波段选择的概念。天宫一号高光谱数据集根据波段信噪比和信息熵评价结果剔除信噪比和信息熵较低的波段,并结合影像实际目视结果剔除部分波段,共保留可见近红外谱段54个、短波红外谱段52个以及全色谱段数据。 |
||||||
|
|
||||||
|
**波段组合** |
||||||
|
|
||||||
|
波段组合是指在MSI/HSI中选择三个波段数据进行组合、代替RGB三个通道所得到的结果,称为彩色图(*使用真实的RGB三波段合成的结果称为真彩色图,否则称为假彩色图*)。不同波段的组合能够突出不同的地物特征,下图展示了几种不同组合的目视效果: |
||||||
|
|
||||||
|
![图片3](../images/band_combination.jpg) |
||||||
|
|
||||||
|
**光谱曲线解读** |
||||||
|
|
||||||
|
光谱信息往往能够反映地物特征,不同的波段反映的地物特征也不尽相同。以电磁波的波长或频率为横轴,反射率为纵轴,可以绘制光谱曲线。以植被的光谱曲线为例,如下图所示,植被在0.8μm波段反射率大于40%,相比在0.6μm波段10%左右的反射率明显更大,因此在成像时反射回更多的辐射能量。体现在图中,植被部分在0.8μm的影像中看起来更加明亮。 |
||||||
|
|
||||||
|
![band_mean](../images/band_mean.jpg) |
||||||
|
|
||||||
|
**波段选择** |
||||||
|
|
||||||
|
MSI/HSI包含的波段数量可能较多。一方面,并不是所有波段都适用于待处理的任务;另一方面,过多的波段数可能带来沉重的资源负担。在实际应用中,可以根据需求选用MSI/HSI的部分波段完成任务,也可以使用如PCA、小波变换等方法对MSI/HSI进行降维处理,以减少冗余,节省计算资源。 |
||||||
|
|
||||||
|
### 4.3 SAR影像 |
||||||
|
|
||||||
|
SAR(Synthetic Aperture Radar)指的是主动式侧视雷达系统。SAR的成像几何属于斜距投影类型,因此SAR影像与光学影像在成像机理、几何特征、辐射特征等方面都有较大的区别。 |
||||||
|
|
||||||
|
光学影像中不同波段的信息来自于不同波长电磁波的反射能量,而SAR影像则以二进制复数形式记录了不同极化(*即电磁波发射和接收的振动方向*)的回波信息。基于记录的复数数据,可将原始的SAR影像通过变换提取相应的振幅和相位信息。人类无法直接分辨相位信息,但可以直观地感知振幅信息,利用振幅信息可以得到强度图像,如下图所示: |
||||||
|
|
||||||
|
![sar](../images/sar.jpg) |
||||||
|
|
||||||
|
由于SAR影像的特殊成像机理,其分辨率相对较低,信噪比也较低,所以SAR影像中所包含的振幅信息远达不到光学影像的成像水平。这也是为什么SAR影像在CV领域中的应用较少。目前,SAR影像被主要用于基于相位信息的沉降检测反演、三维重建等。值得一提的是,由于SAR的波长较长,具有一定的云层和地表穿透能力,因此在部分应用场景中有其独特的优势。 |
||||||
|
|
||||||
|
### 4.4 RGBD影像 |
||||||
|
|
||||||
|
RGBD影像与RGB影像的区别在于多了一个D通道,即深度(depth)。深度影像类似于灰度图像,只是其中的每个像素值代表的是传感器距离物体的实际距离。通常RGBD影像中的RGB数据和深度数据是相互配准的。如下图所示为无人机航摄的RGBD影像,其中可以看出建筑物与地面之间的相对高度。 |
||||||
|
|
||||||
|
![rgbd](../images/rgbd.jpg) |
||||||
|
|
||||||
|
深度影像提供了RGB影像所不具有的高度信息,能够在某些下游任务中对一些光谱特征相似的地物起到一定的区分作用。 |
||||||
|
|
||||||
|
## 5 遥感影像的预处理 |
||||||
|
|
||||||
|
相比自然图像,遥感影像的预处理过程十分繁琐。具体而言,主要可分为以下步骤: |
||||||
|
|
||||||
|
1. **辐射定标**:将DN值转化为辐射亮度值或者反射率等物理量。 |
||||||
|
2. **大气校正**:消除由大气影响所造成的辐射误差,反演地物真实的表面反射率。该步骤与辐射定标合称为**辐射校正**。 |
||||||
|
3. **正射校正**:对影像同时进行倾斜改正和投影差改正,将影像重采样为正射影像。 |
||||||
|
4. **影像配准**:将不同时间、不同传感器(成像设备)或不同条件下(天候、照度、摄像位置和角度等)获取的两幅或多幅影像进行匹配、叠加。 |
||||||
|
5. **影像融合**:将多源信道所采集到的关于同一目标的影像数据综合成高质量影像。 |
||||||
|
6. **影像裁剪**:将大幅遥感影像裁剪为小块,提取感兴趣区域。 |
||||||
|
7. **定义投影**:对数据定义投影信息(地理坐标系)。 |
||||||
|
|
||||||
|
需要说明的是,在实际应用中,上述的步骤并不都是必须的,可根据需要选择性地执行其中某些步骤。 |
||||||
|
|
||||||
|
## 参考资料 |
||||||
|
|
||||||
|
- [Remote sensing in Wikipedia](https://en.wikipedia.org/wiki/Remote_sensing) |
||||||
|
- [宁津生等 《测绘学概论》](https://book.douban.com/subject/3116967/) |
||||||
|
- [孙家抦 《遥感原理与应用》](https://book.douban.com/subject/3826668/) |
||||||
|
- [遥感影像预处理步骤](https://blog.csdn.net/qq_35093027/article/details/119808941) |
@ -1,80 +0,0 @@ |
|||||||
# 遥感数据介绍 |
|
||||||
|
|
||||||
广义上,遥感是指遥远的感知,是指在不直接接触的情况下,对目标或自然现象远距离探测和感知的一种技术。一般我们所说的遥感为电磁波遥感,即在某平台上利用传感器探测电磁波反射或发射,并从中提取信息的过程。这个过程获取的图像数据一般即为卫星和航空影像。遥感数据可以被用于各种应用程序中,为空间分析等提供数据源,也可以在包括场景分类、图像分割与检测等CV领域进行判别或提取。 |
|
||||||
|
|
||||||
目前常用的遥感影像来自各种商业卫星影像提供商如Google等,以及来自NASA、ESA等的开放数据。可以从它们的官网中找到更多信息。 |
|
||||||
|
|
||||||
## 图像的工作原理 |
|
||||||
|
|
||||||
卫星和航空图像来自各种来源的栅格数据,经过接收方的部分处理后进行发布,如几何校正、辐射校正、大气校正或者色彩校正等,使其可以进行较准确的定量分析或具有更加逼真的视觉效果。 |
|
||||||
|
|
||||||
### 栅格数据 |
|
||||||
|
|
||||||
所有卫星和航空图像都以光栅格式存储。栅格是一种基于像素的数据格式,可以有效地表示连续表面。栅格中的信息存储在网格结构中,每个信息单元或像素具有相同的大小和形状,但值不同。数码照片、正射影像和卫星图像都以这种格式存储。 |
|
||||||
|
|
||||||
栅格格式非常适合用于查看空间和时间变化的分析,因为每个数据值都有一个基于网格的可访问位置。这使我们能够访问两个或多个不同栅格中的相同地理位置并比较它们的值。 |
|
||||||
|
|
||||||
### 卫星栅格 |
|
||||||
|
|
||||||
当地球观测卫星拍摄照片时,传感器会读取并记录从沿电磁光谱的波长收集的反射率值,并利用反射率计算各个栅格像元的DN值(Digital Number),即遥感影像像元的亮度值,记录的地物的灰度值。 |
|
||||||
|
|
||||||
而利用遥感图像的目的之一就是使用DN值可以反算地物的辐照率和反射率。它们之间的关系如下公式所示,其中$gain$和$bias$分别指传感器的增益和偏移;$L$是辐射率,也称为辐射亮度值;$\rho$是地物反射率;$d_{s}$、$E_{0}$和$\theta$分别表示日地天文单位距离、太阳辐照度以及太阳天顶角。 |
|
||||||
|
|
||||||
$$ |
|
||||||
L = gain * DN + bias \\ |
|
||||||
\rho = \pi Ld^{2}_{s}/(E_{0}\cos{\theta}) |
|
||||||
$$ |
|
||||||
|
|
||||||
电磁波谱是人类根据电磁波的波长或频率、波数、能量等的大小顺序进行排列的成果。在电磁波谱中人眼只能感受到一个很小的波段范围,这个范围被称为可见光,波长范围在0.38-0.76μm。这是因为我们的视觉进化为在太阳发出最多光的地方最敏感,并且广泛地局限于构成我们所谓的红色、绿色和蓝色的波长。但卫星传感器可以感知范围更广的电磁频谱,这使得我们能够与借助传感器感知更多的频谱范围。 |
|
||||||
|
|
||||||
![band](../images/band.jpg) |
|
||||||
|
|
||||||
电磁波谱范围很广,传感器同时收集所有波长的信息是不切实际的。相反,不同的传感器优先考虑从不同波长的光谱收集信息。由传感器捕获和分类的频谱的每个部分都被归类为一个信息带。信息带的大小各不相同,可以编译成不同类型的合成图像,每个图像都强调不同的物理特性。同时,大多数遥感图像都为16位的图像,与传统的8位图像不同,它能表示更精细的光谱信息。 |
|
||||||
|
|
||||||
#### RGB |
|
||||||
|
|
||||||
RGB图像与我们常见的自然图像类似,也符合人类的视觉常识(如树是绿色的、水泥是灰色的等),三个通道分别表示红、绿和蓝。一般的RGB数据来自于无人机影像、各种电子地图下载器等,如下图所示。 |
|
||||||
|
|
||||||
![rgb](../images/rgb.jpg) |
|
||||||
|
|
||||||
由于当前大多数CV任务的流程都是基于自然图像进行设计的,因此RGB类型的遥感数据集依然是使用较多的。 |
|
||||||
|
|
||||||
#### MSI/HSI |
|
||||||
|
|
||||||
MSI(*Multispectral Image,多光谱图像*)和HSI(*Hyperspectral Image,高光谱图像*)均是一种波段数均大于3的遥感影像,其波段由几个到几百个不等,以不同的光谱分辨率(*光谱分辨率是指传感器所能记录的电磁波谱中,某一特定的波长范围值,波长范围值越宽,光谱分辨率越低*)进行区分。通常光谱分辨率在波长的1/10数量级范围内称为多光谱。其中多光谱影像的波段较少,谱带较宽,空间分辨率较高;而高光谱影像的波段较多,谱带较窄,光谱分辨率较高。 |
|
||||||
|
|
||||||
在使用中,MSI/HSI有一些常用波段具有不同的作用,例如中红外波段的透射率在60%-70%,包含地物反射及发射光谱,可以用来探测火灾等高温目标;红边波段(*绿色植物在0.67-0.76μm之间反射率增高最快的点,也是一阶导数光谱在该区间内的拐点*)是指示绿色植物生长状况的敏感性波段,可以有效地监测植被的生长状况,用于研究植物养分、健康状态监测、植被识别和生理生化参数等信息等。 |
|
||||||
|
|
||||||
下面以天宫一号高光谱成像仪拍摄的北京大兴机场为例,简单介绍一下波段组合和光谱曲线。天宫一号高光谱数据集根据波段信噪比和信息熵评价结果,剔除信噪比和信息熵较低的波段,结合图像实际目视结果,剔除了部分波段,共有可见近红外谱段54 个;短波红外谱段 52 个以及1个全色谱段数据。 |
|
||||||
|
|
||||||
##### 波段组合 |
|
||||||
|
|
||||||
波段组合是指在MSI/HSI中选择三个波段数据进行组合,代替RGB三个通道所得到的结果,称为彩色图(*RGB三波段的合成图称为真彩色图,任意非RGB波段的合成图称为假彩色图*)。不同彩色图的组合能够突出不同的地物特征,下图展示了不同的几种组合的效果。 |
|
||||||
|
|
||||||
![图片3](../images/band_combination.jpg) |
|
||||||
|
|
||||||
##### 光谱曲线解读 |
|
||||||
|
|
||||||
不同的光谱能够突出不同的地物特征,以植物的光谱曲线为例,如下图所示,植被在0.8μm波段,反射率大于40%,相比在0.6μm波段10%左右的反射率明显更大,因此在成像时反射回更多的辐射能量。所以成像时0.8μm波段的植被亮度大于0.6μm波段的植被亮度,也就是图上看起来就更明亮了。 |
|
||||||
|
|
||||||
![band_mean](../images/band_mean.jpg) |
|
||||||
|
|
||||||
了解MSI/HSI的波段后,可以根据资源使用不同数量和不同组合方式的使用MSI/HSI完成各类任务,也可以使用如PCA、小波变换等方法对MSI/HSI进行降维处理,以减少冗余,使用更少的计算资源完成任务。 |
|
||||||
|
|
||||||
#### SAR |
|
||||||
|
|
||||||
SAR(Synthetic Aperture Radar)是主动式侧视雷达系统,且成像几何属于斜距投影类型。因此SAR图像与光学图像在成像机理、几何特征、辐射特征等方面都有较大的区别。 |
|
||||||
|
|
||||||
与光学图像不同,光学图像不同波段的信息来自不不同波长的电磁波反射,以便于识别目标和分类提取;SAR图像则记录了不同极化(*即电磁波发射和接收的振动方向*)的回波信息,以二进制复数形式记录下来,并且基于每个像素的复数数据可变换提取相应的振幅和相位信息。相位信息人类无法直接分辨,但振幅信息可以,利用振幅信息可以得到强度图像如下图所示。 |
|
||||||
|
|
||||||
![sar](../images/sar.jpg) |
|
||||||
|
|
||||||
由于SAR图像的成像机理的不同,SAR影像分辨率相对较低、信噪比较低,所以SAR影像中所包含的振幅信息远达不到同光学影像的成像水平,因此在CV领域使用较少。而其的主要作用在于基于相位信息可以进行沉降检测反演、三维重建等,同时SAR卫星波长较长,具有一定的云层和地表穿透能力,有其独特的使用优势。 |
|
||||||
|
|
||||||
#### RGBD |
|
||||||
|
|
||||||
RGBD与RGB图像的区别在于多了一个D通道,即深度。深度图像类似于灰度图像,只是它的每个像素值是传感器距离物体的实际距离。通常RGB图像和深度图像是配准的,因而两幅图像对应于同一空间位置的点是一一对应的。如下图所示为部分无人机航摄的RGBD图像,其中可以看出建筑物与地面之间的相对高度。 |
|
||||||
|
|
||||||
![rgbd](../images/rgbd.jpg) |
|
||||||
|
|
||||||
深度图像提供了RGB图像所不具有的高度信息,能够在下游任务中对一些光谱特征相似的地物起到一定的区分作用。 |
|
@ -1,41 +0,0 @@ |
|||||||
# 遥感数据集 |
|
||||||
|
|
||||||
遥感影像的格式多种多样,不同传感器产生的数据格式也可能不同。PaddleRS至少兼容以下6种格式图片读取: |
|
||||||
|
|
||||||
- `tif` |
|
||||||
- `png`, `jpeg`, `bmp` |
|
||||||
- `img` |
|
||||||
- `npy` |
|
||||||
|
|
||||||
标注图要求必须为单通道的png格式图像,像素值即为对应的类别,像素标注类别需要从0开始递增。例如0,1,2,3表示有4种类别,255用于指定不参与训练和评估的像素,标注类别最多为256类。 |
|
||||||
|
|
||||||
## L8 SPARCS数据集 |
|
||||||
[L8 SPARCS公开数据集](https://www.usgs.gov/land-resources/nli/landsat/spatial-procedures-automated-removal-cloud-and-shadow-sparcs-validation)进行云雪分割,该数据集包含80张卫星影像,涵盖10个波段。原始标注图片包含7个类别,分别是`cloud`, `cloud shadow`, `shadow over water`, `snow/ice`, `water`, `land`和`flooded`。由于`flooded`和`shadow over water`2个类别占比仅为`1.8%`和`0.24%`,我们将其进行合并,`flooded`归为`land`,`shadow over water`归为`shadow`,合并后标注包含5个类别。 |
|
||||||
|
|
||||||
数值、类别、颜色对应表: |
|
||||||
|
|
||||||
|Pixel value|Class|Color| |
|
||||||
|---|---|---| |
|
||||||
|0|cloud|white| |
|
||||||
|1|shadow|black| |
|
||||||
|2|snow/ice|cyan| |
|
||||||
|3|water|blue| |
|
||||||
|4|land|grey| |
|
||||||
|
|
||||||
<p align="center"> |
|
||||||
<img src="./images/dataset.jpg" align="middle" |
|
||||||
</p> |
|
||||||
|
|
||||||
|
|
||||||
<p align='center'> |
|
||||||
L8 SPARCS数据集示例 |
|
||||||
</p> |
|
||||||
|
|
||||||
执行以下命令下载并解压经过类别合并后的数据集: |
|
||||||
```shell script |
|
||||||
mkdir dataset && cd dataset |
|
||||||
wget https://paddleseg.bj.bcebos.com/dataset/remote_sensing_seg.zip |
|
||||||
unzip remote_sensing_seg.zip |
|
||||||
cd .. |
|
||||||
``` |
|
||||||
其中`data`目录存放遥感影像,`data_vis`目录存放彩色合成预览图,`mask`目录存放标注图。 |
|
Before Width: | Height: | Size: 307 KiB |
After Width: | Height: | Size: 241 KiB |
@ -0,0 +1,36 @@ |
|||||||
|
# 模型库 |
||||||
|
|
||||||
|
PaddleRS的基础模型库来自Paddle-CV系列套件:[PaddleClas](https://github.com/PaddlePaddle/PaddleClas/blob/release/2.3/docs/zh_CN/algorithm_introduction/ImageNet_models.md)、[PaddleSeg](https://github.com/PaddlePaddle/PaddleSeg/blob/release/2.4/docs/model_zoo_overview_cn.md)、[PaddleDetection](https://github.com/PaddlePaddle/PaddleDetection/blob/release/2.3/README_cn.md#模型库)以及[PaddleGAN](https://github.com/PaddlePaddle/PaddleGAN/blob/develop/README_cn.md#模型库)。除此之外,PaddleRS也包含一系列遥感特色模型,可用于遥感影像分割、变化检测等。 |
||||||
|
|
||||||
|
## PaddleRS已支持的模型列表 |
||||||
|
|
||||||
|
PaddleRS目前已支持的全部模型如下(标注\*的为遥感专用模型): |
||||||
|
|
||||||
|
| 任务 | 模型 | 多波段支持 | |
||||||
|
|--------|---------|------| |
||||||
|
| 变化检测 | \*BIT | 是 | |
||||||
|
| 变化检测 | \*CDNet | 是 | |
||||||
|
| 变化检测 | \*DSAMNet | 是 | |
||||||
|
| 变化检测 | \*DSIFN | 否 | |
||||||
|
| 变化检测 | \*SNUNet | 是 | |
||||||
|
| 变化检测 | \*STANet | 是 | |
||||||
|
| 变化检测 | \*FC-EF | 是 | |
||||||
|
| 变化检测 | \*FC-Siam-conc | 是 | |
||||||
|
| 变化检测 | \*FC-Siam-diff | 是 | |
||||||
|
| 变化检测 | \*ChangeStar | 否 | |
||||||
|
| 变化检测 | \*ChangeFormer | 是 | |
||||||
|
| 场景分类 | HRNet | 是 | |
||||||
|
| 场景分类 | MobileNetV3 | 是 | |
||||||
|
| 场景分类 | ResNet50-vd | 是 | |
||||||
|
| 场景分类 | CondenseNetV2 | 是 | |
||||||
|
| 图像复原 | DRN | 否 | |
||||||
|
| 图像复原 | ESRGAN | 否 | |
||||||
|
| 图像复原 | LESRCNN | 否 | |
||||||
|
| 目标检测 | Faster R-CNN | 是 | |
||||||
|
| 目标检测 | PP-YOLO | 是 | |
||||||
|
| 目标检测 | PP-YOLO Tiny | 是 | |
||||||
|
| 目标检测 | PP-YOLOv2 | 是 | |
||||||
|
| 目标检测 | YOLOv3 | 是 | |
||||||
|
| 图像分割 | DeepLab V3+ | 是 | |
||||||
|
| 图像分割 | UNet | 是 | |
||||||
|
| 图像分割 | \*FarSeg | 否 | |
@ -0,0 +1,33 @@ |
|||||||
|
# 数据预处理/数据增强 |
||||||
|
|
||||||
|
## PaddleRS已支持的数据变换算子列表 |
||||||
|
|
||||||
|
PaddleRS对不同遥感任务需要的数据预处理/数据增强(合称为数据变换)策略进行了有机整合,设计统一的算子。考虑到遥感影像的多波段特性,PaddleRS的大部分数据处理算子均能够处理任意数量波段的输入。PaddleRS目前提供的所有数据变换算子如下表: |
||||||
|
|
||||||
|
| 数据变换算子名 | 用途 | 任务 | ... | |
||||||
|
| -------------------- | ------------------------------------------------- | -------- | ---- | |
||||||
|
| Resize | 调整输入影像大小。 | 所有任务 | ... | |
||||||
|
| RandomResize | 随机调整输入影像大小。 | 所有任务 | ... | |
||||||
|
| ResizeByShort | 调整输入影像大小,保持纵横比不变(根据短边计算缩放系数)。 | 所有任务 | ... | |
||||||
|
| RandomResizeByShort | 随机调整输入影像大小,保持纵横比不变(根据短边计算缩放系数)。 | 所有任务 | ... | |
||||||
|
| ResizeByLong | 调整输入影像大小,保持纵横比不变(根据长边计算缩放系数)。 | 所有任务 | ... | |
||||||
|
| RandomHorizontalFlip | 随机水平翻转输入影像。 | 所有任务 | ... | |
||||||
|
| RandomVerticalFlip | 随机竖直翻转输入影像。 | 所有任务 | ... | |
||||||
|
| Normalize | 对输入影像应用标准化。 | 所有任务 | ... | |
||||||
|
| CenterCrop | 对输入影像进行中心裁剪。 | 所有任务 | ... | |
||||||
|
| RandomCrop | 对输入影像进行随机中心裁剪。 | 所有任务 | ... | |
||||||
|
| RandomScaleAspect | 裁剪输入影像并重新缩放到原始尺寸。 | 所有任务 | ... | |
||||||
|
| RandomExpand | 根据随机偏移扩展输入影像。 | 所有任务 | ... | |
||||||
|
| Pad | 将输入影像填充到指定的大小。 | 所有任务 | ... | |
||||||
|
| MixupImage | 将两幅影像(及对应的目标检测标注)混合在一起作为新的样本。 | 目标检测 | ... | |
||||||
|
| RandomDistort | 对输入施加随机色彩变换。 | 所有任务 | ... | |
||||||
|
| RandomBlur | 对输入施加随机模糊。 | 所有任务 | ... | |
||||||
|
| Dehaze | 对输入图像进行去雾。 | 所有任务 | ... | |
||||||
|
| ReduceDim | 对输入图像进行波段降维。 | 所有任务 | ... | |
||||||
|
| SelectBand | 对输入影像进行波段选择。 | 所有任务 | ... | |
||||||
|
| RandomSwap | 随机交换两个时相的输入影像。 | 变化检测 | ... | |
||||||
|
| ... | ... | ... | ... | |
||||||
|
|
||||||
|
## 组合算子 |
||||||
|
|
||||||
|
在实际的模型训练过程中,常常需要组合多种数据预处理与数据增强策略。PaddleRS提供了`paddlers.transforms.Compose`以便捷地组合多个数据变换算子,使这些算子能够串行执行。关于`paddlers.transforms.Compose`的具体用法请参见[API说明](https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/data.md)。 |
@ -1,42 +0,0 @@ |
|||||||
|
|
||||||
## 环境准备 |
|
||||||
|
|
||||||
- [PaddlePaddle安装](https://www.paddlepaddle.org.cn/install/quick) |
|
||||||
* 版本要求:PaddlePaddle>=2.1.0 |
|
||||||
|
|
||||||
- PaddleRS安装 |
|
||||||
|
|
||||||
|
|
||||||
PaddleRS代码会跟随开发进度不断更新,可以安装develop分支的代码使用最新的功能,安装方式如下: |
|
||||||
|
|
||||||
``` |
|
||||||
git clone https://github.com/PaddlePaddle/PaddleRS |
|
||||||
cd PaddleRS |
|
||||||
git checkout develop |
|
||||||
pip install -r requirements.txt |
|
||||||
python setup.py install |
|
||||||
``` |
|
||||||
|
|
||||||
## 开始训练 |
|
||||||
* 在安装PaddleRS后,使用如下命令开始训练,代码会自动下载训练数据, 并均使用单张GPU卡进行训练。 |
|
||||||
|
|
||||||
```commandline |
|
||||||
export CUDA_VISIBLE_DEVICES=0 |
|
||||||
python tutorials/train/semantic_segmentation/deeplabv3p_resnet50_multi_channel.py |
|
||||||
``` |
|
||||||
|
|
||||||
* 若需使用多张GPU卡进行训练,例如使用2张卡时执行: |
|
||||||
|
|
||||||
```commandline |
|
||||||
python -m paddle.distributed.launch --gpus 0,1 tutorials/train/semantic_segmentation/deeplabv3p_resnet50_multi_channel.py |
|
||||||
``` |
|
||||||
使用多卡时,参考[训练参数调整](../../docs/parameters.md)调整学习率和批量大小。 |
|
||||||
|
|
||||||
|
|
||||||
## VisualDL可视化训练指标 |
|
||||||
在模型训练过程,在`train`函数中,将`use_vdl`设为True,则训练过程会自动将训练日志以VisualDL的格式打点在`save_dir`(用户自己指定的路径)下的`vdl_log`目录,用户可以使用如下命令启动VisualDL服务,查看可视化指标 |
|
||||||
```commandline |
|
||||||
visualdl --logdir output/deeplabv3p_resnet50_multi_channel/vdl_log --port 8001 |
|
||||||
``` |
|
||||||
|
|
||||||
服务启动后,使用浏览器打开 https://0.0.0.0:8001 或 https://localhost:8001 |
|
@ -1,105 +1,105 @@ |
|||||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. |
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. |
||||||
# |
# |
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); |
# Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
# you may not use this file except in compliance with the License. |
# you may not use this file except in compliance with the License. |
||||||
# You may obtain a copy of the License at |
# You may obtain a copy of the License at |
||||||
# |
# |
||||||
# http://www.apache.org/licenses/LICENSE-2.0 |
# http://www.apache.org/licenses/LICENSE-2.0 |
||||||
# |
# |
||||||
# Unless required by applicable law or agreed to in writing, software |
# Unless required by applicable law or agreed to in writing, software |
||||||
# distributed under the License is distributed on an "AS IS" BASIS, |
# distributed under the License is distributed on an "AS IS" BASIS, |
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
# See the License for the specific language governing permissions and |
# See the License for the specific language governing permissions and |
||||||
# limitations under the License. |
# limitations under the License. |
||||||
|
|
||||||
import os |
import os |
||||||
import os.path as osp |
import os.path as osp |
||||||
import argparse |
import argparse |
||||||
|
|
||||||
import numpy as np |
import numpy as np |
||||||
from PIL import Image |
from PIL import Image |
||||||
try: |
try: |
||||||
from osgeo import gdal, ogr, osr |
from osgeo import gdal, ogr, osr |
||||||
except ImportError: |
except ImportError: |
||||||
import gdal |
import gdal |
||||||
import ogr |
import ogr |
||||||
import osr |
import osr |
||||||
|
|
||||||
from utils import Raster, save_geotiff, time_it |
from utils import Raster, save_geotiff, time_it |
||||||
|
|
||||||
|
|
||||||
def _mask2tif(mask_path, tmp_path, proj, geot): |
def _mask2tif(mask_path, tmp_path, proj, geot): |
||||||
dst_ds = save_geotiff( |
dst_ds = save_geotiff( |
||||||
np.asarray(Image.open(mask_path)), tmp_path, proj, geot, |
np.asarray(Image.open(mask_path)), tmp_path, proj, geot, |
||||||
gdal.GDT_UInt16, False) |
gdal.GDT_UInt16, False) |
||||||
return dst_ds |
return dst_ds |
||||||
|
|
||||||
|
|
||||||
def _polygonize_raster(mask_path, vec_save_path, proj, geot, ignore_index, ext): |
def _polygonize_raster(mask_path, vec_save_path, proj, geot, ignore_index, ext): |
||||||
if proj is None or geot is None: |
if proj is None or geot is None: |
||||||
tmp_path = None |
tmp_path = None |
||||||
ds = gdal.Open(mask_path) |
ds = gdal.Open(mask_path) |
||||||
else: |
else: |
||||||
tmp_path = vec_save_path.replace("." + ext, ".tif") |
tmp_path = vec_save_path.replace("." + ext, ".tif") |
||||||
ds = _mask2tif(mask_path, tmp_path, proj, geot) |
ds = _mask2tif(mask_path, tmp_path, proj, geot) |
||||||
srcband = ds.GetRasterBand(1) |
srcband = ds.GetRasterBand(1) |
||||||
maskband = srcband.GetMaskBand() |
maskband = srcband.GetMaskBand() |
||||||
gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES") |
gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES") |
||||||
gdal.SetConfigOption("SHAPE_ENCODING", "UTF-8") |
gdal.SetConfigOption("SHAPE_ENCODING", "UTF-8") |
||||||
ogr.RegisterAll() |
ogr.RegisterAll() |
||||||
drv = ogr.GetDriverByName("ESRI Shapefile" if ext == "shp" else "GeoJSON") |
drv = ogr.GetDriverByName("ESRI Shapefile" if ext == "shp" else "GeoJSON") |
||||||
if osp.exists(vec_save_path): |
if osp.exists(vec_save_path): |
||||||
os.remove(vec_save_path) |
os.remove(vec_save_path) |
||||||
dst_ds = drv.CreateDataSource(vec_save_path) |
dst_ds = drv.CreateDataSource(vec_save_path) |
||||||
prosrs = osr.SpatialReference(wkt=ds.GetProjection()) |
prosrs = osr.SpatialReference(wkt=ds.GetProjection()) |
||||||
dst_layer = dst_ds.CreateLayer( |
dst_layer = dst_ds.CreateLayer( |
||||||
"POLYGON", geom_type=ogr.wkbPolygon, srs=prosrs) |
"POLYGON", geom_type=ogr.wkbPolygon, srs=prosrs) |
||||||
dst_fieldname = "CLAS" |
dst_fieldname = "CLAS" |
||||||
fd = ogr.FieldDefn(dst_fieldname, ogr.OFTInteger) |
fd = ogr.FieldDefn(dst_fieldname, ogr.OFTInteger) |
||||||
dst_layer.CreateField(fd) |
dst_layer.CreateField(fd) |
||||||
gdal.Polygonize(srcband, maskband, dst_layer, 0, []) |
gdal.Polygonize(srcband, maskband, dst_layer, 0, []) |
||||||
# TODO: temporary: delete ignored values |
# TODO: temporary: delete ignored values |
||||||
dst_ds.Destroy() |
dst_ds.Destroy() |
||||||
ds = None |
ds = None |
||||||
vec_ds = drv.Open(vec_save_path, 1) |
vec_ds = drv.Open(vec_save_path, 1) |
||||||
lyr = vec_ds.GetLayer() |
lyr = vec_ds.GetLayer() |
||||||
lyr.SetAttributeFilter("{} = '{}'".format(dst_fieldname, str(ignore_index))) |
lyr.SetAttributeFilter("{} = '{}'".format(dst_fieldname, str(ignore_index))) |
||||||
for holes in lyr: |
for holes in lyr: |
||||||
lyr.DeleteFeature(holes.GetFID()) |
lyr.DeleteFeature(holes.GetFID()) |
||||||
vec_ds.Destroy() |
vec_ds.Destroy() |
||||||
if tmp_path is not None: |
if tmp_path is not None: |
||||||
os.remove(tmp_path) |
os.remove(tmp_path) |
||||||
|
|
||||||
|
|
||||||
@time_it |
@time_it |
||||||
def raster2vector(srcimg_path, mask_path, save_path, ignore_index=255): |
def mask2shape(srcimg_path, mask_path, save_path, ignore_index=255): |
||||||
vec_ext = save_path.split(".")[-1].lower() |
vec_ext = save_path.split(".")[-1].lower() |
||||||
if vec_ext not in ["json", "geojson", "shp"]: |
if vec_ext not in ["json", "geojson", "shp"]: |
||||||
raise ValueError( |
raise ValueError( |
||||||
"The extension of `save_path` must be 'json/geojson' or 'shp', not {}.". |
"The extension of `save_path` must be 'json/geojson' or 'shp', not {}.". |
||||||
format(vec_ext)) |
format(vec_ext)) |
||||||
ras_ext = srcimg_path.split(".")[-1].lower() |
ras_ext = srcimg_path.split(".")[-1].lower() |
||||||
if osp.exists(srcimg_path) and ras_ext in ["tif", "tiff", "geotiff", "img"]: |
if osp.exists(srcimg_path) and ras_ext in ["tif", "tiff", "geotiff", "img"]: |
||||||
src = Raster(srcimg_path) |
src = Raster(srcimg_path) |
||||||
_polygonize_raster(mask_path, save_path, src.proj, src.geot, |
_polygonize_raster(mask_path, save_path, src.proj, src.geot, |
||||||
ignore_index, vec_ext) |
ignore_index, vec_ext) |
||||||
src = None |
src = None |
||||||
else: |
else: |
||||||
_polygonize_raster(mask_path, save_path, None, None, ignore_index, |
_polygonize_raster(mask_path, save_path, None, None, ignore_index, |
||||||
vec_ext) |
vec_ext) |
||||||
|
|
||||||
|
|
||||||
parser = argparse.ArgumentParser() |
parser = argparse.ArgumentParser() |
||||||
parser.add_argument("--mask_path", type=str, required=True, \ |
parser.add_argument("--mask_path", type=str, required=True, \ |
||||||
help="Path of mask data.") |
help="Path of mask data.") |
||||||
parser.add_argument("--save_path", type=str, required=True, \ |
parser.add_argument("--save_path", type=str, required=True, \ |
||||||
help="Path to save the shape file (the extension is .json/geojson or .shp).") |
help="Path to save the shape file (the extension is .json/geojson or .shp).") |
||||||
parser.add_argument("--srcimg_path", type=str, default="", \ |
parser.add_argument("--srcimg_path", type=str, default="", \ |
||||||
help="Path of original data with geoinfo. Default to empty.") |
help="Path of original data with geoinfo. Default to empty.") |
||||||
parser.add_argument("--ignore_index", type=int, default=255, \ |
parser.add_argument("--ignore_index", type=int, default=255, \ |
||||||
help="The ignored index will not be converted to a value in the shape file. Default value is 255.") |
help="The ignored index will not be converted to a value in the shape file. Default value is 255.") |
||||||
|
|
||||||
if __name__ == "__main__": |
if __name__ == "__main__": |
||||||
args = parser.parse_args() |
args = parser.parse_args() |
||||||
raster2vector(args.srcimg_path, args.mask_path, args.save_path, |
mask2shape(args.srcimg_path, args.mask_path, args.save_path, |
||||||
args.ignore_index) |
args.ignore_index) |
Loading…
Reference in new issue