Răsfoiți Sursa

[Feature] Update tools

geoyee 3 ani în urmă
părinte
comite
747c6fb6c0
5 a modificat fișierele cu 101 adăugiri și 6 ștergeri
  1. 2 1
      README.md
  2. 22 4
      docs/data/tools.md
  3. 1 1
      requirements.txt
  4. 0 0
      tools/coco2mask.py
  5. 76 0
      tools/mask2geojson.py

+ 2 - 1
README.md

@@ -113,8 +113,9 @@ PaddleRS是xxx、xxx、xxx等遥感科研院所共同基于飞桨开发的遥感
       <td>
         <b>数据格式转换</b><br>
         <ul>
-          <li>geojson to mask</li>
+          <li>coco to mask</li>
           <li>mask to shpfile</li>
+          <li>mask to geojson</li>
         </ul>
         <b>数据预处理</b><br>
         <ul>

+ 22 - 4
docs/data/tools.md

@@ -2,8 +2,9 @@
 
 工具箱位于`tools`文件夹下,目前有如下工具:
 
-- `geojson2mask`:用于将geojson格式的分割标注标签转换为png格式。
+- `coco2mask`:用于将geojson格式的分割标注标签转换为png格式。
 - `mask2shp`:用于对推理得到的png提取shapefile。
+- `mask2geojson`:用于对推理得到的png提取geojson。
 - `matcher`:用于在推理前匹配两个时段的影响。
 - `spliter`:用于将大图数据进行分割以作为训练数据。
 
@@ -18,12 +19,12 @@ git clone https://github.com/PaddleCV-SIG/PaddleRS.git
 dc PaddleRS\tools
 ```
 
-### geojson2mask
+### coco2mask
 
-`geojson2mask`的主要功能是将图像以及对应json格式的分割标签转换为图像与png格式的标签,结果会分别存放在`img`和`gt`两个文件夹中。相关的数据样例可以参考[中国典型城市建筑物实例数据集](https://www.scidb.cn/detail?dataSetId=806674532768153600&dataSetType=journal)。保存结果为单通道的伪彩色图像。使用代码如下:
+`coco2mask`的主要功能是将图像以及对应json格式的分割标签转换为图像与png格式的标签,结果会分别存放在`img`和`gt`两个文件夹中。相关的数据样例可以参考[中国典型城市建筑物实例数据集](https://www.scidb.cn/detail?dataSetId=806674532768153600&dataSetType=journal)。保存结果为单通道的伪彩色图像。使用代码如下:
 
 ```shell
-python geojson2mask.py --raw_folder xxx --save_folder xxx
+python coco2mask.py --raw_folder xxx --save_folder xxx
 ```
 
 其中:
@@ -42,10 +43,27 @@ python mask2shp.py --srcimg_path xxx.tif --mask_path xxx.png [--save_path output
 其中:
 
 - `srcimg_path`:原始图像的路径,需要带有地理信息,以便为生成的shapefile提供crs等信息。
+
 - `mask_path`:推理得到的png格式的标签的路径。
+
 - `save_path`:保存shapefile的路径,默认为`output`。
+
 - `ignore_index`:忽略生成shp的索引,如背景等,默认为255。
 
+### mask2geojson
+
+  `mask2geojson`的主要功能是将推理得到的png格式的分割结果转换为geojson格式。使用代码如下:
+
+  ```shell
+  python mask2geojson.py --mask_path xxx.tif --save_path xxx.json [--epsilon 0]
+  ```
+
+  其中:
+
+  - `mask_path`:推理得到的png格式的标签的路径。
+  - `save_path`:保存geojson的路径。
+  - `epsilon`:opencv的简化参数,默认为0。
+
 ### matcher
 
 ` matcher`的主要功能是在进行变化检测的推理前,匹配两期影像的位置,并将转换后的`im2`图像保存在原地址下,命名为`im2_M.tif`。使用代码如下:

+ 1 - 1
requirements.txt

@@ -5,7 +5,6 @@ opencv-contrib-python == 4.3.0.38
 numba == 0.53.1
 scikit-learn == 0.23.2
 scikit-image >= 0.14.0
-# numpy == 1.22.3
 pandas
 scipy
 cython
@@ -18,6 +17,7 @@ openpyxl
 easydict
 munch
 natsort
+geojson
 
 # # Self installation
 # GDAL >= 3.1.3

+ 0 - 0
tools/geojson2mask.py → tools/coco2mask.py


+ 76 - 0
tools/mask2geojson.py

@@ -0,0 +1,76 @@
+# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import codecs
+import cv2
+import numpy as np
+import argparse
+import geojson
+from geojson import Polygon, Feature, FeatureCollection
+from utils import Raster, Timer
+
+
+def _gt_convert(x, y, geotf):
+    x_geo = geotf[0] + x * geotf[1] + y * geotf[2]
+    y_geo = geotf[3] + x * geotf[4] + y * geotf[5]
+    return x_geo, y_geo
+
+
+@Timer
+def convert_data(mask_path, save_path, epsilon=0):
+    raster = Raster(mask_path)
+    img = raster.getArray()
+    geo_writer = codecs.open(save_path, "w", encoding="utf-8")
+    clas = np.unique(img)
+    cv2_v = (cv2.__version__.split(".")[0] == "3")
+    feats = []
+    if not isinstance(epsilon, (int, float)):
+        epsilon = 0
+    for iclas in range(1, len(clas)):
+        tmp = np.zeros_like(img).astype("uint8")
+        tmp[img == iclas] = 1
+        # TODO: Detect internal and external contour
+        results = cv2.findContours(tmp, cv2.RETR_EXTERNAL,
+                                   cv2.CHAIN_APPROX_TC89_KCOS)
+        contours = results[1] if cv2_v else results[0]
+        # hierarchys = results[2] if cv2_v else results[1]
+        if len(contours) == 0:
+            continue
+        for contour in contours:
+            contour = cv2.approxPolyDP(contour, epsilon, True)
+            polys = []
+            for point in contour:
+                x, y = point[0]
+                xg, yg = _gt_convert(x, y, raster.geot)
+                polys.append((xg, yg))
+            polys.append(polys[0])
+            feat = Feature(
+                geometry=Polygon([polys]), properties={"class": int(iclas)})
+            feats.append(feat)
+    gjs = FeatureCollection(feats)
+    geo_writer.write(geojson.dumps(gjs))
+    geo_writer.close()
+
+
+parser = argparse.ArgumentParser(description="input parameters")
+parser.add_argument("--mask_path", type=str, required=True, \
+                    help="The path of mask tif.")
+parser.add_argument("--save_path", type=str, required=True, \
+                    help="The path to save the results, file suffix is `*.json`.")
+parser.add_argument("--epsilon", type=float, default=0, \
+                    help="The CV2 simplified parameters, `0` is the default.")
+
+if __name__ == "__main__":
+    args = parser.parse_args()
+    convert_data(args.mask_path, args.save_path, args.epsilon)